Re: [llvm-commits] llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
Hi Chris, Chris Lattner wrote: Ahhh, ok. I think I understand now what is going on. Thank you for the very clear explanation. In this case, it seems like a clearly good thing to just call CreateFixedObject unconditionally early on (e.g.) when lowering the arguments. Unconditionally? I can do that, but do you mean without any check if R31 is actually used as frame pointer or we're compiling for linux/ppc? Nicolas ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
Re: [llvm-commits] Stack and register alignment in linux/ppc calls
Here's the final patch with the modifications you suggested. Thx a lot for your reviewing Chris. If everything's OK I'm checking this in soon. Cheers, Nicolas Chris Lattner wrote: On Mar 6, 2007, at 10:03 AM, Nicolas Geoffray wrote: This patch corrects arguments passing alignment for linux/ppc calls (ELF ABI). It affects LowerFORMAL_ARGUMENTS and LowerCALL of PPCISelLowering.cpp. Sure, sorry for the delay. Please add some high-level comments that explain what is going on here (what the ABI says). I would eventually like to switch PPC over to using autogenerated callingconv code, but I haven't had a chance to finish argument passing. @@ -1164,24 +1165,34 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() (1 27)) + (!(Flags (1 27; Please update this to use the enums that anton recently added for decoding the flags values. unsigned CurArgOffset = ArgOffset; switch (ObjectVT) { default: assert(0 Unhandled argument type!); case MVT::i32: + // Double word align in ELF + if (Expand !isELF_ABI !isPPC64) GPR_idx += (GPR_idx % 2); This says !isELF_ABI, shouldn't it be isELF_ABI? If not, you're modifying the Darwin/PPC ABI. - +unsigned Flags = castConstantSDNode(Op.getOperand(5+2*i+1))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (Arg.getValueType() == MVT::f64) || + ((i + 1 NumOps) + (castConstantSDNode(Op.getOperand(5+2*(i+1)+1))-getValue() + (1 27)) + (!(Flags (1 27; Likewise, plz use enums here. Also, there is some funky indentation going on here. Perhaps making a ConstantSDNode *Tmp would make this more natural. // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. -SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); +SDOperand PtrOff; + +// Stack align in ELF +if (isELF_ABI Expand !isPPC64) +PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize, +StackPtr.getValueType()); +else +PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); + Funky indentation. Statements should be indented by 2. Subexpressions (StackPtr.getValueType() should be aligned to the (. Otherwise, looks great, thanks! -Chris Index: PPCISelLowering.cpp === RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCISelLowering.cpp,v retrieving revision 1.260 diff -t -d -u -p -5 -r1.260 PPCISelLowering.cpp --- PPCISelLowering.cpp 6 Mar 2007 00:59:59 - 1.260 +++ PPCISelLowering.cpp 12 Mar 2007 15:39:25 - @@ -1130,10 +1130,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand Root = Op.getOperand(0); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); static const unsigned GPR_32[] = { // 32-bit registers. @@ -1161,30 +1162,46 @@ static SDOperand LowerFORMAL_ARGUMENTS(S const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32; // Add DAG nodes to load the arguments or copy them out of registers. On // entry to a function on PPC, the arguments start after the linkage area, // although the first ones are often in registers. + // + // In the ELF ABI, GPRs and stack are double word align: an argument + // represented with two words (long long or double) must be copied to an + // even GPR_idx value or to an even ArgOffset value. + for (unsigned ArgNo = 0, e = Op.Val-getNumValues()-1; ArgNo != e; ++ArgNo) { SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))-getValue(); +unsigned AlignFlag = 1 ISD::ParamFlags::OrigAlignmentOffs; +// See if next argument requires stack alignment in ELF +bool Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() AlignFlag) + (!(Flags AlignFlag))); unsigned CurArgOffset = ArgOffset; switch
[llvm-commits] [see] CVS: llvm-poolalloc/lib/DSA/Local.cpp
Changes in directory llvm-poolalloc/lib/DSA: Local.cpp updated: 1.158.2.4.2.4 - 1.158.2.4.2.5 --- Log message: this could be bad, but it doesn't trigger --- Diffs of the changes: (+27 -0) Local.cpp | 27 +++ 1 files changed, 27 insertions(+) Index: llvm-poolalloc/lib/DSA/Local.cpp diff -u llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.4 llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.5 --- llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.4 Fri Mar 9 11:27:51 2007 +++ llvm-poolalloc/lib/DSA/Local.cppMon Mar 12 11:41:06 2007 @@ -1451,6 +1451,33 @@ EliminateUsesOfECGlobals(*I-second, ECGlobals); } +#ifdef LLVA_KERNEL + + // Ugly hack. kmem_cache_allocs are in the same pool also if the kmem_cache_t's are the same + // this only works on global kmem_cache_ts + Function* KMA = M.getNamedFunction(kmem_cache_alloc); + if (KMA) { +for (Value::use_iterator ii = KMA-use_begin(), ee = KMA-use_end(); + ii != ee; ++ii) { + std::mapValue*, MetaPool* locs; + if (CallInst* CI = dyn_castCallInst(*ii)) { +if (CI-getCalledFunction() == KMA isaGlobalValue(CI-getOperand(1))) { + Value* V = CI-getOperand(1); //the kmem_cache_alloc + DSNodeHandle DSH = DSInfo[CI-getParent()-getParent()]-getNodeForValue(CI); + MetaPoolHandle L(locs[V]), N(DSH.getNode()-getMP()); + if (L.getPool() != N.getPool()) { +std::cerr kmem_cache_alloc recovered merge\n; +MetaPoolHandle L(locs[V]), N(DSH.getNode()-getMP()); +locs[V]-merge(DSH.getNode()-getMP()); + } + locs[V] = DSH.getNode()-getMP(); +} + } +} + } + +#endif + return false; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.653 - 1.654 --- Log message: Avoid to assert on (KnownZero KnownOne) == 0. --- Diffs of the changes: (+1 -1) InstructionCombining.cpp |2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.653 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.654 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.653 Mon Mar 12 00:44:52 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 12 11:54:56 2007 @@ -979,7 +979,7 @@ /// this predicate to simplify operations downstream. Mask is known to be zero /// for bits that V cannot have. static bool MaskedValueIsZero(Value *V, const APInt Mask, unsigned Depth = 0) { - APInt KnownZero(Mask), KnownOne(Mask); + APInt KnownZero(Mask.getBitWidth(), 0), KnownOne(Mask.getBitWidth(), 0); ComputeMaskedBits(V, Mask, KnownZero, KnownOne, Depth); assert((KnownZero KnownOne) == 0 Bits known to be one AND zero?); return (KnownZero Mask) == Mask; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.654 - 1.655 --- Log message: Add an APInt version of ShrinkDemandedConstant. Patch by Zhou Sheng. --- Diffs of the changes: (+24 -0) InstructionCombining.cpp | 24 1 files changed, 24 insertions(+) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.654 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.655 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.654 Mon Mar 12 11:54:56 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 12 12:15:10 2007 @@ -1004,6 +1004,30 @@ return true; } +/// ShrinkDemandedConstant - Check to see if the specified operand of the +/// specified instruction is a constant integer. If so, check to see if there +/// are any bits set in the constant that are not demanded. If so, shrink the +/// constant and return true. +static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo, + APInt Demanded) { + assert(I No instruction?); + assert(OpNo I-getNumOperands() Operand index too large); + + // If the operand is not a constant integer, nothing to do. + ConstantInt *OpC = dyn_castConstantInt(I-getOperand(OpNo)); + if (!OpC) return false; + + // If there are no bits set that aren't demanded, nothing to do. + Demanded.zextOrTrunc(OpC-getValue().getBitWidth()); + if ((~Demanded OpC-getValue()) == 0) +return false; + + // This instruction is producing bits that are not demanded. Shrink the RHS. + Demanded = OpC-getValue(); + I-setOperand(OpNo, ConstantInt::get(Demanded)); + return true; +} + // ComputeSignedMinMaxValuesFromKnownBits - Given a signed integer type and a // set of known zero and one bits, compute the maximum and minimum values that // could have the specified known zero and known one bits, returning them in ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.655 - 1.656 --- Log message: Add an APInt version of SimplifyDemandedBits. Patch by Zhou Sheng. --- Diffs of the changes: (+524 -1) InstructionCombining.cpp | 525 ++- 1 files changed, 524 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.655 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.656 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.655 Mon Mar 12 12:15:10 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 12 12:25:59 2007 @@ -319,10 +319,14 @@ /// most-complex to least-complex order. bool SimplifyCompare(CmpInst I); -bool SimplifyDemandedBits(Value *V, uint64_t Mask, +bool SimplifyDemandedBits(Value *V, uint64_t DemandedMask, uint64_t KnownZero, uint64_t KnownOne, unsigned Depth = 0); +bool SimplifyDemandedBits(Value *V, APInt DemandedMask, + APInt KnownZero, APInt KnownOne, + unsigned Depth = 0); + Value *SimplifyDemandedVectorElts(Value *V, uint64_t DemandedElts, uint64_t UndefElts, unsigned Depth = 0); @@ -1545,6 +1549,525 @@ return false; } +/// SimplifyDemandedBits - This function attempts to replace V with a simpler +/// value based on the demanded bits. When this function is called, it is known +/// that only the bits set in DemandedMask of the result of V are ever used +/// downstream. Consequently, depending on the mask and V, it may be possible +/// to replace V with a constant or one of its operands. In such cases, this +/// function does the replacement and returns true. In all other cases, it +/// returns false after analyzing the expression and setting KnownOne and known +/// to be one in the expression. KnownZero contains all the bits that are known +/// to be zero in the expression. These are provided to potentially allow the +/// caller (which might recursively be SimplifyDemandedBits itself) to simplify +/// the expression. KnownOne and KnownZero always follow the invariant that +/// KnownOne KnownZero == 0. That is, a bit can't be both 1 and 0. Note that +/// the bits in KnownOne and KnownZero may only be accurate for those bits set +/// in DemandedMask. Note also that the bitwidth of V, DemandedMask, KnownZero +/// and KnownOne must all be the same. +bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, +APInt KnownZero, APInt KnownOne, +unsigned Depth) { + assert(V != 0 Null pointer of Value???); + assert(Depth = 6 Limit Search Depth); + uint32_t BitWidth = DemandedMask.getBitWidth(); + const IntegerType *VTy = castIntegerType(V-getType()); + assert(VTy-getBitWidth() == BitWidth + KnownZero.getBitWidth() == BitWidth + KnownOne.getBitWidth() == BitWidth + Value *V, DemandedMask, KnownZero and KnownOne \ + must have same BitWidth); + if (ConstantInt *CI = dyn_castConstantInt(V)) { +// We know all of the bits for a constant! +KnownOne = CI-getValue() DemandedMask; +KnownZero = ~KnownOne DemandedMask; +return false; + } + + //KnownZero.clear(); + //KnownOne.clear(); + if (!V-hasOneUse()) {// Other users may use these bits. +if (Depth != 0) { // Not at the root. + // Just compute the KnownZero/KnownOne bits to simplify things downstream. + ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth); + return false; +} +// If this is the root being simplified, allow it to have multiple uses, +// just set the DemandedMask to all bits. +DemandedMask = APInt::getAllOnesValue(BitWidth); + } else if (DemandedMask == 0) { // Not demanding any bits from V. +if (V != UndefValue::get(VTy)) + return UpdateValueUsesWith(V, UndefValue::get(VTy)); +return false; + } else if (Depth == 6) {// Limit search depth. +return false; + } + + Instruction *I = dyn_castInstruction(V); + if (!I) return false;// Only analyze instructions. + + DemandedMask = APInt::getAllOnesValue(BitWidth); + + APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); + APInt RHSKnownZero = KnownZero, RHSKnownOne = KnownOne; + switch (I-getOpcode()) { + default: break; + case Instruction::And: +// If either the LHS or the RHS are Zero, the result is zero. +if (SimplifyDemandedBits(I-getOperand(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1)) + return true; +assert((RHSKnownZero RHSKnownOne) == 0 + Bits known to be one AND zero?); + +// If something is known zero on the RHS, the bits aren't demanded on the +
[llvm-commits] CVS: llvm/lib/Support/APInt.cpp
Changes in directory llvm/lib/Support: APInt.cpp updated: 1.69 - 1.70 --- Log message: For APInt::z/sext(width), if width == BitWidth, just return *this. --- Diffs of the changes: (+4 -0) APInt.cpp |4 1 files changed, 4 insertions(+) Index: llvm/lib/Support/APInt.cpp diff -u llvm/lib/Support/APInt.cpp:1.69 llvm/lib/Support/APInt.cpp:1.70 --- llvm/lib/Support/APInt.cpp:1.69 Sun Mar 4 18:00:42 2007 +++ llvm/lib/Support/APInt.cpp Mon Mar 12 12:47:45 2007 @@ -921,6 +921,8 @@ // Sign extend to a new width. APInt APInt::sext(uint32_t width) { + if (width == BitWidth) +return *this; assert(width BitWidth Invalid APInt SignExtend request); assert(width = IntegerType::MAX_INT_BITS Too many bits); // If the sign bit isn't set, this is the same as zext. @@ -969,6 +971,8 @@ // Zero extend to a new width. APInt APInt::zext(uint32_t width) { + if (width == BitWidth) +return *this; assert(width BitWidth Invalid APInt ZeroExtend request); assert(width = IntegerType::MAX_INT_BITS Too many bits); uint32_t wordsBefore = getNumWords(); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Support/APInt.cpp
Changes in directory llvm/lib/Support: APInt.cpp updated: 1.70 - 1.71 --- Log message: Revert the last patch as it violates the conditions of sext/zext. --- Diffs of the changes: (+0 -4) APInt.cpp |4 1 files changed, 4 deletions(-) Index: llvm/lib/Support/APInt.cpp diff -u llvm/lib/Support/APInt.cpp:1.70 llvm/lib/Support/APInt.cpp:1.71 --- llvm/lib/Support/APInt.cpp:1.70 Mon Mar 12 12:47:45 2007 +++ llvm/lib/Support/APInt.cpp Mon Mar 12 13:37:25 2007 @@ -921,8 +921,6 @@ // Sign extend to a new width. APInt APInt::sext(uint32_t width) { - if (width == BitWidth) -return *this; assert(width BitWidth Invalid APInt SignExtend request); assert(width = IntegerType::MAX_INT_BITS Too many bits); // If the sign bit isn't set, this is the same as zext. @@ -971,8 +969,6 @@ // Zero extend to a new width. APInt APInt::zext(uint32_t width) { - if (width == BitWidth) -return *this; assert(width BitWidth Invalid APInt ZeroExtend request); assert(width = IntegerType::MAX_INT_BITS Too many bits); uint32_t wordsBefore = getNumWords(); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
Re: [llvm-commits] CVS: llvm/lib/Support/APInt.cpp
On Mon, 2007-03-12 at 12:48 -0500, Zhou Sheng wrote: Changes in directory llvm/lib/Support: APInt.cpp updated: 1.69 - 1.70 --- Log message: For APInt::z/sext(width), if width == BitWidth, just return *this. Sheng, this is incorrect. It is not legal to use sext/zext with a bit width that is equal to the bit width of the APInt. Please see the definition of sext/zext in the language reference. APInt must implement the same operations (and restrictions on them) as the instructions do. In the future, please consult with me before making this kind of change. I have reverted this patch. Reid. --- Diffs of the changes: (+4 -0) APInt.cpp |4 1 files changed, 4 insertions(+) Index: llvm/lib/Support/APInt.cpp diff -u llvm/lib/Support/APInt.cpp:1.69 llvm/lib/Support/APInt.cpp:1.70 --- llvm/lib/Support/APInt.cpp:1.69 Sun Mar 4 18:00:42 2007 +++ llvm/lib/Support/APInt.cppMon Mar 12 12:47:45 2007 @@ -921,6 +921,8 @@ // Sign extend to a new width. APInt APInt::sext(uint32_t width) { + if (width == BitWidth) +return *this; assert(width BitWidth Invalid APInt SignExtend request); assert(width = IntegerType::MAX_INT_BITS Too many bits); // If the sign bit isn't set, this is the same as zext. @@ -969,6 +971,8 @@ // Zero extend to a new width. APInt APInt::zext(uint32_t width) { + if (width == BitWidth) +return *this; assert(width BitWidth Invalid APInt ZeroExtend request); assert(width = IntegerType::MAX_INT_BITS Too many bits); uint32_t wordsBefore = getNumWords(); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] [see] CVS: llvm-poolalloc/lib/DSA/Local.cpp
Changes in directory llvm-poolalloc/lib/DSA: Local.cpp updated: 1.158.2.4.2.5 - 1.158.2.4.2.6 --- Log message: add these --- Diffs of the changes: (+2 -0) Local.cpp |2 ++ 1 files changed, 2 insertions(+) Index: llvm-poolalloc/lib/DSA/Local.cpp diff -u llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.5 llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.6 --- llvm-poolalloc/lib/DSA/Local.cpp:1.158.2.4.2.5 Mon Mar 12 11:41:06 2007 +++ llvm-poolalloc/lib/DSA/Local.cppMon Mar 12 14:50:27 2007 @@ -1408,6 +1408,8 @@ AllocList.push_back(kmalloc); AllocList.push_back(__vmalloc); AllocList.push_back(kmem_cache_alloc); + FreeList.push_back(kfree); + FreeList.push_back(vfree); #endif const TargetData TD = getAnalysisTargetData(); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] llvm-gcc: emit switch cases with a wide range as a conditional branch
In gcc, a switch case is a range of values that branch to a label, for example 1 .. 17 - label. These are emitted as individual LLVM switch cases: 1 - label, 2 - label, ..., 17 - label. This works well except, for example, when the range is INT_MIN .. 0 - label, in which case you can say goodbye to all your memory! This patch causes ranges with more than 64 elements (128 on 64 bit machines) to be emitted as explicit if statements. For example, the following gcc switch (from the Ada testcase) INT_MIN .. -1 - block_neg 0 - block_zero default - block_default is emitted as switch i32 %n, label %0 [ i32 0, label %block_zero ] ; label:0 ; preds = %entry %tmp = sub i32 %n, -2147483648 ; i32 [#uses=1] icmp ule i32 %tmp, 2147483647 ; i1:2 [#uses=1] br i1 %2, label %block_neg, label %case_false case_false: ; preds = %0 br label %block_default The if statements are placed in the default block of the switch, with a branch to the real default label if none of them fires. Ciao, Duncan. Index: gcc.llvm.master/gcc/llvm-convert.cpp === --- gcc.llvm.master.orig/gcc/llvm-convert.cpp 2007-03-12 14:16:34.0 +0100 +++ gcc.llvm.master/gcc/llvm-convert.cpp 2007-03-12 14:34:41.0 +0100 @@ -1673,14 +1673,13 @@ EmitBlock(new BasicBlock()); SI-setSuccessor(0, CurBB); // Default location starts out as fall-through - // Output the body of the switch. - if (SWITCH_BODY(exp)) -Emit(SWITCH_BODY(exp), 0); - + assert(!SWITCH_BODY(exp) not a gimple switch?); + + BasicBlock *DefaultDest = NULL; for (unsigned i = 0, e = TREE_VEC_LENGTH(Cases); i != e; ++i) { BasicBlock *Dest = getLabelDeclBlock(CASE_LABEL(TREE_VEC_ELT(Cases, i))); if (CASE_LOW(TREE_VEC_ELT(Cases, i)) == 0) { - SI-setSuccessor(0, Dest); // Change the default destination. + DefaultDest = Dest; continue; } @@ -1693,19 +1692,37 @@ continue; } -// Otherwise, we have a range, like 'case 1 ... 17'. Add all of the -// necessary successors to the switch. +// Otherwise, we have a range, like 'case 1 ... 17'. Val = Emit(CASE_HIGH(TREE_VEC_ELT(Cases, i)), 0); -// Make sure the case value is the same type as the switch expression (int) +// Make sure the case value is the same type as the switch expression Val = CastToSIntType(Val, SwitchExp-getType()); ConstantInt *HiC = castConstantInt(Val); -Constant *OneC = ConstantInt::get(ValC-getType(), 1); -while (1) { - SI-addCase(ValC, Dest); - if (ValC == HiC) break; // Emitted the last one. - ValC = castConstantInt(ConstantExpr::getAdd(ValC, OneC)); +ConstantInt *Range = castConstantInt(ConstantExpr::getSub(HiC, ValC)); +if (Range-getZExtValue() 2*HOST_BITS_PER_WIDE_INT) { + // Add all of the necessary successors to the switch. + Constant *OneC = ConstantInt::get(ValC-getType(), 1); + while (1) { +SI-addCase(ValC, Dest); +if (ValC == HiC) break; // Emitted the last one. +ValC = castConstantInt(ConstantExpr::getAdd(ValC, OneC)); + } +} else { + // The range is too big to add to the switch - emit an if. + Value *Diff = BinaryOperator::create(Instruction::Sub, SwitchExp, ValC, + tmp, CurBB); + Value *Cond = new ICmpInst(ICmpInst::ICMP_ULE, Diff, Range, tmp, CurBB); + BasicBlock *False_Block = new BasicBlock(case_false); + new BranchInst(Dest, False_Block, Cond, CurBB); + EmitBlock(False_Block); } } + + if (DefaultDest) +if (SI-getSuccessor(0) == CurBB) + SI-setSuccessor(0, DefaultDest); +else + new BranchInst(DefaultDest, CurBB); + return 0; } Index: llvm.master/test/AdaFrontend/switch.adb === --- /dev/null 1970-01-01 00:00:00.0 + +++ llvm.master/test/AdaFrontend/switch.adb 2007-03-12 21:05:57.0 +0100 @@ -0,0 +1,12 @@ +-- RUN: %llvmgcc -c %s -o /dev/null +function Switch (N : Integer) return Integer is +begin + case N is + when Integer'First .. -1 = + return -1; + when 0 = + return 0; + when others = + return 1; + end case; +end; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] [124887] Fix component reference handling.
Revision: 124887 Author: dpatel Date: 2007-03-12 15:27:39 -0700 (Mon, 12 Mar 2007) Log Message: --- Fix component reference handling. Patch by Duncan Sands. Modified Paths: -- apple-local/branches/llvm/gcc/llvm-convert.cpp Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp === --- apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-03-12 18:24:41 UTC (rev 124886) +++ apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-03-12 22:27:39 UTC (rev 124887) @@ -4596,6 +4596,20 @@ return Result; } +/// getComponentRefOffsetInBits - Return the offset (in bits) of the field +/// referenced in a COMPONENT_REF exp. +static unsigned getComponentRefOffsetInBits(tree exp) { + assert(TREE_CODE(exp) == COMPONENT_REF not a COMPONENT_REF!); + tree field = TREE_OPERAND(exp, 1); + assert(TREE_CODE(field) == FIELD_DECL not a FIELD_DECL!); + tree field_offset = component_ref_field_offset (exp); + assert(DECL_FIELD_BIT_OFFSET(field) field_offset); + unsigned Result = TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(field)); + if (TREE_CODE(field_offset) == INTEGER_CST) +Result += TREE_INT_CST_LOW(field_offset)*8; + return Result; +} + LValue TreeToLLVM::EmitLV_COMPONENT_REF(tree exp) { LValue StructAddrLV = EmitLV(TREE_OPERAND(exp, 0)); tree FieldDecl = TREE_OPERAND(exp, 1); @@ -4618,11 +4632,12 @@ // BitStart - This is the actual offset of the field from the start of the // struct, in bits. For bitfields this may be on a non-byte boundary. - unsigned BitStart = getFieldOffsetInBits(FieldDecl); + unsigned BitStart = getComponentRefOffsetInBits(exp); Value *FieldPtr; + tree field_offset = component_ref_field_offset (exp); // If this is a normal field at a fixed offset from the start, handle it. - if (TREE_CODE(DECL_FIELD_OFFSET(FieldDecl)) == INTEGER_CST) { + if (TREE_CODE(field_offset) == INTEGER_CST) { assert(DECL_LLVM_SET_P(FieldDecl) Struct not laid out for LLVM?); ConstantInt *CI = castConstantInt(DECL_LLVM(FieldDecl)); uint32_t MemberIndex = CI-getZExtValue(); @@ -4646,7 +4661,7 @@ } } else { -Value *Offset = Emit(DECL_FIELD_OFFSET(FieldDecl), 0); +Value *Offset = Emit(field_offset, 0); Value *Ptr = CastToType(Instruction::PtrToInt, StructAddrLV.Ptr, Offset-getType()); Ptr = BinaryOperator::createAdd(Ptr, Offset, tmp, CurBB); @@ -5663,13 +5678,14 @@ // BitStart - This is the actual offset of the field from the start of the // struct, in bits. For bitfields this may be on a non-byte boundary. - unsigned BitStart = getFieldOffsetInBits(FieldDecl); + unsigned BitStart = getComponentRefOffsetInBits(exp); unsigned BitSize = 0; Constant *FieldPtr; const TargetData TD = getTargetData(); - + + tree field_offset = component_ref_field_offset (exp); // If this is a normal field at a fixed offset from the start, handle it. - if (TREE_CODE(DECL_FIELD_OFFSET(FieldDecl)) == INTEGER_CST) { + if (TREE_CODE(field_offset) == INTEGER_CST) { assert(DECL_LLVM_SET_P(FieldDecl) Struct not laid out for LLVM?); ConstantInt *CI = castConstantInt(DECL_LLVM(FieldDecl)); uint64_t MemberIndex = CI-getZExtValue(); @@ -5689,18 +5705,18 @@ } } else { // We were unable to make a nice offset, emit an ugly one. - Constant *Offset = Convert(DECL_FIELD_OFFSET(FieldDecl)); + Constant *Offset = Convert(field_offset); FieldPtr = ConstantExpr::getPtrToInt(StructAddrLV, Offset-getType()); FieldPtr = ConstantExpr::getAdd(FieldPtr, Offset); FieldPtr = ConstantExpr::getIntToPtr(FieldPtr, PointerType::get(FieldTy)); // Do horrible pointer arithmetic to get the address of the field. - unsigned ByteOffset = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(FieldDecl)); + unsigned ByteOffset = TREE_INT_CST_LOW(field_offset); BitStart -= ByteOffset * 8; } } else { -Constant *Offset = Convert(DECL_FIELD_OFFSET(FieldDecl)); +Constant *Offset = Convert(field_offset); Constant *Ptr = ConstantExpr::getPtrToInt(StructAddrLV, Offset-getType()); Ptr = ConstantExpr::getAdd(Ptr, Offset); FieldPtr = ConstantExpr::getIntToPtr(Ptr, PointerType::get(FieldTy)); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
Re: [llvm-commits] llvm-gcc: use component_ref_field_offset in component references
On Mar 2, 2007, at 6:36 AM, Duncan Sands wrote: The third operand of a COMPONENT_REF represents the byte offset of the field; it is accessed using component_ref_field_offset. Most of the time you can get away with extracting the offset from the type, using DECL_FIELD_OFFSET, which is what is done currently, but this can fail if DECL_FIELD_OFFSET contains a PLACEHOLDER_EXPR for example. The NON_LVALUE_EXPR Ada testcase also tests this one. Applied. - Devang ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] [124921] Support arrays with non-zero lower bound
Revision: 124921 Author: dpatel Date: 2007-03-12 16:07:59 -0700 (Mon, 12 Mar 2007) Log Message: --- Support arrays with non-zero lower bound Patch by Duncan Sands. Modified Paths: -- apple-local/branches/llvm/gcc/llvm-abi.h apple-local/branches/llvm/gcc/llvm-convert.cpp apple-local/branches/llvm/gcc/llvm-internal.h apple-local/branches/llvm/gcc/llvm-types.cpp Modified: apple-local/branches/llvm/gcc/llvm-abi.h === --- apple-local/branches/llvm/gcc/llvm-abi.h2007-03-12 22:37:51 UTC (rev 124920) +++ apple-local/branches/llvm/gcc/llvm-abi.h2007-03-12 23:07:59 UTC (rev 124921) @@ -110,16 +110,11 @@ } return FoundField ? isSingleElementStructOrArray(FoundField) : 0; case ARRAY_TYPE: -tree Domain = TYPE_DOMAIN(type); -if (!Domain || !TYPE_MIN_VALUE(Domain) || !TYPE_MAX_VALUE(Domain)) +if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST) return 0; -if (TREE_CODE(TYPE_SIZE(type)) != INTEGER_CST || -TREE_CODE(TYPE_MIN_VALUE(Domain)) != INTEGER_CST || -TREE_CODE(TYPE_MAX_VALUE(Domain)) != INTEGER_CST) +tree length = arrayLength(type); +if (!length || !integer_onep(length)) return 0; -if (TREE_INT_CST_LOW(TYPE_MAX_VALUE(Domain)) != -TREE_INT_CST_LOW(TYPE_MIN_VALUE(Domain))) - return 0; return isSingleElementStructOrArray(TREE_TYPE(type)); } } Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp === --- apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-03-12 22:37:51 UTC (rev 124920) +++ apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-03-12 23:07:59 UTC (rev 124921) @@ -1353,18 +1353,14 @@ DECL_USER_ALIGN(decl) = 0; Alignment = DECL_ALIGN(decl)/8; } else { +tree length; + // Dynamic-size object: must push space on the stack. -if (TREE_CODE(type) == ARRAY_TYPE TYPE_DOMAIN(type)) { +if (TREE_CODE(type) == ARRAY_TYPE (length = arrayLength(type))) { Ty = ConvertType(TREE_TYPE(type)); // Get array element type. - // Compute the size of the number of elements of the array. - Size = Emit(TYPE_MAX_VALUE(TYPE_DOMAIN(type)), 0); - Size = CastToUIntType(Size, Type::Int32Ty); - - // Annoyingly, TYPE_MAX_VALUE returns the maximum valid index, NOT the - // number of elements in the array. Thus, we must add one to the returned - // value. This addition should be optimized out later. - Size = BinaryOperator::createAdd(Size, ConstantInt::get(Type::Int32Ty, 1), - tmp, CurBB); + // Compute the number of elements in the array. + Size = Emit(length, 0); + Size = CastToUIntType(Size, Size-getType()); } else { // Compute the variable's size in bytes. Size = CastToUIntType(Emit(DECL_SIZE_UNIT(decl), 0), Type::Int32Ty); @@ -4538,9 +4534,8 @@ // If this is an index into an array, codegen as a GEP. if (TREE_CODE(TREE_TYPE(Array)) == ARRAY_TYPE) { // Check for variable sized array reference. -tree Domain = TYPE_DOMAIN(TREE_TYPE(Array)); -if (Domain TYPE_MAX_VALUE(Domain) -TREE_CODE(TYPE_MAX_VALUE(Domain)) != INTEGER_CST) { +tree length = arrayLength(TREE_TYPE(Array)); +if (length !host_integerp(length, 1)) { // Make sure that ArrayAddr is of type ElementTy*, then do a 2-index gep. tree ElTy = TREE_TYPE(TREE_TYPE(Array)); ArrayAddr = BitCastToType(ArrayAddr, PointerType::get(Type::Int8Ty)); @@ -5003,7 +4998,7 @@ // If this is a variable sized array type, set the length to Len. if (ConstantSize == 0) { tree Domain = TYPE_DOMAIN(TREE_TYPE(exp)); - if (Domain == 0 || TYPE_MAX_VALUE(Domain) == 0) { + if (!Domain || !TYPE_MAX_VALUE(Domain)) { ConstantSize = Len; StrTy = ArrayType::get(ElTy, Len); } @@ -5102,21 +5097,23 @@ // type indirectly. assert(TREE_CODE(TREE_TYPE(exp)) != VECTOR_TYPE VECTOR_TYPE's haven't been tested!); - - // If we have constant lower bound for the range of the type, get it. */ + + // If we have a lower bound for the range of the type, get it. */ tree Domain = TYPE_DOMAIN(TREE_TYPE(exp)); - unsigned MinElement = 0; - if (Domain TYPE_MIN_VALUE(Domain) - host_integerp(TYPE_MIN_VALUE(Domain), 0)) -MinElement = tree_low_cst(TYPE_MIN_VALUE(Domain), 0); - + tree min_element = size_zero_node; + if (Domain TYPE_MIN_VALUE(Domain)) +min_element = fold_convert(sizetype, TYPE_MIN_VALUE(Domain)); + std::vectorConstant* ResultElts; Constant *SomeVal = 0; - if (Domain TYPE_MAX_VALUE(Domain) - host_integerp(TYPE_MAX_VALUE(Domain), 0)) { -unsigned MaxElement = tree_low_cst(TYPE_MAX_VALUE(Domain), 0); -ResultElts.resize(MaxElement-MinElement+1); + if (Domain TYPE_MAX_VALUE(Domain)) { +tree max_element =
Re: [llvm-commits] llvm-gcc: support arrays with non-zero lower bound
On Mar 2, 2007, at 6:19 AM, Duncan Sands wrote: Refreshed patch after Chris's array indexing changes. Applied. - Devang ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h
Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.111 - 1.112 --- Log message: More flexible TargetLowering LSR hooks for testing whether an immediate is a legal target address immediate or scale. --- Diffs of the changes: (+10 -20) TargetLowering.h | 30 ++ 1 files changed, 10 insertions(+), 20 deletions(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.111 llvm/include/llvm/Target/TargetLowering.h:1.112 --- llvm/include/llvm/Target/TargetLowering.h:1.111 Wed Mar 7 10:25:08 2007 +++ llvm/include/llvm/Target/TargetLowering.h Mon Mar 12 18:26:27 2007 @@ -856,18 +856,18 @@ // Loop Strength Reduction hooks // - /// isLegalAddressImmediate - Return true if the integer value or GlobalValue - /// can be used as the offset of the target addressing mode. - virtual bool isLegalAddressImmediate(int64_t V) const; + /// isLegalAddressImmediate - Return true if the integer value can be used as + /// the offset of the target addressing mode for load / store of the given + /// type. + virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const; + + /// isLegalAddressImmediate - Return true if the GlobalValue can be used as + /// the offset of the target addressing mode. virtual bool isLegalAddressImmediate(GlobalValue *GV) const; - typedef std::vectorunsigned::const_iterator legal_am_scale_iterator; - legal_am_scale_iterator legal_am_scale_begin() const { -return LegalAddressScales.begin(); - } - legal_am_scale_iterator legal_am_scale_end() const { -return LegalAddressScales.end(); - } + /// isLegalAddressScale - Return true if the integer value can be used as the + /// scale of the target addressing mode for load / store of the given type. + virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const; //======// // Div utility functions @@ -906,17 +906,7 @@ return CmpLibcallCCs[Call]; } -protected: - /// addLegalAddressScale - Add a integer ( 1) value which can be used as - /// scale in the target addressing mode. Note: the ordering matters so the - /// least efficient ones should be entered first. - void addLegalAddressScale(unsigned Scale) { -LegalAddressScales.push_back(Scale); - } - private: - std::vectorunsigned LegalAddressScales; - TargetMachine TM; const TargetData *TD; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.116 - 1.117 --- Log message: Use new TargetLowering addressing modes hooks. --- Diffs of the changes: (+18 -20) LoopStrengthReduce.cpp | 38 ++ 1 files changed, 18 insertions(+), 20 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.116 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.117 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.116 Fri Mar 9 15:19:53 2007 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Mar 12 18:27:37 2007 @@ -612,12 +612,12 @@ /// immediate field of a target instruction. static bool isTargetConstant(const SCEVHandle V, const TargetLowering *TLI) { if (SCEVConstant *SC = dyn_castSCEVConstant(V)) { -int64_t V = SC-getValue()-getSExtValue(); +int64_t VC = SC-getValue()-getSExtValue(); if (TLI) - return TLI-isLegalAddressImmediate(V); + return TLI-isLegalAddressImmediate(VC, V-getType()); else // Defaults to PPC. PPC allows a sign-extended 16-bit immediate field. - return (V -(1 16) V (1 16)-1); + return (VC -(1 16) VC (1 16)-1); } if (SCEVUnknown *SU = dyn_castSCEVUnknown(V)) @@ -878,24 +878,22 @@ int64_t SInt = SC-getValue()-getSExtValue(); if (SInt == 1) return 0; -for (TargetLowering::legal_am_scale_iterator - I = TLI-legal_am_scale_begin(), E = TLI-legal_am_scale_end(); - I != E; ++I) { - unsigned Scale = *I; - if (unsigned(abs(SInt)) Scale || (SInt % Scale) != 0) +for (std::mapSCEVHandle, IVsOfOneStride::iterator SI= IVsByStride.begin(), + SE = IVsByStride.end(); SI != SE; ++SI) { + int64_t SSInt = castSCEVConstant(SI-first)-getValue()-getSExtValue(); + if (unsigned(abs(SInt)) SSInt || (SInt % SSInt) != 0) continue; - std::mapSCEVHandle, IVsOfOneStride::iterator SI = -IVsByStride.find(SCEVUnknown::getIntegerSCEV(SInt/Scale, UIntPtrTy)); - if (SI == IVsByStride.end()) -continue; - for (std::vectorIVExpr::iterator II = SI-second.IVs.begin(), - IE = SI-second.IVs.end(); II != IE; ++II) -// FIXME: Only handle base == 0 for now. -// Only reuse previous IV if it would not require a type conversion. -if (isZero(II-Base) II-Base-getType() == Ty) { - IV = *II; - return Scale; -} + int64_t Scale = SInt / SSInt; + if (TLI-isLegalAddressScale(Scale, Ty)) { +for (std::vectorIVExpr::iterator II = SI-second.IVs.begin(), + IE = SI-second.IVs.end(); II != IE; ++II) + // FIXME: Only handle base == 0 for now. + // Only reuse previous IV if it would not require a type conversion. + if (isZero(II-Base) II-Base-getType() == Ty) { +IV = *II; +return Scale; + } + } } } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.367 - 1.368 X86ISelLowering.h updated: 1.91 - 1.92 --- Log message: More flexible TargetLowering LSR hooks for testing whether an immediate is a legal target address immediate or scale. --- Diffs of the changes: (+33 -16) X86ISelLowering.cpp | 34 +- X86ISelLowering.h | 15 --- 2 files changed, 33 insertions(+), 16 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.367 llvm/lib/Target/X86/X86ISelLowering.cpp:1.368 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.367 Mon Mar 12 17:58:52 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Mar 12 18:28:50 2007 @@ -64,16 +64,6 @@ setUseUnderscoreLongJmp(true); } - // Add legal addressing mode scale values. - addLegalAddressScale(8); - addLegalAddressScale(4); - addLegalAddressScale(2); - // Enter the ones which require both scale + index last. These are more - // expensive. - addLegalAddressScale(9); - addLegalAddressScale(5); - addLegalAddressScale(3); - // Set up the register classes. addRegisterClass(MVT::i8, X86::GR8RegisterClass); addRegisterClass(MVT::i16, X86::GR16RegisterClass); @@ -4016,13 +4006,16 @@ } } -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -bool X86TargetLowering::isLegalAddressImmediate(int64_t V) const { +/// isLegalAddressImmediate - Return true if the integer value can be used +/// as the offset of the target addressing mode for load / store of the +/// given type. +bool X86TargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{ // X86 allows a sign-extended 32-bit immediate field. return (V -(1LL 32) V (1LL 32)-1); } +/// isLegalAddressImmediate - Return true if the GlobalValue can be used as +/// the offset of the target addressing mode. bool X86TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { // In 64-bit mode, GV is 64-bit so it won't fit in the 32-bit displacement // field unless we are in small code model. @@ -4033,6 +4026,21 @@ return (!Subtarget-GVRequiresExtraLoad(GV, getTargetMachine(), false)); } +/// isLegalAddressScale - Return true if the integer value can be used as the +/// scale of the target addressing mode for load / store of the given type. +bool X86TargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const { + switch (S) { + default: +return false; + case 2: case 4: case 8: +return true; + // FIXME: These require both scale + index last and thus more expensive. + // How to tell LSR to try for 2, 4, 8 first? + case 3: case 5: case 9: +return true; + } +} + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.91 llvm/lib/Target/X86/X86ISelLowering.h:1.92 --- llvm/lib/Target/X86/X86ISelLowering.h:1.91 Fri Mar 2 17:16:35 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Mar 12 18:28:50 2007 @@ -335,11 +335,20 @@ getRegForInlineAsmConstraint(const std::string Constraint, MVT::ValueType VT) const; -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -virtual bool isLegalAddressImmediate(int64_t V) const; +/// isLegalAddressImmediate - Return true if the integer value can be used +/// as the offset of the target addressing mode for load / store of the +/// given type. +virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const; + +/// isLegalAddressImmediate - Return true if the GlobalValue can be used as +/// the offset of the target addressing mode. virtual bool isLegalAddressImmediate(GlobalValue *GV) const; +/// isLegalAddressScale - Return true if the integer value can be used as +/// the scale of the target addressing mode for load / store of the given +/// type. +virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const; + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h
Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.260 - 1.261 PPCISelLowering.h updated: 1.61 - 1.62 --- Log message: More flexible TargetLowering LSR hooks for testing whether an immediate is a legal target address immediate or scale. --- Diffs of the changes: (+10 -5) PPCISelLowering.cpp |5 +++-- PPCISelLowering.h | 10 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.260 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.261 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.260 Mon Mar 5 18:59:59 2007 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Mar 12 18:29:01 2007 @@ -3152,8 +3152,9 @@ } /// isLegalAddressImmediate - Return true if the integer value can be used -/// as the offset of the target addressing mode. -bool PPCTargetLowering::isLegalAddressImmediate(int64_t V) const { +/// as the offset of the target addressing mode for load / store of the +/// given type. +bool PPCTargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{ // PPC allows a sign-extended 16-bit immediate field. return (V -(1 16) V (1 16)-1); } Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.61 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.62 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.61 Thu Mar 1 07:11:38 2007 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Mon Mar 12 18:29:01 2007 @@ -237,9 +237,13 @@ SelectionDAG DAG); /// isLegalAddressImmediate - Return true if the integer value can be used -/// as the offset of the target addressing mode. -virtual bool isLegalAddressImmediate(int64_t V) const; -virtual bool isLegalAddressImmediate(llvm::GlobalValue*) const; +/// as the offset of the target addressing mode for load / store of the +/// given type. +virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const; + +/// isLegalAddressImmediate - Return true if the GlobalValue can be used as +/// the offset of the target addressing mode. +virtual bool isLegalAddressImmediate(GlobalValue *GV) const; SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG DAG); }; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelLowering.cpp ARMISelLowering.h
Changes in directory llvm/lib/Target/ARM: ARMISelLowering.cpp updated: 1.20 - 1.21 ARMISelLowering.h updated: 1.2 - 1.3 --- Log message: Updated TargetLowering LSR addressing mode hooks for ARM and Thumb. --- Diffs of the changes: (+88 -8) ARMISelLowering.cpp | 81 ARMISelLowering.h | 15 +++-- 2 files changed, 88 insertions(+), 8 deletions(-) Index: llvm/lib/Target/ARM/ARMISelLowering.cpp diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.20 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.21 --- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.20Thu Mar 8 15:59:30 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp Mon Mar 12 18:30:29 2007 @@ -30,6 +30,7 @@ #include llvm/CodeGen/SSARegMap.h #include llvm/Target/TargetOptions.h #include llvm/ADT/VectorExtras.h +#include llvm/Support/MathExtras.h using namespace llvm; ARMTargetLowering::ARMTargetLowering(TargetMachine TM) @@ -1268,17 +1269,87 @@ // ARM Optimization Hooks //===--===// -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -bool ARMTargetLowering::isLegalAddressImmediate(int64_t V) const { - // ARM allows a 12-bit immediate field. - return V == V ((1LL 12) - 1); +/// isLegalAddressImmediate - Return true if the integer value can be used +/// as the offset of the target addressing mode for load / store of the +/// given type. +bool ARMTargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{ + MVT::ValueType VT = getValueType(Ty); + if (Subtarget-isThumb()) { +if (V 0) + return false; + +unsigned Scale = 1; +switch (VT) { +default: return false; +case MVT::i1: +case MVT::i8: + // Scale == 1; + break; +case MVT::i16: + // Scale == 2; + Scale = 2; + break; +case MVT::i32: + // Scale == 4; + Scale = 4; + break; +} + +if ((V (Scale - 1)) != 0) + return false; +V /= Scale; +return V == V ((1LL 5) - 1); + } + + if (V 0) +V = - V; + switch (VT) { + default: return false; + case MVT::i1: + case MVT::i8: + case MVT::i32: +// +- imm12 +return V == V ((1LL 12) - 1); + case MVT::i16: +// +- imm8 +return V == V ((1LL 8) - 1); + case MVT::f32: + case MVT::f64: +if (!Subtarget-hasVFP2()) + return false; +if ((V % 3) != 0) + return false; +V = 2; +return V == V ((1LL 8) - 1); + } } bool ARMTargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { return false; } +/// isLegalAddressScale - Return true if the integer value can be used as +/// the scale of the target addressing mode for load / store of the given +/// type. +bool ARMTargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const { + if (Subtarget-isThumb()) +return false; + + MVT::ValueType VT = getValueType(Ty); + switch (VT) { + default: return false; + case MVT::i1: + case MVT::i8: + case MVT::i32: +// r + r +if (S == 2) + return true; +// r + r imm +S = ~1; +return isPowerOf2_32(S); + } +} + static bool getIndexedAddressParts(SDNode *Ptr, MVT::ValueType VT, bool isSEXTLoad, SDOperand Base, SDOperand Offset, bool isInc, Index: llvm/lib/Target/ARM/ARMISelLowering.h diff -u llvm/lib/Target/ARM/ARMISelLowering.h:1.2 llvm/lib/Target/ARM/ARMISelLowering.h:1.3 --- llvm/lib/Target/ARM/ARMISelLowering.h:1.2 Tue Jan 30 14:37:08 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.h Mon Mar 12 18:30:29 2007 @@ -80,11 +80,20 @@ virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, MachineBasicBlock *MBB); -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -virtual bool isLegalAddressImmediate(int64_t V) const; +/// isLegalAddressImmediate - Return true if the integer value can be used +/// as the offset of the target addressing mode for load / store of the +/// given type. +virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const; + +/// isLegalAddressImmediate - Return true if the GlobalValue can be used as +/// the offset of the target addressing mode. virtual bool isLegalAddressImmediate(GlobalValue *GV) const; +/// isLegalAddressScale - Return true if the integer value can be used as +/// the scale of the target addressing mode for load / store of the given +/// type. +virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const; + /// getPreIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if the node's address
[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Changes in directory llvm/lib/CodeGen/SelectionDAG: TargetLowering.cpp updated: 1.95 - 1.96 --- Log message: More flexible TargetLowering LSR hooks for testing whether an immediate is a legal target address immediate or scale. --- Diffs of the changes: (+13 -3) TargetLowering.cpp | 16 +--- 1 files changed, 13 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp diff -u llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.95 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.96 --- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.95 Sat Feb 24 19:28:05 2007 +++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cppMon Mar 12 18:37:10 2007 @@ -1931,15 +1931,25 @@ // Loop Strength Reduction hooks //===--===// -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -bool TargetLowering::isLegalAddressImmediate(int64_t V) const { +/// isLegalAddressImmediate - Return true if the integer value can be used as +/// the offset of the target addressing mode for load / store of the given +/// type. +bool TargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const { return false; } + +/// isLegalAddressImmediate - Return true if the GlobalValue can be used as +/// the offset of the target addressing mode. bool TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { return false; } +/// isLegalAddressScale - Return true if the integer value can be used as the +/// scale of the target addressing mode for load / store of the given type. +bool TargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const { + return false; +} + // Magic for divide replacement ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.656 - 1.657 --- Log message: In APInt version ComputeMaskedBits(): 1. Ensure VTy, KnownOne and KnownZero have same bitwidth. 2. Make code more efficient. --- Diffs of the changes: (+28 -15) InstructionCombining.cpp | 43 --- 1 files changed, 28 insertions(+), 15 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.656 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.657 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.656 Mon Mar 12 12:25:59 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 12 21:23:10 2007 @@ -582,29 +582,30 @@ /// this won't lose us code quality. static void ComputeMaskedBits(Value *V, APInt Mask, APInt KnownZero, APInt KnownOne, unsigned Depth = 0) { + assert(V No Value?); + assert(Depth = 6 Limit Search Depth); uint32_t BitWidth = Mask.getBitWidth(); - assert(KnownZero.getBitWidth() == BitWidth + const IntegerType *VTy = castIntegerType(V-getType()); + assert(VTy-getBitWidth() == BitWidth + KnownZero.getBitWidth() == BitWidth KnownOne.getBitWidth() == BitWidth - Mask, KnownOne and KnownZero should have same BitWidth); + VTy, Mask, KnownOne and KnownZero should have same BitWidth); if (ConstantInt *CI = dyn_castConstantInt(V)) { // We know all of the bits for a constant! -APInt Tmp(CI-getValue()); -Tmp.zextOrTrunc(BitWidth); -KnownOne = Tmp Mask; +KnownOne = CI-getValue() Mask; KnownZero = ~KnownOne Mask; return; } - KnownZero.clear(); KnownOne.clear(); // Don't know anything. if (Depth == 6 || Mask == 0) return; // Limit search depth. Instruction *I = dyn_castInstruction(V); if (!I) return; + KnownZero.clear(); KnownOne.clear(); // Don't know anything. APInt KnownZero2(KnownZero), KnownOne2(KnownOne); - Mask = APInt::getAllOnesValue( -castIntegerType(V-getType())-getBitWidth()).zextOrTrunc(BitWidth); + Mask = APInt::getAllOnesValue(BitWidth); switch (I-getOpcode()) { case Instruction::And: @@ -664,10 +665,16 @@ case Instruction::UIToFP: case Instruction::IntToPtr: return; // Can't work with floating point or pointers - case Instruction::Trunc: + case Instruction::Trunc: { // All these have integer operands -ComputeMaskedBits(I-getOperand(0), Mask, KnownZero, KnownOne, Depth+1); +uint32_t SrcBitWidth = + castIntegerType(I-getOperand(0)-getType())-getBitWidth(); +ComputeMaskedBits(I-getOperand(0), Mask.zext(SrcBitWidth), + KnownZero.zext(SrcBitWidth), KnownOne.zext(SrcBitWidth), Depth+1); +KnownZero.trunc(BitWidth); +KnownOne.trunc(BitWidth); return; + } case Instruction::BitCast: { const Type *SrcTy = I-getOperand(0)-getType(); if (SrcTy-isInteger()) { @@ -681,10 +688,13 @@ const IntegerType *SrcTy = castIntegerType(I-getOperand(0)-getType()); APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy-getBitWidth())); -Mask = SrcTy-getMask().zextOrTrunc(BitWidth); -ComputeMaskedBits(I-getOperand(0), Mask, KnownZero, KnownOne, Depth+1); +uint32_t SrcBitWidth = SrcTy-getBitWidth(); +ComputeMaskedBits(I-getOperand(0), Mask.trunc(SrcBitWidth), + KnownZero.trunc(SrcBitWidth), KnownOne.trunc(SrcBitWidth), Depth+1); assert((KnownZero KnownOne) == 0 Bits known to be one AND zero?); // The top bits are known to be zero. +KnownZero.zext(BitWidth); +KnownOne.zext(BitWidth); KnownZero |= NewBits; return; } @@ -693,14 +703,17 @@ const IntegerType *SrcTy = castIntegerType(I-getOperand(0)-getType()); APInt NewBits(APInt::getAllOnesValue(BitWidth).shl(SrcTy-getBitWidth())); -Mask = SrcTy-getMask().zextOrTrunc(BitWidth); -ComputeMaskedBits(I-getOperand(0), Mask, KnownZero, KnownOne, Depth+1); +uint32_t SrcBitWidth = SrcTy-getBitWidth(); +ComputeMaskedBits(I-getOperand(0), Mask.trunc(SrcBitWidth), + KnownZero.trunc(SrcBitWidth), KnownOne.trunc(SrcBitWidth), Depth+1); assert((KnownZero KnownOne) == 0 Bits known to be one AND zero?); +KnownZero.zext(BitWidth); +KnownOne.zext(BitWidth); // If the sign bit of the input is known set or clear, then we know the // top bits of the result. APInt InSignBit(APInt::getSignBit(SrcTy-getBitWidth())); -InSignBit.zextOrTrunc(BitWidth); +InSignBit.zext(BitWidth); if ((KnownZero InSignBit) != 0) { // Input sign bit known zero KnownZero |= NewBits; KnownOne = ~NewBits; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/include/llvm/ADT/APInt.h
Changes in directory llvm/include/llvm/ADT: APInt.h updated: 1.41 - 1.42 --- Log message: Add zextOrCopy() into APInt for convenience. --- Diffs of the changes: (+9 -0) APInt.h |9 + 1 files changed, 9 insertions(+) Index: llvm/include/llvm/ADT/APInt.h diff -u llvm/include/llvm/ADT/APInt.h:1.41 llvm/include/llvm/ADT/APInt.h:1.42 --- llvm/include/llvm/ADT/APInt.h:1.41 Sun Mar 11 01:16:10 2007 +++ llvm/include/llvm/ADT/APInt.h Tue Mar 13 01:16:26 2007 @@ -450,6 +450,15 @@ /// @brief Zero extend or truncate to width APInt zextOrTrunc(uint32_t width); + /// This is a help function for convenience. If the given \p width equals to + /// this APInt's BitWidth, just return this APInt, otherwise, just zero + /// extend it. + inline APInt zextOrCopy(uint32_t width) { +if (width == BitWidth) + return *this; +return zext(width); + } + /// @brief Set every bit to 1. APInt set(); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.657 - 1.658 --- Log message: For expression like APInt::getAllOnesValue(ShiftAmt).zextOrCopy(BitWidth), to handle ShiftAmt == BitWidth situation, use zextOrCopy() instead of zext(). --- Diffs of the changes: (+3 -3) InstructionCombining.cpp |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.657 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.658 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.657 Mon Mar 12 21:23:10 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Mar 13 01:40:59 2007 @@ -1995,7 +1995,7 @@ RHSKnownZero = ShiftAmt; RHSKnownOne = ShiftAmt; // low bits known zero. - RHSKnownZero |= APInt::getAllOnesValue(ShiftAmt).zext(BitWidth); + RHSKnownZero |= APInt::getAllOnesValue(ShiftAmt).zextOrCopy(BitWidth); } break; case Instruction::LShr: @@ -2012,7 +2012,7 @@ assert((RHSKnownZero RHSKnownOne) == 0 Bits known to be one AND zero?); // Compute the new bits that are at the top now. - APInt HighBits(APInt::getAllOnesValue(ShiftAmt).zext(BitWidth).shl( + APInt HighBits(APInt::getAllOnesValue(ShiftAmt).zextOrCopy(BitWidth).shl( BitWidth - ShiftAmt)); RHSKnownZero = TypeMask; RHSKnownOne = TypeMask; @@ -2046,7 +2046,7 @@ assert((RHSKnownZero RHSKnownOne) == 0 Bits known to be one AND zero?); // Compute the new bits that are at the top now. - APInt HighBits(APInt::getAllOnesValue(ShiftAmt).zext(BitWidth).shl( + APInt HighBits(APInt::getAllOnesValue(ShiftAmt).zextOrCopy(BitWidth).shl( BitWidth - ShiftAmt)); RHSKnownZero = TypeMask; RHSKnownOne = TypeMask; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits