From sabre at nondot.org Mon Apr 2 00:09:11 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 00:09:11 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/PowerPC/branch-opt.ll Message-ID: <200704020509.l3259BKU011303@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/PowerPC: branch-opt.ll updated: 1.6 -> 1.7 --- Log message: my patch fixed the fixme. --- Diffs of the changes: (+1 -2) branch-opt.ll | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/test/CodeGen/PowerPC/branch-opt.ll diff -u llvm/test/CodeGen/PowerPC/branch-opt.ll:1.6 llvm/test/CodeGen/PowerPC/branch-opt.ll:1.7 --- llvm/test/CodeGen/PowerPC/branch-opt.ll:1.6 Fri Feb 16 18:44:34 2007 +++ llvm/test/CodeGen/PowerPC/branch-opt.ll Mon Apr 2 00:08:54 2007 @@ -1,6 +1,5 @@ ; RUN: llvm-upgrade < %s | llvm-as | llc -march=ppc32 && -; RUN: llvm-upgrade < %s | llvm-as | llc -march=ppc32 | grep 'b LBB.*' | wc -l | grep 5 -;;; FIXME, 4 unconditional branches is minimal +; RUN: llvm-upgrade < %s | llvm-as | llc -march=ppc32 | grep 'b LBB.*' | wc -l | grep 4 target endian = big target pointersize = 32 From sabre at nondot.org Mon Apr 2 00:35:25 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 00:35:25 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/InstCombine/xor.ll Message-ID: <200704020535.l325ZPJD012404@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/InstCombine: xor.ll updated: 1.20 -> 1.21 --- Log message: creative way to add one. --- Diffs of the changes: (+6 -0) xor.ll | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/test/Transforms/InstCombine/xor.ll diff -u llvm/test/Transforms/InstCombine/xor.ll:1.20 llvm/test/Transforms/InstCombine/xor.ll:1.21 --- llvm/test/Transforms/InstCombine/xor.ll:1.20 Fri Jan 26 02:25:06 2007 +++ llvm/test/Transforms/InstCombine/xor.ll Mon Apr 2 00:35:08 2007 @@ -190,3 +190,9 @@ ret int %tmp6 } +int %test28(int %indvar) { + %tmp7 = add int %indvar, -2147483647 + %tmp214 = xor int %tmp7, -2147483648 + ret int %tmp214 +} + From sabre at nondot.org Mon Apr 2 00:36:39 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 00:36:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200704020536.l325adWo012464@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.718 -> 1.719 --- Log message: simplify (x+c)^signbit as (x+c+signbit), pointed out by PR1288: http://llvm.org/PR1288 . This implements test/Transforms/InstCombine/xor.ll:test28 --- Diffs of the changes: (+7 -1) InstructionCombining.cpp | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.718 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.719 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.718 Sun Apr 1 15:57:36 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Apr 2 00:36:22 2007 @@ -4005,7 +4005,7 @@ return BinaryOperator::createOr(Op0NotVal, NotY); } } - + if (ConstantInt *Op0CI = dyn_cast(Op0I->getOperand(1))) if (Op0I->getOpcode() == Instruction::Add) { // ~(X-c) --> (-c-1)-X @@ -4015,6 +4015,12 @@ ConstantExpr::getSub(NegOp0CI, ConstantInt::get(I.getType(), 1)), Op0I->getOperand(0)); + } else if (RHS->getValue().isMinSignedValue()) { + // (X + C) ^ signbit -> (X + C + signbit) + Constant *C = ConstantInt::get(RHS->getValue() + Op0CI->getValue()); + return BinaryOperator::createAdd(Op0I->getOperand(0), C); + + } } else if (Op0I->getOpcode() == Instruction::Or) { // (X|C1)^C2 -> X^(C1|C2) iff X&~C1 == 0 From sabre at nondot.org Mon Apr 2 00:41:17 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 00:41:17 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/ADT/APInt.h Message-ID: <200704020541.l325fHZQ012626@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ADT: APInt.h updated: 1.60 -> 1.61 --- Log message: add a helper function. --- Diffs of the changes: (+3 -0) APInt.h | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/include/llvm/ADT/APInt.h diff -u llvm/include/llvm/ADT/APInt.h:1.60 llvm/include/llvm/ADT/APInt.h:1.61 --- llvm/include/llvm/ADT/APInt.h:1.60 Sun Apr 1 07:45:33 2007 +++ llvm/include/llvm/ADT/APInt.h Mon Apr 2 00:41:00 2007 @@ -272,6 +272,9 @@ /// @returns true if the argument APInt value is a power of two > 0. bool isPowerOf2() const; + /// isSignBit - Return true if this is the value returned by getSignBit. + bool isSignBit() const { return isMinSignedValue(); } + /// This converts the APInt to a boolean value as a test against zero. /// @brief Boolean conversion function. inline bool getBoolValue() const { From sabre at nondot.org Mon Apr 2 00:41:56 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 00:41:56 -0500 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200704020541.l325fuqC012671@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.105 -> 1.106 --- Log message: Treat xor of signbit like an add. --- Diffs of the changes: (+10 -1) ScalarEvolution.cpp | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.105 llvm/lib/Analysis/ScalarEvolution.cpp:1.106 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.105 Sat Mar 3 19:25:35 2007 +++ llvm/lib/Analysis/ScalarEvolution.cpp Mon Apr 2 00:41:38 2007 @@ -1427,7 +1427,16 @@ } } break; - + case Instruction::Xor: + // If the RHS of the xor is a signbit, then this is just an add. + // Instcombine turns add of signbit into xor as a strength reduction step. + if (ConstantInt *CI = dyn_cast(I->getOperand(1))) { + if (CI->getValue().isSignBit()) + return SCEVAddExpr::get(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); + } + break; + case Instruction::Shl: // Turn shift left of a constant amount into a multiply. if (ConstantInt *SA = dyn_cast(I->getOperand(1))) { From sabre at nondot.org Mon Apr 2 00:42:39 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 00:42:39 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200704020542.l325gdZG012726@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.719 -> 1.720 --- Log message: use more obvious function name. --- 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.719 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.720 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.719 Mon Apr 2 00:36:22 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Apr 2 00:42:22 2007 @@ -4015,7 +4015,7 @@ ConstantExpr::getSub(NegOp0CI, ConstantInt::get(I.getType(), 1)), Op0I->getOperand(0)); - } else if (RHS->getValue().isMinSignedValue()) { + } else if (RHS->getValue().isSignBit()) { // (X + C) ^ signbit -> (X + C + signbit) Constant *C = ConstantInt::get(RHS->getValue() + Op0CI->getValue()); return BinaryOperator::createAdd(Op0I->getOperand(0), C); From sabre at nondot.org Mon Apr 2 00:49:16 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 00:49:16 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200704020549.l325nG5k013022@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.720 -> 1.721 --- Log message: Wrap long line --- 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.720 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.721 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.720 Mon Apr 2 00:42:22 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Apr 2 00:48:58 2007 @@ -4019,8 +4019,7 @@ // (X + C) ^ signbit -> (X + C + signbit) Constant *C = ConstantInt::get(RHS->getValue() + Op0CI->getValue()); return BinaryOperator::createAdd(Op0I->getOperand(0), C); - - + } } else if (Op0I->getOpcode() == Instruction::Or) { // (X|C1)^C2 -> X^(C1|C2) iff X&~C1 == 0 @@ -6272,7 +6271,8 @@ case Instruction::ZExt: { // We need to emit an AND to clear the high bits. assert(SrcBitSize < DestBitSize && "Not a zext?"); - Constant *C = ConstantInt::get(APInt::getLowBitsSet(DestBitSize, SrcBitSize)); + Constant *C = ConstantInt::get(APInt::getLowBitsSet(DestBitSize, + SrcBitSize)); return BinaryOperator::createAnd(Res, C); } case Instruction::SExt: From sabre at nondot.org Mon Apr 2 00:58:17 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 00:58:17 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/PowerPC/compare-simm.ll Message-ID: <200704020558.l325wHZn013410@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/PowerPC: compare-simm.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+13 -0) compare-simm.ll | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/test/CodeGen/PowerPC/compare-simm.ll diff -c /dev/null llvm/test/CodeGen/PowerPC/compare-simm.ll:1.1 *** /dev/null Mon Apr 2 00:58:09 2007 --- llvm/test/CodeGen/PowerPC/compare-simm.ll Mon Apr 2 00:57:59 2007 *************** *** 0 **** --- 1,13 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 | grep 'cmpwi cr0, r3, -1' + + define i32 @test(i32 %x) { + %c = icmp eq i32 %x, -1 + br i1 %c, label %T, label %F + T: + %A = call i32 @test(i32 123) + %B = add i32 %A, 43 + ret i32 %B + F: + %G = add i32 %x, 1234 + ret i32 %G + } From sabre at nondot.org Mon Apr 2 01:00:00 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 01:00:00 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200704020600.l3260065013462@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.229 -> 1.230 --- Log message: Fix a bug which caused us to never be able to use signed comparisons for equality comparisons of a constant. This allows us to codegen the 'sintzero' loop in PR1288: http://llvm.org/PR1288 as: LBB1_1: ;cond_next li r4, 0 addi r2, r2, 1 stw r4, 0(r3) addi r3, r3, 4 cmpwi cr0, r2, -1 bne cr0, LBB1_1 ;cond_next instead of: LBB1_1: ;cond_next addi r2, r2, 1 li r4, 0 xoris r5, r2, 65535 stw r4, 0(r3) addi r3, r3, 4 cmplwi cr0, r5, 65535 bne cr0, LBB1_1 ;cond_next This implements CodeGen/PowerPC/compare-simm.ll, and also cuts 74 instructions out of kc++. --- Diffs of the changes: (+1 -1) PPCISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.229 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.230 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.229 Tue Dec 19 16:59:26 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Mon Apr 2 00:59:42 2007 @@ -508,7 +508,7 @@ return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, LHS, getI32Imm(Imm & 0xFFFF)), 0); // If this is a 16-bit signed immediate, fold it. - if (isInt16(Imm)) + if (isInt16((int)Imm)) return SDOperand(CurDAG->getTargetNode(PPC::CMPWI, MVT::i32, LHS, getI32Imm(Imm & 0xFFFF)), 0); From reid at x10sys.com Mon Apr 2 01:10:11 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 01:10:11 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704020610.l326ABZc013855@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.22 -> 1.23 --- Log message: Add Devang. --- Diffs of the changes: (+4 -3) DevMtgMay2007.html | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.22 llvm-www/DevMtgMay2007.html:1.23 --- llvm-www/DevMtgMay2007.html:1.22 Sun Apr 1 16:07:53 2007 +++ llvm-www/DevMtgMay2007.html Mon Apr 2 01:09:54 2007 @@ -212,13 +212,14 @@ Chris LattnerApple, Inc. Nick LewyckyIndependent Scott Michel + 2Aerospace + Devang PatelApple, Inc. Reid SpencerIndependent Sarah Thompson + 1NASA, Ames Research Center Bill WendlingApple, Inc. Marcel WeiherMetaObject -

Total confirmed attendees: 13

-

Possible additional attendees: 8

+

Total confirmed attendees: 14

+

Possible additional attendees: 7

@@ -228,6 +229,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
Last modified: $Date: 2007/04/01 21:07:53 $ +
Last modified: $Date: 2007/04/02 06:09:54 $ From sabre at nondot.org Mon Apr 2 01:33:28 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 01:33:28 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/ARM/lsr-scale-addr-mode.ll Message-ID: <200704020633.l326XSbP014774@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/ARM: lsr-scale-addr-mode.ll added (r1.1) --- Log message: new testcase. --- Diffs of the changes: (+19 -0) lsr-scale-addr-mode.ll | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+) Index: llvm/test/CodeGen/ARM/lsr-scale-addr-mode.ll diff -c /dev/null llvm/test/CodeGen/ARM/lsr-scale-addr-mode.ll:1.1 *** /dev/null Mon Apr 2 01:33:20 2007 --- llvm/test/CodeGen/ARM/lsr-scale-addr-mode.ll Mon Apr 2 01:33:10 2007 *************** *** 0 **** --- 1,19 ---- + ; RUN: llvm-as < %s | llc -march=arm | grep -F 'str r2, [r0, +r3, lsl #2]' + ; Should use scaled addressing mode. + + define void @sintzero(i32* %a) { + entry: + store i32 0, i32* %a + br label %cond_next + + cond_next: ; preds = %cond_next, %entry + %indvar = phi i32 [ 0, %entry ], [ %tmp25, %cond_next ] ; [#uses=1] + %tmp25 = add i32 %indvar, 1 ; [#uses=3] + %tmp36 = getelementptr i32* %a, i32 %tmp25 ; [#uses=1] + store i32 0, i32* %tmp36 + icmp eq i32 %tmp25, -1 ; :0 [#uses=1] + br i1 %0, label %return, label %cond_next + + return: ; preds = %cond_next + ret void + } From sabre at nondot.org Mon Apr 2 01:35:01 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 01:35:01 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200704020635.l326Z1JC014818@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.123 -> 1.124 --- Log message: Pass the type of the store access, not the type of the store, into the target hook. This allows us to codegen a loop as: LBB1_1: @cond_next mov r2, #0 str r2, [r0, +r3, lsl #2] add r3, r3, #1 cmn r3, #1 bne LBB1_1 @cond_next instead of: LBB1_1: @cond_next mov r2, #0 str r2, [r0], #+4 add r3, r3, #1 cmn r3, #1 bne LBB1_1 @cond_next This looks the same, but has one fewer induction variable (and therefore, one fewer register) live in the loop. --- Diffs of the changes: (+9 -2) LoopStrengthReduce.cpp | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.123 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.124 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.123 Sun Apr 1 17:21:39 2007 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Apr 2 01:34:44 2007 @@ -899,8 +899,15 @@ Imm = SC->getValue()->getSExtValue(); else Imm = 0; - if (!TLI->isLegalAddressScaleAndImm(Scale, Imm, - UsersToProcess[i].Inst->getType())) + + // If this is a load or other access, pass the type of the access in. + const Type *AccessTy = Type::VoidTy; + if (StoreInst *SI = dyn_cast(UsersToProcess[i].Inst)) + AccessTy = SI->getOperand(0)->getType(); + else if (LoadInst *LI = dyn_cast(UsersToProcess[i].Inst)) + AccessTy = LI->getType(); + + if (!TLI->isLegalAddressScaleAndImm(Scale, Imm, AccessTy)) return false; } return true; From zhousheng00 at gmail.com Mon Apr 2 03:20:58 2007 From: zhousheng00 at gmail.com (Zhou Sheng) Date: Mon, 2 Apr 2007 03:20:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200704020820.l328Kw6b028937@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.721 -> 1.722 --- Log message: Use uint32_t for bitwidth instead of unsigned. --- Diffs of the changes: (+29 -29) InstructionCombining.cpp | 58 +++++++++++++++++++++++------------------------ 1 files changed, 29 insertions(+), 29 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.721 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.722 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.721 Mon Apr 2 00:48:58 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Apr 2 03:20:41 2007 @@ -1279,7 +1279,7 @@ if (DemandedMask[BitWidth-1] == 0) { // Right fill the mask of bits for this SUB to demand the most // significant bit and all those below it. - unsigned NLZ = DemandedMask.countLeadingZeros(); + uint32_t NLZ = DemandedMask.countLeadingZeros(); APInt DemandedFromOps(APInt::getLowBitsSet(BitWidth, BitWidth-NLZ)); if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps, LHSKnownZero, LHSKnownOne, Depth+1)) @@ -1871,7 +1871,7 @@ if (ConstantInt *CI = dyn_cast(RHSC)) { // X + (signbit) --> X ^ signbit const APInt& Val = CI->getValue(); - unsigned BitWidth = Val.getBitWidth(); + uint32_t BitWidth = Val.getBitWidth(); if (Val == APInt::getSignBit(BitWidth)) return BinaryOperator::createXor(LHS, RHS); @@ -1893,10 +1893,10 @@ Value *XorLHS = 0; if (isa(RHSC) && match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { - unsigned TySizeBits = I.getType()->getPrimitiveSizeInBits(); + uint32_t TySizeBits = I.getType()->getPrimitiveSizeInBits(); const APInt& RHSVal = cast(RHSC)->getValue(); - unsigned Size = TySizeBits / 2; + uint32_t Size = TySizeBits / 2; APInt C0080Val(APInt(TySizeBits, 1ULL).shl(Size - 1)); APInt CFF80Val(-C0080Val); do { @@ -2049,7 +2049,7 @@ // isSignBit - Return true if the value represented by the constant only has the // highest order bit set. static bool isSignBit(ConstantInt *CI) { - unsigned NumBits = CI->getType()->getPrimitiveSizeInBits(); + uint32_t NumBits = CI->getType()->getPrimitiveSizeInBits(); return CI->getValue() == APInt::getSignBit(NumBits); } @@ -2321,8 +2321,8 @@ // If the multiply type is not the same as the source type, sign extend // or truncate to the multiply type. if (I.getType() != V->getType()) { - unsigned SrcBits = V->getType()->getPrimitiveSizeInBits(); - unsigned DstBits = I.getType()->getPrimitiveSizeInBits(); + uint32_t SrcBits = V->getType()->getPrimitiveSizeInBits(); + uint32_t DstBits = I.getType()->getPrimitiveSizeInBits(); Instruction::CastOps opcode = (SrcBits == DstBits ? Instruction::BitCast : (SrcBits < DstBits ? Instruction::SExt : Instruction::Trunc)); @@ -3081,7 +3081,7 @@ // any number of 0s on either side. The 1s are allowed to wrap from LSB to // MSB, so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs. 0x0F0F0000 is // not, since all 1s are not contiguous. -static bool isRunOfOnes(ConstantInt *Val, unsigned &MB, unsigned &ME) { +static bool isRunOfOnes(ConstantInt *Val, uint32_t &MB, uint32_t &ME) { const APInt& V = Val->getValue(); uint32_t BitWidth = Val->getType()->getBitWidth(); if (!APIntOps::isShiftedMask(BitWidth, V)) return false; @@ -3125,7 +3125,7 @@ // Otherwise, if Mask is 0+1+0+, and if B is known to have the low 0+ // part, we don't need any explicit masks to take them out of A. If that // is all N is, ignore it. - unsigned MB = 0, ME = 0; + uint32_t MB = 0, ME = 0; if (isRunOfOnes(Mask, MB, ME)) { // begin/end bit of run, inclusive uint32_t BitWidth = cast(RHS->getType())->getBitWidth(); APInt Mask(APInt::getLowBitsSet(BitWidth, MB-1)); @@ -4844,7 +4844,7 @@ case Instruction::Shl: // (icmp pred (shl X, ShAmt), CI) if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { if (I.isEquality()) { - unsigned TypeBits = CI->getType()->getPrimitiveSizeInBits(); + uint32_t TypeBits = CI->getType()->getPrimitiveSizeInBits(); // Check that the shift amount is in range. If not, don't perform // undefined shifts. When the shift is visited it will be @@ -4865,8 +4865,8 @@ if (LHSI->hasOneUse()) { // Otherwise strength reduce the shift into an and. uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); - uint64_t Val = (1ULL << (TypeBits-ShAmtVal))-1; - Constant *Mask = ConstantInt::get(CI->getType(), Val); + Constant *Mask = ConstantInt::get( + APInt::getLowBitsSet(TypeBits, TypeBits-ShAmtVal)); Instruction *AndI = BinaryOperator::createAnd(LHSI->getOperand(0), @@ -4886,7 +4886,7 @@ // Check that the shift amount is in range. If not, don't perform // undefined shifts. When the shift is visited it will be // simplified. - unsigned TypeBits = CI->getType()->getPrimitiveSizeInBits(); + uint32_t TypeBits = CI->getType()->getPrimitiveSizeInBits(); if (ShAmt->uge(TypeBits)) break; @@ -5180,7 +5180,7 @@ if (CastInst *Cast = dyn_cast(Op0)) { Value *CastOp = Cast->getOperand(0); const Type *SrcTy = CastOp->getType(); - unsigned SrcTySize = SrcTy->getPrimitiveSizeInBits(); + uint32_t SrcTySize = SrcTy->getPrimitiveSizeInBits(); if (SrcTy->isInteger() && SrcTySize == Cast->getType()->getPrimitiveSizeInBits()) { // If this is an unsigned comparison, try to make the comparison use @@ -5747,7 +5747,7 @@ if (ShiftAmt1 == 0) return 0; // Will be simplified in the future. Value *X = ShiftOp->getOperand(0); - unsigned AmtSum = ShiftAmt1+ShiftAmt2; // Fold into one big shift. + uint32_t AmtSum = ShiftAmt1+ShiftAmt2; // Fold into one big shift. if (AmtSum > TypeBits) AmtSum = TypeBits; @@ -5808,7 +5808,7 @@ } // Otherwise, we can't handle it yet. } else if (ShiftAmt1 < ShiftAmt2) { - unsigned ShiftDiff = ShiftAmt2-ShiftAmt1; + uint32_t ShiftDiff = ShiftAmt2-ShiftAmt1; // (X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) if (I.getOpcode() == Instruction::Shl) { @@ -5836,7 +5836,7 @@ // We can't handle (X << C1) >>s C2, it shifts arbitrary bits in. } else { assert(ShiftAmt2 < ShiftAmt1); - unsigned ShiftDiff = ShiftAmt1-ShiftAmt2; + uint32_t ShiftDiff = ShiftAmt1-ShiftAmt2; // (X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) if (I.getOpcode() == Instruction::Shl) { @@ -6209,8 +6209,8 @@ Value *Src = CI.getOperand(0); const Type *SrcTy = Src->getType(); const Type *DestTy = CI.getType(); - unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); - unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); + uint32_t SrcBitSize = SrcTy->getPrimitiveSizeInBits(); + uint32_t DestBitSize = DestTy->getPrimitiveSizeInBits(); // See if we can simplify any instructions used by the LHS whose sole // purpose is to compute bits we don't care about. @@ -6406,7 +6406,7 @@ return ReplaceInstUsesWith(CI, Res); } - unsigned ShiftAmt = KnownZeroMask.logBase2(); + uint32_t ShiftAmt = KnownZeroMask.logBase2(); Value *In = Op0; if (ShiftAmt) { // Perform a logical shr by shiftamt. @@ -6441,8 +6441,8 @@ Value *Src = CI.getOperand(0); const Type *Ty = CI.getType(); - unsigned DestBitWidth = Ty->getPrimitiveSizeInBits(); - unsigned SrcBitWidth = cast(Src->getType())->getBitWidth(); + uint32_t DestBitWidth = Ty->getPrimitiveSizeInBits(); + uint32_t SrcBitWidth = cast(Src->getType())->getBitWidth(); if (Instruction *SrcI = dyn_cast(Src)) { switch (SrcI->getOpcode()) { @@ -6507,9 +6507,9 @@ if (isa(CSrc)) { // Get the sizes of the types involved Value *A = CSrc->getOperand(0); - unsigned SrcSize = A->getType()->getPrimitiveSizeInBits(); - unsigned MidSize = CSrc->getType()->getPrimitiveSizeInBits(); - unsigned DstSize = CI.getType()->getPrimitiveSizeInBits(); + uint32_t SrcSize = A->getType()->getPrimitiveSizeInBits(); + uint32_t MidSize = CSrc->getType()->getPrimitiveSizeInBits(); + uint32_t DstSize = CI.getType()->getPrimitiveSizeInBits(); // If we're actually extending zero bits and the trunc is a no-op if (MidSize < DstSize && SrcSize == DstSize) { // Replace both of the casts with an And of the type mask. @@ -6838,7 +6838,7 @@ CanXForm = CmpCst->isZero() && IC->getPredicate() == ICmpInst::ICMP_SLT; else { - unsigned Bits = CmpCst->getType()->getPrimitiveSizeInBits(); + uint32_t Bits = CmpCst->getType()->getPrimitiveSizeInBits(); CanXForm = CmpCst->getValue() == APInt::getSignedMaxValue(Bits) && IC->getPredicate() == ICmpInst::ICMP_UGT; } @@ -6847,7 +6847,7 @@ // The comparison constant and the result are not neccessarily the // same width. Make an all-ones value by inserting a AShr. Value *X = IC->getOperand(0); - unsigned Bits = X->getType()->getPrimitiveSizeInBits(); + uint32_t Bits = X->getType()->getPrimitiveSizeInBits(); Constant *ShAmt = ConstantInt::get(X->getType(), Bits-1); Instruction *SRA = BinaryOperator::create(Instruction::AShr, X, ShAmt, "ones"); @@ -6856,8 +6856,8 @@ // Finally, convert to the type of the select RHS. We figure out // if this requires a SExt, Trunc or BitCast based on the sizes. Instruction::CastOps opc = Instruction::BitCast; - unsigned SRASize = SRA->getType()->getPrimitiveSizeInBits(); - unsigned SISize = SI.getType()->getPrimitiveSizeInBits(); + uint32_t SRASize = SRA->getType()->getPrimitiveSizeInBits(); + uint32_t SISize = SI.getType()->getPrimitiveSizeInBits(); if (SRASize < SISize) opc = Instruction::SExt; else if (SRASize > SISize) From zhousheng00 at gmail.com Mon Apr 2 08:45:48 2007 From: zhousheng00 at gmail.com (Zhou Sheng) Date: Mon, 2 Apr 2007 08:45:48 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200704021345.l32Djmxb009604@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.722 -> 1.723 --- Log message: 1. Make use of APInt operation instead of using ConstantExpr::getXXX. 2. Use cheaper APInt methods. --- Diffs of the changes: (+19 -26) InstructionCombining.cpp | 45 +++++++++++++++++++-------------------------- 1 files changed, 19 insertions(+), 26 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.722 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.723 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.722 Mon Apr 2 03:20:41 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Apr 2 08:45:30 2007 @@ -522,7 +522,7 @@ // Constants can be considered to be not'ed values... if (ConstantInt *C = dyn_cast(V)) - return ConstantExpr::getNot(C); + return ConstantInt::get(~C->getValue()); return 0; } @@ -844,16 +844,14 @@ "Ty, KnownZero, KnownOne and Min, Max must have equal bitwidth."); APInt UnknownBits = ~(KnownZero|KnownOne); - APInt SignBit(APInt::getSignBit(BitWidth)); - // The minimum value is when all unknown bits are zeros, EXCEPT for the sign // bit if it is unknown. Min = KnownOne; Max = KnownOne|UnknownBits; if (UnknownBits[BitWidth-1]) { // Sign bit is unknown - Min |= SignBit; - Max &= ~SignBit; + Min.set(BitWidth-1); + Max.clear(BitWidth-1); } } @@ -1133,7 +1131,6 @@ const IntegerType *SrcTy = cast(I->getOperand(0)->getType()); uint32_t SrcBitWidth = SrcTy->getBitWidth(); - DemandedMask &= SrcTy->getMask().zext(BitWidth); DemandedMask.trunc(SrcBitWidth); RHSKnownZero.trunc(SrcBitWidth); RHSKnownOne.trunc(SrcBitWidth); @@ -1154,9 +1151,6 @@ const IntegerType *SrcTy = cast(I->getOperand(0)->getType()); uint32_t SrcBitWidth = SrcTy->getBitWidth(); - // Get the sign bit for the source type - APInt InSignBit(APInt::getSignBit(SrcBitWidth)); - InSignBit.zext(BitWidth); APInt InputDemandedBits = DemandedMask & APInt::getLowBitsSet(BitWidth, SrcBitWidth); @@ -1164,7 +1158,7 @@ // If any of the sign extended bits are demanded, we know that the sign // bit is demanded. if ((NewBits & DemandedMask) != 0) - InputDemandedBits |= InSignBit; + InputDemandedBits.set(SrcBitWidth-1); InputDemandedBits.trunc(SrcBitWidth); RHSKnownZero.trunc(SrcBitWidth); @@ -3652,7 +3646,8 @@ Instruction *Or = BinaryOperator::createOr(X, RHS); InsertNewInstBefore(Or, I); Or->takeName(Op0); - return BinaryOperator::createAnd(Or, ConstantExpr::getOr(RHS, C1)); + return BinaryOperator::createAnd(Or, + ConstantInt::get(RHS->getValue() | C1->getValue())); } // (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2) @@ -3661,7 +3656,7 @@ InsertNewInstBefore(Or, I); Or->takeName(Op0); return BinaryOperator::createXor(Or, - ConstantExpr::getAnd(C1, ConstantExpr::getNot(RHS))); + ConstantInt::get(C1->getValue() & ~RHS->getValue())); } // Try to fold constant and into select arguments. @@ -3716,13 +3711,14 @@ match(Op1, m_And(m_Value(B), m_ConstantInt(C2)))) { if (A == B) // (A & C1)|(A & C2) == A & (C1|C2) - return BinaryOperator::createAnd(A, ConstantExpr::getOr(C1, C2)); + return BinaryOperator::createAnd(A, + ConstantInt::get(C1->getValue() | C2->getValue())); // If we have: ((V + N) & C1) | (V & C2) // .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0 // replace with V+N. - if (C1 == ConstantExpr::getNot(C2)) { + if (C1->getValue() == ~C2->getValue()) { Value *V1 = 0, *V2 = 0; if ((C2->getValue() & (C2->getValue()+1)) == 0 && // C2 == 0+1+ match(A, m_Add(m_Value(V1), m_Value(V2)))) { @@ -3826,7 +3822,7 @@ Instruction *Add = BinaryOperator::createAdd(LHSVal, AddCST, LHSVal->getName()+".off"); InsertNewInstBefore(Add, I); - AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst); + AddCST = Subtract(AddOne(RHSCst), LHSCst); return new ICmpInst(ICmpInst::ICMP_ULT, Add, AddCST); } break; // (X == 13 | X == 15) -> no change @@ -4027,7 +4023,7 @@ Constant *NewRHS = ConstantExpr::getOr(Op0CI, RHS); // Anything in both C1 and C2 is known to be zero, remove it from // NewRHS. - Constant *CommonBits = ConstantExpr::getAnd(Op0CI, RHS); + Constant *CommonBits = And(Op0CI, RHS); NewRHS = ConstantExpr::getAnd(NewRHS, ConstantExpr::getNot(CommonBits)); AddToWorkList(Op0I); @@ -4196,7 +4192,7 @@ /// overflowed for this type. static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1, ConstantInt *In2, bool IsSigned = false) { - Result = cast(ConstantExpr::getAdd(In1, In2)); + Result = cast(Add(In1, In2)); if (IsSigned) if (In2->getValue().isNegative()) @@ -4956,8 +4952,7 @@ // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and // C2 (CI). By solving for X we can turn this into a range check // instead of computing a divide. - ConstantInt *Prod = - cast(ConstantExpr::getMul(CI, DivRHS)); + ConstantInt *Prod = Multiply(CI, DivRHS); // Determine if the product overflows by seeing if the product is // not equal to the divide. Make sure we do the same kind of divide @@ -5005,7 +5000,7 @@ } else { // (X / neg) op neg LoBound = Prod; LoOverflow = HiOverflow = ProdOV; - HiBound = cast(ConstantExpr::getSub(Prod, DivRHS)); + HiBound = Subtract(Prod, DivRHS); } // Dividing by a negate swaps the condition. @@ -5085,7 +5080,7 @@ if (ConstantInt *BOp1C = dyn_cast(BO->getOperand(1))) { if (BO->hasOneUse()) return new ICmpInst(I.getPredicate(), BO->getOperand(0), - ConstantExpr::getSub(CI, BOp1C)); + Subtract(CI, BOp1C)); } else if (CI->isNullValue()) { // Replace ((add A, B) != 0) with (A != -B) if A or B is // efficiently invertible, or if the add has just this one use. @@ -5133,8 +5128,7 @@ if (ConstantInt *BOC = dyn_cast(BO->getOperand(1))) { // If bits are being compared against that are and'd out, then the // comparison can never succeed! - if (!ConstantExpr::getAnd(CI, - ConstantExpr::getNot(BOC))->isNullValue()) + if (!And(CI, ConstantInt::get(~BOC->getValue()))->isZero()) return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, isICMP_NE)); @@ -5323,7 +5317,7 @@ if (ConstantInt *C1 = dyn_cast(B)) if (ConstantInt *C2 = dyn_cast(D)) if (Op1->hasOneUse()) { - Constant *NC = ConstantExpr::getXor(C1, C2); + Constant *NC = ConstantInt::get(C1->getValue() ^ C2->getValue()); Instruction *Xor = BinaryOperator::createXor(C, NC, "tmp"); return new ICmpInst(I.getPredicate(), A, InsertNewInstBefore(Xor, I)); @@ -5975,8 +5969,7 @@ // If the allocation size is constant, form a constant mul expression Amt = ConstantInt::get(Type::Int32Ty, Scale); if (isa(NumElements)) - Amt = ConstantExpr::getMul( - cast(NumElements), cast(Amt)); + Amt = Multiply(cast(NumElements), cast(Amt)); // otherwise multiply the amount and the number of elements else if (Scale != 1) { Instruction *Tmp = BinaryOperator::createMul(Amt, NumElements, "tmp"); From reid at x10sys.com Mon Apr 2 09:28:51 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 09:28:51 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704021428.l32ESp2a011928@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.23 -> 1.24 --- Log message: Add Mark Schimmel. --- Diffs of the changes: (+4 -3) DevMtgMay2007.html | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.23 llvm-www/DevMtgMay2007.html:1.24 --- llvm-www/DevMtgMay2007.html:1.23 Mon Apr 2 01:09:54 2007 +++ llvm-www/DevMtgMay2007.html Mon Apr 2 09:28:34 2007 @@ -213,13 +213,14 @@ Nick LewyckyIndependent Scott Michel + 2Aerospace Devang PatelApple, Inc. + Mark SchimmelWind River Reid SpencerIndependent Sarah Thompson + 1NASA, Ames Research Center Bill WendlingApple, Inc. Marcel WeiherMetaObject -

Total confirmed attendees: 14

-

Possible additional attendees: 7

+

Total confirmed attendees: 15

+

Possible additional attendees: 6

@@ -229,6 +230,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
Last modified: $Date: 2007/04/02 06:09:54 $ +
Last modified: $Date: 2007/04/02 14:28:34 $ From reid at x10sys.com Mon Apr 2 10:40:56 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 10:40:56 -0500 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200704021540.l32FeuW7014674@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.267 -> 1.268 --- Log message: Check for .svn directories too to determine if a debug build is appropriate. --- Diffs of the changes: (+3 -3) configure.ac | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.267 llvm/autoconf/configure.ac:1.268 --- llvm/autoconf/configure.ac:1.267 Thu Mar 29 10:37:57 2007 +++ llvm/autoconf/configure.ac Mon Apr 2 10:40:39 2007 @@ -235,13 +235,13 @@ AC_SUBST(LLVM_CROSS_COMPILING, [0]) fi -dnl Check to see if there's a "CVS" directory indicating that this build is -dnl being done from a CVS checkout. This sets up several defaults for the +dnl Check to see if there's a "CVS" (or .svn) directory indicating that this +dnl build is being done from a checkout. This sets up several defaults for the dnl command line switches. When we build with a CVS directory, we get a dnl debug with assertions turned on. Without, we assume a source release and we dnl get an optimized build without assertions. See --enable-optimized and dnl --enable-assertions below -if test -d "CVS" -o -d "${srcdir}/CVS"; then +if test -d "CVS" -o -d "${srcdir}/CVS" -o -d ".svn" -o -d "${srcdir}/.svn"; then cvsbuild="yes" optimize="no" AC_SUBST(CVSBUILD,[[CVSBUILD=1]]) From reid at x10sys.com Mon Apr 2 10:41:56 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 10:41:56 -0500 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200704021541.l32FfurC014725@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.272 -> 1.273 --- Log message: Regenerate. --- Diffs of the changes: (+1 -1) configure | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/configure diff -u llvm/configure:1.272 llvm/configure:1.273 --- llvm/configure:1.272 Thu Mar 29 10:38:33 2007 +++ llvm/configure Mon Apr 2 10:41:39 2007 @@ -4535,7 +4535,7 @@ fi -if test -d "CVS" -o -d "${srcdir}/CVS"; then +if test -d "CVS" -o -d "${srcdir}/CVS" -o -d ".svn" -o -d "${srcdir}/.svn"; then cvsbuild="yes" optimize="no" CVSBUILD=CVSBUILD=1 From reid at x10sys.com Mon Apr 2 10:49:55 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 10:49:55 -0500 Subject: [llvm-commits] CVS: llvm-www/developers.txt Message-ID: <200704021549.l32FntRJ015200@zion.cs.uiuc.edu> Changes in directory llvm-www: developers.txt updated: 1.11 -> 1.12 --- Log message: Add Zhou Sheng to the developer's list. --- Diffs of the changes: (+1 -0) developers.txt | 1 + 1 files changed, 1 insertion(+) Index: llvm-www/developers.txt diff -u llvm-www/developers.txt:1.11 llvm-www/developers.txt:1.12 --- llvm-www/developers.txt:1.11 Sat Mar 17 12:14:55 2007 +++ llvm-www/developers.txt Mon Apr 2 10:49:38 2007 @@ -19,3 +19,4 @@ Devang Patel href=mailto:dpatel at apple.com img=PhotoDevang.jpg width=145 height=172 alt=Devang Reid Spencer href=http://illuvium.net/rspencer/ img=PhotoReid.jpg width=145 height=172 alt=Reid Bill Wendling href=http://www.isanbard.org/~wendling/ img=PhotoBill.jpg width=173 height=240 alt=Bill +Sheng Zhou href=mailto:zhousheng at gmail.com img=PhotoSheng.jpg width=200 height=231 alt=Sheng From reid at x10sys.com Mon Apr 2 10:57:52 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 10:57:52 -0500 Subject: [llvm-commits] CVS: llvm-www/img/PhotoSheng.jpg Message-ID: <200704021557.l32Fvq5f015613@zion.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoSheng.jpg added (r1.1) --- Log message: Add Sheng's picture. --- Diffs of the changes: (+0 -0) PhotoSheng.jpg | 0 1 files changed Index: llvm-www/img/PhotoSheng.jpg From dpatel at apple.com Mon Apr 2 11:54:29 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 2 Apr 2007 11:54:29 -0500 Subject: [llvm-commits] CVS: llvm/docs/LinkTimeOptimization.html Message-ID: <200704021654.l32GsTHK017827@zion.cs.uiuc.edu> Changes in directory llvm/docs: LinkTimeOptimization.html updated: 1.10 -> 1.11 --- Log message: Update example notes to clarify system linker's role. --- Diffs of the changes: (+4 -2) LinkTimeOptimization.html | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/docs/LinkTimeOptimization.html diff -u llvm/docs/LinkTimeOptimization.html:1.10 llvm/docs/LinkTimeOptimization.html:1.11 --- llvm/docs/LinkTimeOptimization.html:1.10 Fri Oct 27 18:06:27 2006 +++ llvm/docs/LinkTimeOptimization.html Mon Apr 2 11:54:12 2007 @@ -83,7 +83,9 @@

The following example illustrates the advantages of LTO's integrated - approach and clean interface.

+ approach and clean interface. This example requires optimization support, + using interface described in this document, from system linker. Here, + llvm-gcc4 transparantly invokes system linker.

  • Input source file a.c is compiled into LLVM byte code form.
  • Input source file main.c is compiled into native object code. @@ -383,7 +385,7 @@ Devang Patel
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2006/10/27 23:06:27 $ + Last modified: $Date: 2007/04/02 16:54:12 $ From asl at math.spbu.ru Mon Apr 2 11:55:02 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 2 Apr 2007 11:55:02 -0500 Subject: [llvm-commits] CVS: llvm-www/img/PhotoAnton.jpg Message-ID: <200704021655.l32Gt2PN017956@zion.cs.uiuc.edu> Changes in directory llvm-www/img: PhotoAnton.jpg added (r1.1) --- Log message: Add myself to the developer's list --- Diffs of the changes: (+0 -0) PhotoAnton.jpg | 0 1 files changed Index: llvm-www/img/PhotoAnton.jpg From asl at math.spbu.ru Mon Apr 2 11:55:04 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 2 Apr 2007 11:55:04 -0500 Subject: [llvm-commits] CVS: llvm-www/developers.txt Message-ID: <200704021655.l32Gt4Ym017961@zion.cs.uiuc.edu> Changes in directory llvm-www: developers.txt updated: 1.12 -> 1.13 --- Log message: Add myself to the developer's list --- Diffs of the changes: (+1 -0) developers.txt | 1 + 1 files changed, 1 insertion(+) Index: llvm-www/developers.txt diff -u llvm-www/developers.txt:1.12 llvm-www/developers.txt:1.13 --- llvm-www/developers.txt:1.12 Mon Apr 2 10:49:38 2007 +++ llvm-www/developers.txt Mon Apr 2 11:54:45 2007 @@ -11,6 +11,7 @@ Brian Gaeke href=http://netfiles.uiuc.edu/gaeke/www/ img=PhotoBrian.png width=155 height=163 alt=brg Patrick Jenkins href=http://www.patjenk.com img=PhotoPatJenk.jpg width=200 width=173 height=130 alt=PatJenk Brad Jones href=http://www.nondot.org/~kungfoomaster/ img=PhotoBrad.jpg width=200 height=171 alt=KungFooMaster +Anton Korobeynikov href=mailto:asl_at_math_dot_spbu_dot_ru img=PhotoAnton.jpg width=239 height=207 alt=Anton Jim Laskey href=mailto:jlaskey at mac.com img=PhotoJim.jpg width=128 height=128 alt=Wickund Chris Lattner href=http://nondot.org/sabre/LLVMNotes/ img=PhotoChris.jpg width=150 height=152 alt=Sabre Tanya Lattner href=http://nondot.org/tonic/ img=PhotoTanya.jpg width=200 height=217 alt=tonic From reid at x10sys.com Mon Apr 2 11:58:09 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 11:58:09 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704021658.l32Gw9lQ018261@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.24 -> 1.25 --- Log message: Add Devang's talk on the PassManager. --- Diffs of the changes: (+3 -1) DevMtgMay2007.html | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.24 llvm-www/DevMtgMay2007.html:1.25 --- llvm-www/DevMtgMay2007.html:1.24 Mon Apr 2 09:28:34 2007 +++ llvm-www/DevMtgMay2007.html Mon Apr 2 11:57:52 2007 @@ -104,6 +104,8 @@ Nick Lewycky Design and implementation of the PredicateSimplifier pass, or, "VRP in LLVM" + Devang Patel + Demystifying the LLVM Pass Manager
@@ -230,6 +232,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
Last modified: $Date: 2007/04/02 14:28:34 $ +
Last modified: $Date: 2007/04/02 16:57:52 $ From reid at x10sys.com Mon Apr 2 12:18:41 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 12:18:41 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704021718.l32HIfNs019047@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.25 -> 1.26 --- Log message: Add Robert Hundt. --- Diffs of the changes: (+3 -2) DevMtgMay2007.html | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.25 llvm-www/DevMtgMay2007.html:1.26 --- llvm-www/DevMtgMay2007.html:1.25 Mon Apr 2 11:57:52 2007 +++ llvm-www/DevMtgMay2007.html Mon Apr 2 12:18:24 2007 @@ -211,6 +211,7 @@ Owen AndersonIndependent Ryan BrownGoogle Jeff CohenIndependent + Robert HundtGoogle Chris LattnerApple, Inc. Nick LewyckyIndependent Scott Michel + 2Aerospace @@ -221,7 +222,7 @@ Bill WendlingApple, Inc. Marcel WeiherMetaObject -

Total confirmed attendees: 15

+

Total confirmed attendees: 16

Possible additional attendees: 6

@@ -232,6 +233,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
Last modified: $Date: 2007/04/02 16:57:52 $ +
Last modified: $Date: 2007/04/02 17:18:24 $ From sabre at nondot.org Mon Apr 2 12:24:25 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 12:24:25 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <200704021724.l32HOPGi019286@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMISelLowering.cpp updated: 1.35 -> 1.36 --- Log message: add support for the 'w' inline asm register class. --- Diffs of the changes: (+28 -6) ARMISelLowering.cpp | 34 ++++++++++++++++++++++++++++------ 1 files changed, 28 insertions(+), 6 deletions(-) Index: llvm/lib/Target/ARM/ARMISelLowering.cpp diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.35 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.36 --- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.35 Sun Apr 1 20:30:03 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp Mon Apr 2 12:24:08 2007 @@ -1598,6 +1598,7 @@ switch (Constraint[0]) { default: break; case 'l': return C_RegisterClass; + case 'w': return C_RegisterClass; } } return TargetLowering::getConstraintType(Constraint); @@ -1609,12 +1610,17 @@ if (Constraint.size() == 1) { // GCC RS6000 Constraint Letters switch (Constraint[0]) { - case 'l': - // FIXME: in thumb mode, 'l' is only low-regs. - // FALL THROUGH. - case 'r': - return std::make_pair(0U, ARM::GPRRegisterClass); - break; + case 'l': + // FIXME: in thumb mode, 'l' is only low-regs. + // FALL THROUGH. + case 'r': + return std::make_pair(0U, ARM::GPRRegisterClass); + case 'w': + if (VT == MVT::f32) + return std::make_pair(0U, ARM::SPRRegisterClass); + if (VT == MVT::f32) + return std::make_pair(0U, ARM::DPRRegisterClass); + break; } } return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); @@ -1634,6 +1640,22 @@ ARM::R4, ARM::R5, ARM::R6, ARM::R7, ARM::R8, ARM::R9, ARM::R10, ARM::R11, ARM::R12, ARM::LR, 0); + case 'w': + if (VT == MVT::f32) + return make_vector(ARM::S0, ARM::S1, ARM::S2, ARM::S3, + ARM::S4, ARM::S5, ARM::S6, ARM::S7, + ARM::S8, ARM::S9, ARM::S10, ARM::S11, + ARM::S12,ARM::S13,ARM::S14,ARM::S15, + ARM::S16,ARM::S17,ARM::S18,ARM::S19, + ARM::S20,ARM::S21,ARM::S22,ARM::S23, + ARM::S24,ARM::S25,ARM::S26,ARM::S27, + ARM::S28,ARM::S29,ARM::S30,ARM::S31, 0); + if (VT == MVT::f64) + return make_vector(ARM::D0, ARM::D1, ARM::D2, ARM::D3, + ARM::D4, ARM::D5, ARM::D6, ARM::D7, + ARM::D8, ARM::D9, ARM::D10,ARM::D11, + ARM::D12,ARM::D13,ARM::D14,ARM::D15, 0); + break; } return std::vector(); From reid at x10sys.com Mon Apr 2 12:48:09 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 12:48:09 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704021748.l32Hm9EZ020193@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.26 -> 1.27 --- Log message: Get the attendee count correct. Add Reid's talk on HLVM. --- Diffs of the changes: (+4 -3) DevMtgMay2007.html | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.26 llvm-www/DevMtgMay2007.html:1.27 --- llvm-www/DevMtgMay2007.html:1.26 Mon Apr 2 12:18:24 2007 +++ llvm-www/DevMtgMay2007.html Mon Apr 2 12:47:52 2007 @@ -107,6 +107,7 @@ Devang Patel Demystifying the LLVM Pass Manager + Reid SpencerThe Goal of HLVM @@ -216,13 +217,13 @@ Nick LewyckyIndependent Scott Michel + 2Aerospace Devang PatelApple, Inc. - Mark SchimmelWind River + Mark Schimmel + 1Wind River Reid SpencerIndependent Sarah Thompson + 1NASA, Ames Research Center Bill WendlingApple, Inc. Marcel WeiherMetaObject -

Total confirmed attendees: 16

+

Total confirmed attendees: 18

Possible additional attendees: 6

@@ -233,6 +234,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
Last modified: $Date: 2007/04/02 17:18:24 $ +
Last modified: $Date: 2007/04/02 17:47:52 $ From reid at x10sys.com Mon Apr 2 13:04:36 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 13:04:36 -0500 Subject: [llvm-commits] CVS: llvm-www/SVNMigration.html Message-ID: <200704021804.l32I4aAb020679@zion.cs.uiuc.edu> Changes in directory llvm-www: SVNMigration.html added (r1.1) --- Log message: Add a page for tracking information about the CVS -> SVN migration. --- Diffs of the changes: (+122 -0) SVNMigration.html | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 122 insertions(+) Index: llvm-www/SVNMigration.html diff -c /dev/null llvm-www/SVNMigration.html:1.1 *** /dev/null Mon Apr 2 13:04:29 2007 --- llvm-www/SVNMigration.html Mon Apr 2 13:04:19 2007 *************** *** 0 **** --- 1,122 ---- + + +
Subversion Migration Notes
+
+

This document contains notes about the planned migration of the CVS code + repository to Subversion.

+
+ + + +
+

The existing branches have been categorized as shown in the table below. If + a branch is scheduled to be removed and you need it, please let + Reid know as soon as + possible.

+

Branches To Be Kept

+ + + + + + +
NameDescription
release_*Release branches (10 total)
seeBranch Vikram's group is using for Secure + Code?
parallelBranch for parallel features? (not sure)
vector_llvmBranch for vector stuff? (not sure)
+ +

Branches To Be Removed

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
autoconfappears to be an early version, even before the autoconf + directory existed
bug_122a bug fix branch that I created long ago. Its not needed any more. +
jrsdevhas exactly 2 header files in it, one for reoptimizer, the other for + SparcV9
llvmappears to be a *very* early version (docs has only LangRef.html, + and only 3 tools)
regalloc_linearscanhas only 3 old header files in it
PowerPC_0Appears to be an early version of the PowerPC target. Seems not + important to keep it
pre-11, prerelease_*John created these as the first step towards a release, but it + hasn't been done that way since (there's no prerelease_12 or later). + I think its not important to retain these.
SignlessTypesReid created this and doesn't need/want it
unlabelled-*these three appear to be mistakes (only a few files each)
+
+ + + +
+

Below are some tables of tag names to be kept or removed when the migration + occurs.

+

Tags To Be Kept

+ + + + + + + + + + + + + +
NameDescription
jtcAssuming this is John Criswell's tag and he wants + it
jtcllvaAssuming this is the LLVA tag
PARALLEL_ROOTRoot of the parallel branch
RELEASE_*These are the final release tags (7 total)
ROOT_RELEASE_*These are the original release tags (9 total) +
RC15This should have been ROOT_RELEASE_15, I think
startThis seems to be the very first tag. It references an + ancient version of llvm and is only of historical interest
+

Tags To Be Removed

+ + + + + + + + + + + + + + + + +
NameDescription
byebyeContains just the old lib/Analysis/DataStructure + stuff. It is inappropriately named and definitely not needed
LLVM_PRE111This is a pre-release tag to go with a branch + we're planning to remove.
new_merge_vectorAppears to be a merging tag. Pretty sure + its unneeded at this point
PowerPC_0_0Root of a branch we're deleting
PRE10Root of a branch we're deleting
PRE101Root of a branch we're deleting
PRE11Root of a branch we're deleting
PRE11_ROOTRoot of a branch we're deleting
PRE2_ROOTRoot of a branch we're deleting
regalloc_linearscan_mergein_mainMerge point of branch + we're deleting
ROOT_VLLVMAppears to be a typo
ST_incr_*SignlessTypes tags, not needed any more
+ +
+ +
+
+ Valid CSS! + Valid HTML 4.01! +
Last modified: $Date: 2007/04/02 18:04:19 $ +
+ From reid at x10sys.com Mon Apr 2 13:16:51 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 13:16:51 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704021816.l32IGpn8020964@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.27 -> 1.28 --- Log message: Add Devang's discussion topic and break discussion topics into their own group. --- Diffs of the changes: (+18 -6) DevMtgMay2007.html | 24 ++++++++++++++++++------ 1 files changed, 18 insertions(+), 6 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.27 llvm-www/DevMtgMay2007.html:1.28 --- llvm-www/DevMtgMay2007.html:1.27 Mon Apr 2 12:47:52 2007 +++ llvm-www/DevMtgMay2007.html Mon Apr 2 13:16:34 2007 @@ -9,6 +9,7 @@
  • Session 2: Learning LLVM
  • Session 3: Using LLVM
  • Session 4: Improving LLVM
  • +
  • Discussion Topics Submitted
  • Travel Tips
      @@ -136,14 +137,23 @@ wishful fantasies. What do you think LLVM lacks? Where does it need to go from here? This session will consist of a 5 minute presentation by the issue originator followed by 10 minutes of discussion. This will allow 6 issues to - be discussed in this time slot. + be discussed in this time slot.

      - + + future as an LLVM subproject, and plans for making LLVM more accessible + to scripting and higher level language front ends. +
      Suggested ByIssue or Discussion Topic
      Suggested ByIssue Description
      Owen AndersonIntegration of HLVM into LLVM - its - future as an LLVM subproject, and plans for making LLVM more accessible - to scripting and higher level language front ends.
      + + + +
      +

      In addition to the planned sessions above, the following discussion topics + have been submitted.

      + + +
      Suggested ByIssue or Discussion Topic
      Owen AndersonFuture development practices: with a - burgeoning number of clients and wider adoption, do we want more orgnized + burgeoning number of clients and wider adoption, do we want more organized development practices? i.e. release focuses or something?
      Owen AndersonAdoption Goals: while our adoption has increased greatly recently, we're still tiny compared to GCC. What are our @@ -153,6 +163,8 @@ given us some great things, but sometimes secrecy makes things difficult for those not involved; should there be an LLVM Foundation in our (distant?) future?
      Devang PatelUsing Bugpoint: How to use the bugpoint + tool to identifiy misoptimizations and bad code gen bugs.
      @@ -234,6 +246,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
      Last modified: $Date: 2007/04/02 17:47:52 $ +
      Last modified: $Date: 2007/04/02 18:16:34 $ From evan.cheng at apple.com Mon Apr 2 13:47:30 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 2 Apr 2007 13:47:30 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/ARM/2007-04-02-RegScavengerAssert.ll Message-ID: <200704021847.l32IlUEb021999@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/ARM: 2007-04-02-RegScavengerAssert.ll added (r1.1) --- Log message: New test case. --- Diffs of the changes: (+55 -0) 2007-04-02-RegScavengerAssert.ll | 55 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 55 insertions(+) Index: llvm/test/CodeGen/ARM/2007-04-02-RegScavengerAssert.ll diff -c /dev/null llvm/test/CodeGen/ARM/2007-04-02-RegScavengerAssert.ll:1.1 *** /dev/null Mon Apr 2 13:47:23 2007 --- llvm/test/CodeGen/ARM/2007-04-02-RegScavengerAssert.ll Mon Apr 2 13:47:13 2007 *************** *** 0 **** --- 1,55 ---- + ; RUN: llvm-as < %s | llc -march=arm -mtriple=arm-apple-darwin + + %struct.H_TBL = type { [17 x i8], [256 x i8], i32 } + %struct.Q_TBL = type { [64 x i16], i32 } + %struct.anon = type { [80 x i8] } + %struct.X_c_coef_ccler = type { void (%struct.X_Y*, i32)*, i32 (%struct.X_Y*, i8***)* } + %struct.X_c_main_ccler = type { void (%struct.X_Y*, i32)*, void (%struct.X_Y*, i8**, i32*, i32)* } + %struct.X_c_prep_ccler = type { void (%struct.X_Y*, i32)*, void (%struct.X_Y*, i8**, i32*, i32, i8***, i32*, i32)* } + %struct.X_color_converter = type { void (%struct.X_Y*)*, void (%struct.X_Y*, i8**, i8***, i32, i32)* } + %struct.X_common_struct = type { %struct.X_error_mgr*, %struct.X_memory_mgr*, %struct.X_progress_mgr*, i8*, i32, i32 } + %struct.X_comp_master = type { void (%struct.X_Y*)*, void (%struct.X_Y*)*, void (%struct.X_Y*)*, i32, i32 } + %struct.X_component_info = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.Q_TBL*, i8* } + %struct.X_Y = type { %struct.X_error_mgr*, %struct.X_memory_mgr*, %struct.X_progress_mgr*, i8*, i32, i32, %struct.X_destination_mgr*, i32, i32, i32, i32, double, i32, i32, i32, %struct.X_component_info*, [4 x %struct.Q_TBL*], [4 x %struct.H_TBL*], [4 x %struct.H_TBL*], [16 x i8], [16 x i8], [16 x i8], i32, %struct.X_scan_info*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8, i8, i8, i16, i16, i32, i32, i32, i32, i32, i32, i32, [4 x %struct.X_component_info*], i32, i32, i32, [10 x i32], i32, i32, i32, i32, %struct.X_comp_master*, %struct.X_c_main_ccler*, %struct.X_c_prep_ccler*, %struct.X_c_coef_ccler*, %struct.X_marker_writer*, %struct.X_color_converter*, %struct.X_downssr*, %struct.X_forward_D*, %struct.X_entropy_en*, %struct.X_scan_info*, i32 } + %struct.X_destination_mgr = type { i8*, i32, void (%struct.X_Y*)*, i32 (%struct.X_Y*)*, void (%struct.X_Y*)* } + %struct.X_downssr = type { void (%struct.X_Y*)*, void (%struct.X_Y*, i8***, i32, i8***, i32)*, i32 } + %struct.X_entropy_en = type { void (%struct.X_Y*, i32)*, i32 (%struct.X_Y*, [64 x i16]**)*, void (%struct.X_Y*)* } + %struct.X_error_mgr = type { void (%struct.X_common_struct*)*, void (%struct.X_common_struct*, i32)*, void (%struct.X_common_struct*)*, void (%struct.X_common_struct*, i8*)*, void (%struct.X_common_struct*)*, i32, %struct.anon, i32, i32, i8**, i32, i8**, i32, i32 } + %struct.X_forward_D = type { void (%struct.X_Y*)*, void (%struct.X_Y*, %struct.X_component_info*, i8**, [64 x i16]*, i32, i32, i32)* } + %struct.X_marker_writer = type { void (%struct.X_Y*)*, void (%struct.X_Y*)*, void (%struct.X_Y*)*, void (%struct.X_Y*)*, void (%struct.X_Y*)*, void (%struct.X_Y*, i32, i32)*, void (%struct.X_Y*, i32)* } + %struct.X_memory_mgr = type { i8* (%struct.X_common_struct*, i32, i32)*, i8* (%struct.X_common_struct*, i32, i32)*, i8** (%struct.X_common_struct*, i32, i32, i32)*, [64 x i16]** (%struct.X_common_struct*, i32, i32, i32)*, %struct.jvirt_sAY_cc* (%struct.X_common_struct*, i32, i32, i32, i32, i32)*, %struct.jvirt_bAY_cc* (%struct.X_common_struct*, i32, i32, i32, i32, i32)*, void (%struct.X_common_struct*)*, i8** (%struct.X_common_struct*, %struct.jvirt_sAY_cc*, i32, i32, i32)*, [64 x i16]** (%struct.X_common_struct*, %struct.jvirt_bAY_cc*, i32, i32, i32)*, void (%struct.X_common_struct*, i32)*, void (%struct.X_common_struct*)*, i32, i32 } + %struct.X_progress_mgr = type { void (%struct.X_common_struct*)*, i32, i32, i32, i32 } + %struct.X_scan_info = type { i32, [4 x i32], i32, i32, i32, i32 } + %struct.jvirt_bAY_cc = type opaque + %struct.jvirt_sAY_cc = type opaque + + define void @test(%struct.X_Y* %cinfo) { + entry: + br i1 false, label %bb.preheader, label %return + + bb.preheader: ; preds = %entry + %tbl.014.us = load i32* null ; [#uses=1] + br i1 false, label %cond_next.us, label %bb + + cond_next51.us: ; preds = %cond_next.us, %cond_true33.us.cond_true46.us_crit_edge + %htblptr.019.1.us = phi %struct.H_TBL** [ %tmp37.us, %cond_true33.us.cond_true46.us_crit_edge ], [ %tmp37.us, %cond_next.us ] ; <%struct.H_TBL**> [#uses=0] + ret void + + cond_true33.us.cond_true46.us_crit_edge: ; preds = %cond_next.us + call void @_C_X_a_HT( ) + br label %cond_next51.us + + cond_next.us: ; preds = %bb.preheader + %tmp37.us = getelementptr %struct.X_Y* %cinfo, i32 0, i32 17, i32 %tbl.014.us ; <%struct.H_TBL**> [#uses=3] + %tmp4524.us = load %struct.H_TBL** %tmp37.us ; <%struct.H_TBL*> [#uses=1] + icmp eq %struct.H_TBL* %tmp4524.us, null ; :0 [#uses=1] + br i1 %0, label %cond_true33.us.cond_true46.us_crit_edge, label %cond_next51.us + + bb: ; preds = %bb.preheader + ret void + + return: ; preds = %entry + ret void + } + + declare void @_C_X_a_HT() From evan.cheng at apple.com Mon Apr 2 13:49:39 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 2 Apr 2007 13:49:39 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h Message-ID: <200704021849.l32Ind6O022165@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveIntervalAnalysis.h updated: 1.76 -> 1.77 --- Log message: Ugh. Copy coalescer does not update register numbers. --- Diffs of the changes: (+4 -0) LiveIntervalAnalysis.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h diff -u llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.76 llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.77 --- llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.76 Wed Feb 28 20:03:03 2007 +++ llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h Mon Apr 2 13:49:18 2007 @@ -267,6 +267,10 @@ MachineInstr *lastRegisterUse(unsigned Reg, unsigned Start, unsigned End, MachineOperand *&MOU); + /// findDefOperand - Returns the MachineOperand that is a def of the specific + /// register. It returns NULL if the def is not found. + MachineOperand *findDefOperand(MachineInstr *MI, unsigned Reg); + /// unsetRegisterKill - Unset IsKill property of all uses of the specific /// register of the specific instruction. void unsetRegisterKill(MachineInstr *MI, unsigned Reg); From evan.cheng at apple.com Mon Apr 2 13:49:38 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 2 Apr 2007 13:49:38 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200704021849.l32IncBw022160@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.231 -> 1.232 --- Log message: Ugh. Copy coalescer does not update register numbers. --- Diffs of the changes: (+15 -2) LiveIntervalAnalysis.cpp | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.231 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.232 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.231 Fri Mar 30 15:18:35 2007 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Mon Apr 2 13:49:18 2007 @@ -945,7 +945,7 @@ } else { MachineInstr *SrcMI = getInstructionFromIndex(SrcStart); if (SrcMI) { - MachineOperand *mops = SrcMI->findRegisterDefOperand(SrcReg); + MachineOperand *mops = findDefOperand(SrcMI, repSrcReg); if (mops) // A dead def should have a single cycle interval. ++RemoveStart; @@ -1022,7 +1022,7 @@ } else { MachineInstr *SrcMI = getInstructionFromIndex(SrcStart); if (SrcMI) { - MachineOperand *mops = SrcMI->findRegisterDefOperand(SrcReg); + MachineOperand *mops = findDefOperand(SrcMI, repSrcReg); if (mops) mops->setIsDead(); } @@ -1617,6 +1617,19 @@ return NULL; } + +/// findDefOperand - Returns the MachineOperand that is a def of the specific +/// register. It returns NULL if the def is not found. +MachineOperand *LiveIntervals::findDefOperand(MachineInstr *MI, unsigned Reg) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI->getOperand(i); + if (MO.isReg() && MO.isDef() && + mri_->regsOverlap(rep(MO.getReg()), Reg)) + return &MO; + } + return NULL; +} + /// unsetRegisterKill - Unset IsKill property of all uses of specific register /// of the specific instruction. void LiveIntervals::unsetRegisterKill(MachineInstr *MI, unsigned Reg) { From sabre at nondot.org Mon Apr 2 13:51:35 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 13:51:35 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <200704021851.l32IpZaF022233@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMISelLowering.cpp updated: 1.36 -> 1.37 --- Log message: fix the CodeGen/ARM/2007-03-13-InstrSched.ll regression: allow IV's with scales to be folded into non-store instructions. --- Diffs of the changes: (+20 -4) ARMISelLowering.cpp | 24 ++++++++++++++++++++---- 1 files changed, 20 insertions(+), 4 deletions(-) Index: llvm/lib/Target/ARM/ARMISelLowering.cpp diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.36 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.37 --- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.36 Mon Apr 2 12:24:08 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp Mon Apr 2 13:51:18 2007 @@ -1332,6 +1332,15 @@ // r + r if (((unsigned)AM.HasBaseReg + AM.Scale) <= 2) return true; + + case MVT::isVoid: + // Note, we allow "void" uses (basically, uses that aren't loads or + // stores), because arm allows folding a scale into many arithmetic + // operations. This should be made more precise and revisited later. + + // Allow r << imm, but the imm has to be a multiple of two. + if (AM.Scale & 1) return false; + return isPowerOf2_32(AM.Scale); } break; } @@ -1413,12 +1422,19 @@ case MVT::i1: case MVT::i8: case MVT::i32: - // r + r - if (S == 2) - return true; - // r + r << imm + // Allow: r + r + // Allow: r << imm + // Allow: r + r << imm S &= ~1; return isPowerOf2_32(S); + case MVT::isVoid: + // Note, we allow "void" uses (basically, uses that aren't loads or + // stores), because arm allows folding a scale into many arithmetic + // operations. This should be made more precise and revisited later. + + // Allow r << imm, but the imm has to be a multiple of two. + if (S & 1) return false; + return isPowerOf2_32(S); } } From reid at x10sys.com Mon Apr 2 13:52:56 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 13:52:56 -0500 Subject: [llvm-commits] CVS: llvm-www/SVNMigration.html Message-ID: <200704021852.l32IquK8022321@zion.cs.uiuc.edu> Changes in directory llvm-www: SVNMigration.html updated: 1.1 -> 1.2 --- Log message: We don't need to keep the root version tag for branches because SVN does this automatically. --- Diffs of the changes: (+8 -7) SVNMigration.html | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) Index: llvm-www/SVNMigration.html diff -u llvm-www/SVNMigration.html:1.1 llvm-www/SVNMigration.html:1.2 --- llvm-www/SVNMigration.html:1.1 Mon Apr 2 13:04:19 2007 +++ llvm-www/SVNMigration.html Mon Apr 2 13:52:38 2007 @@ -75,13 +75,8 @@ it jtcllvaAssuming this is the LLVA tag - PARALLEL_ROOTRoot of the parallel branch RELEASE_*These are the final release tags (7 total) - ROOT_RELEASE_*These are the original release tags (9 total) - - - RC15This should have been ROOT_RELEASE_15, I think startThis seems to be the very first tag. It references an ancient version of llvm and is only of historical interest @@ -98,6 +93,7 @@ its unneeded at this point PowerPC_0_0Root of a branch we're deleting + PARALLEL_ROOTRoot of the parallel branch PRE10Root of a branch we're deleting PRE101Root of a branch we're deleting PRE11Root of a branch we're deleting @@ -105,7 +101,12 @@ PRE2_ROOTRoot of a branch we're deleting regalloc_linearscan_mergein_mainMerge point of branch we're deleting - ROOT_VLLVMAppears to be a typo + RC15This should have been ROOT_RELEASE_15, I think + ROOT_RELEASE_*These are the root version tags for release + branches (9 total). They aren't needed in SVN because of the way SVN + handles branches. + + ROOT_VLLVMThe root version tag for the vector_llvm branch. ST_incr_*SignlessTypes tags, not needed any more @@ -117,6 +118,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
      Last modified: $Date: 2007/04/02 18:04:19 $ +
      Last modified: $Date: 2007/04/02 18:52:38 $ From reid at x10sys.com Mon Apr 2 14:02:19 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 14:02:19 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704021902.l32J2JZG022699@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.28 -> 1.29 --- Log message: Add Christopher Lamb and his discussion topic. --- Diffs of the changes: (+9 -3) DevMtgMay2007.html | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.28 llvm-www/DevMtgMay2007.html:1.29 --- llvm-www/DevMtgMay2007.html:1.28 Mon Apr 2 13:16:34 2007 +++ llvm-www/DevMtgMay2007.html Mon Apr 2 14:02:02 2007 @@ -139,10 +139,15 @@ originator followed by 10 minutes of discussion. This will allow 6 issues to be discussed in this time slot.

      - + +
      Suggested ByIssue Description
      Suggested ByIssue Description
      Owen AndersonIntegration of HLVM into LLVM - its future as an LLVM subproject, and plans for making LLVM more accessible to scripting and higher level language front ends.
      Christopher LambConcurrency Primitives: for multi-threaded + shared memory models. Though I don't claim to be any sort of expert + myself, I've spent some time looking over the Java Memory Model revision + and discussions and I think it would be worth discussing similar issues + with regards to LLVM.
      @@ -225,6 +230,7 @@ Ryan BrownGoogle Jeff CohenIndependent Robert HundtGoogle + Christopher LambIndependent Chris LattnerApple, Inc. Nick LewyckyIndependent Scott Michel + 2Aerospace @@ -235,7 +241,7 @@ Bill WendlingApple, Inc. Marcel WeiherMetaObject -

      Total confirmed attendees: 18

      +

      Total confirmed attendees: 19

      Possible additional attendees: 6

      @@ -246,6 +252,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
      Last modified: $Date: 2007/04/02 18:16:34 $ +
      Last modified: $Date: 2007/04/02 19:02:02 $ From reid at x10sys.com Mon Apr 2 14:14:34 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 14:14:34 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704021914.l32JEYxK023196@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.29 -> 1.30 --- Log message: Fix Christopher Lamb's affiliation. --- Diffs of the changes: (+2 -2) DevMtgMay2007.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.29 llvm-www/DevMtgMay2007.html:1.30 --- llvm-www/DevMtgMay2007.html:1.29 Mon Apr 2 14:02:02 2007 +++ llvm-www/DevMtgMay2007.html Mon Apr 2 14:14:17 2007 @@ -230,7 +230,7 @@ Ryan BrownGoogle Jeff CohenIndependent Robert HundtGoogle - Christopher LambIndependent + Christopher LambAgeia Technologies, Inc. Chris LattnerApple, Inc. Nick LewyckyIndependent Scott Michel + 2Aerospace @@ -252,6 +252,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
      Last modified: $Date: 2007/04/02 19:02:02 $ +
      Last modified: $Date: 2007/04/02 19:14:17 $ From clattner at apple.com Mon Apr 2 15:11:53 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 2 Apr 2007 13:11:53 -0700 Subject: [llvm-commits] Patch resubmit: ROTL/ROTR cleanups In-Reply-To: <20070330190256.GA23803@rush.aero.org> References: <20070330190256.GA23803@rush.aero.org> Message-ID: <7F0A9BF5-B95B-4A88-9C07-A4C2C224BC61@apple.com> On Mar 30, 2007, at 12:02 PM, Scott Michel wrote: > Spotted what was probably a long-standing bug, since some of my > cleanups > were simple substitutions. Sorry for the delay. In general, if you keep the changes as simple and disjoint as possible, I'm more likely to look at them soon :). Here you could split up the "allow custom legalize of rotates" part from the "introduce some temporary vars" part from "match ext rotate cases" part. > -scooter > Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp > =================================================================== > --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (.../trunk) (revision > 2119) > +++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (.../branches/llvm- > spu) (revision 2119) > @@ -2683,10 +2683,24 @@ > case ISD::ROTR: > Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS > Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS > - > - assert(TLI.isOperationLegal(Node->getOpcode(), Node- > >getValueType(0)) && > - "Cannot handle this yet!"); > Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); > + switch (TLI.getOperationAction(Node->getOpcode(), Node- > >getValueType(0))) { > + default: > + assert(0 && "ROTL/ROTR legalize operation not supported"); > + break; > + case TargetLowering::Legal: > + break; > + case TargetLowering::Custom: > + Tmp1 = TLI.LowerOperation(Result, DAG); > + if (Tmp1.Val) Result = Tmp1; > + break; > + case TargetLowering::Promote: > + assert(0 && "Do not know how to promote ROTL/ROTR"); > + break; > + case TargetLowering::Expand: > + assert(0 && "Do not know how to expand ROTL/ROTR"); > + break; > + } > break; Looks good. > case ISD::BSWAP: > Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp > =================================================================== > --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp (.../trunk) (revision > 2119) > +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp (.../branches/llvm- > spu) (revision 2119) > @@ -1488,23 +1488,24 @@ > } > > unsigned OpSizeInBits = MVT::getSizeInBits(VT); > + SDOperand LHSShiftArg = LHSShift.getOperand(0); > + SDOperand LHSShiftAmt = LHSShift.getOperand(1); > + SDOperand RHSShiftAmt = RHSShift.getOperand(1); > > // fold (or (shl x, C1), (srl x, C2)) -> (rotl x, C1) > // fold (or (shl x, C1), (srl x, C2)) -> (rotr x, C2) > - if (LHSShift.getOperand(1).getOpcode() == ISD::Constant && > - RHSShift.getOperand(1).getOpcode() == ISD::Constant) { > - uint64_t LShVal = cast(LHSShift.getOperand(1))- > >getValue(); > - uint64_t RShVal = cast(RHSShift.getOperand(1))- > >getValue(); > + if (LHSShiftAmt.getOpcode() == ISD::Constant && > + RHSShiftAmt.getOpcode() == ISD::Constant) { > + uint64_t LShVal = cast(LHSShiftAmt)->getValue(); > + uint64_t RShVal = cast(RHSShiftAmt)->getValue(); > if ((LShVal + RShVal) != OpSizeInBits) > return 0; > > SDOperand Rot; > if (HasROTL) > - Rot = DAG.getNode(ISD::ROTL, VT, LHSShift.getOperand(0), > - LHSShift.getOperand(1)); > + Rot = DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt); > else > - Rot = DAG.getNode(ISD::ROTR, VT, LHSShift.getOperand(0), > - RHSShift.getOperand(1)); > + Rot = DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt); > > // If there is an AND of either shifted operand, apply it to > the result. > if (LHSMask.Val || RHSMask.Val) { Looks fine. > @@ -1532,35 +1533,71 @@ > > // fold (or (shl x, y), (srl x, (sub 32, y))) -> (rotl x, y) > // fold (or (shl x, y), (srl x, (sub 32, y))) -> (rotr x, (sub > 32, y)) > - if (RHSShift.getOperand(1).getOpcode() == ISD::SUB && > - LHSShift.getOperand(1) == RHSShift.getOperand(1).getOperand > (1)) { > + if (RHSShiftAmt.getOpcode() == ISD::SUB && > + LHSShiftAmt == RHSShiftAmt.getOperand(1)) { > if (ConstantSDNode *SUBC = > - dyn_cast(RHSShift.getOperand > (1).getOperand(0))) { > + dyn_cast(RHSShiftAmt.getOperand(0))) { > if (SUBC->getValue() == OpSizeInBits) > if (HasROTL) > - return DAG.getNode(ISD::ROTL, VT, LHSShift.getOperand(0), > - LHSShift.getOperand(1)).Val; > + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, > LHSShiftAmt).Val; > else > - return DAG.getNode(ISD::ROTR, VT, LHSShift.getOperand(0), > - LHSShift.getOperand(1)).Val; > + return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, > RHSShiftAmt).Val; > } > } ok > // fold (or (shl x, (sub 32, y)), (srl x, r)) -> (rotr x, y) > // fold (or (shl x, (sub 32, y)), (srl x, r)) -> (rotl x, (sub > 32, y)) > - if (LHSShift.getOperand(1).getOpcode() == ISD::SUB && > - RHSShift.getOperand(1) == LHSShift.getOperand(1).getOperand > (1)) { > + if (LHSShiftAmt.getOpcode() == ISD::SUB && > + RHSShiftAmt == LHSShiftAmt.getOperand(1)) { > if (ConstantSDNode *SUBC = > - dyn_cast(LHSShift.getOperand > (1).getOperand(0))) { > + dyn_cast(LHSShiftAmt.getOperand(0))) { > if (SUBC->getValue() == OpSizeInBits) > if (HasROTL) > - return DAG.getNode(ISD::ROTL, VT, LHSShift.getOperand(0), > - LHSShift.getOperand(1)).Val; > + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, > LHSShiftAmt).Val; > else > - return DAG.getNode(ISD::ROTR, VT, LHSShift.getOperand(0), > - RHSShift.getOperand(1)).Val; > + return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, > RHSShiftAmt).Val; > } > } Ok > + > + // Look for sign/zext/any-extended cases: > + if ((LHSShiftAmt.getOpcode() == ISD::SIGN_EXTEND > + || LHSShiftAmt.getOpcode() == ISD::ZERO_EXTEND > + || LHSShiftAmt.getOpcode() == ISD::ANY_EXTEND) && > + (RHSShiftAmt.getOpcode() == ISD::SIGN_EXTEND > + || RHSShiftAmt.getOpcode() == ISD::ZERO_EXTEND > + || RHSShiftAmt.getOpcode() == ISD::ANY_EXTEND)) { > + SDOperand LExtOp0 = LHSShiftAmt.getOperand(0); > + SDOperand RExtOp0 = RHSShiftAmt.getOperand(0); > + if (RExtOp0.getOpcode() == ISD::SUB && > + RExtOp0.getOperand(1) == LExtOp0) { > + // fold (or (shl x, (*ext y)), (srl x, (*ext (sub 32, y)))) -> > + // (rotr x, y) > + // fold (or (shl x, (*ext y)), (srl x, (*ext (sub 32, y)))) -> > + // (rotl x, (sub 32, y)) > + if (ConstantSDNode *SUBC = cast > (RExtOp0.getOperand(0))) { > + if (SUBC->getValue() == OpSizeInBits) { > + if (HasROTL) > + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).Val; > + else > + return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).Val; > + } Okay, but needs an extra level of spacing for the indentation here (2 spaces, not 1). > + } > + } else if (LExtOp0.getOpcode() == ISD::SUB && > + RExtOp0 == LExtOp0.getOperand(1)) { > + // fold (or (shl x, (*ext (sub 32, y))), (srl x, (*ext r))) -> > + // (rotl x, y) > + // fold (or (shl x, (*ext (sub 32, y))), (srl x, (*ext r))) -> > + // (rotr x, (sub 32, y)) > + if (ConstantSDNode *SUBC = cast > (LExtOp0.getOperand(0))) { > + if (SUBC->getValue() == OpSizeInBits) { > + if (HasROTL) > + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, RHSShiftAmt).Val; > + else > + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).Val; > + } Likewise. > + } > + } > + } Otherwise, looks great! Please commit, -Chris From dalej at apple.com Mon Apr 2 15:31:24 2007 From: dalej at apple.com (Dale Johannesen) Date: Mon, 2 Apr 2007 15:31:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp Message-ID: <200704022031.l32KVO1h025014@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMConstantIslandPass.cpp updated: 1.33 -> 1.34 --- Log message: fix off by 1 error in displacement computation --- Diffs of the changes: (+5 -0) ARMConstantIslandPass.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp diff -u llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.33 llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.34 --- llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.33 Thu Mar 1 02:26:31 2007 +++ llvm/lib/Target/ARM/ARMConstantIslandPass.cpp Mon Apr 2 15:31:06 2007 @@ -593,6 +593,11 @@ Water->begin()->getOpcode() != ARM::CONSTPOOL_ENTRY)) CPEOffset += 2; + // If the CPE is to be inserted before the instruction, that will raise + // the offset of the instruction. + if (CPEOffset < UserOffset) + UserOffset += isThumb ? 2 : 4; + return OffsetIsInRange (UserOffset, CPEOffset, MaxDisp, !isThumb); } From sabre at nondot.org Mon Apr 2 15:31:57 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 15:31:57 -0500 Subject: [llvm-commits] CVS: llvm-www/pubs/2007-03-12-BossaLLVMIntro.pdf Message-ID: <200704022031.l32KVvAx025067@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2007-03-12-BossaLLVMIntro.pdf updated: 1.2 -> 1.3 --- Log message: this time with less crashing? --- Diffs of the changes: (+0 -0) 2007-03-12-BossaLLVMIntro.pdf | 0 1 files changed Index: llvm-www/pubs/2007-03-12-BossaLLVMIntro.pdf From sabre at nondot.org Mon Apr 2 15:40:08 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 15:40:08 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/X86/2007-03-24-InlineAsmVectorOp.ll Message-ID: <200704022040.l32Ke8W7025262@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/X86: 2007-03-24-InlineAsmVectorOp.ll updated: 1.2 -> 1.3 --- Log message: fix this testcase on ppc hosts --- Diffs of the changes: (+1 -1) 2007-03-24-InlineAsmVectorOp.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/CodeGen/X86/2007-03-24-InlineAsmVectorOp.ll diff -u llvm/test/CodeGen/X86/2007-03-24-InlineAsmVectorOp.ll:1.2 llvm/test/CodeGen/X86/2007-03-24-InlineAsmVectorOp.ll:1.3 --- llvm/test/CodeGen/X86/2007-03-24-InlineAsmVectorOp.ll:1.2 Tue Mar 27 21:38:26 2007 +++ llvm/test/CodeGen/X86/2007-03-24-InlineAsmVectorOp.ll Mon Apr 2 15:39:48 2007 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 | grep 'cmpltsd %xmm0, %xmm0' +; RUN: llvm-as < %s | llc -mcpu=yonah -march=x86 | grep 'cmpltsd %xmm0, %xmm0' target datalayout = "e-p:32:32" target triple = "i686-apple-darwin9" From sabre at nondot.org Mon Apr 2 15:46:45 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 15:46:45 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/InstCombine/bitcount.ll Message-ID: <200704022046.l32KkjF5025530@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/InstCombine: bitcount.ll updated: 1.2 -> 1.3 --- Log message: fix this testcase so it passes --- Diffs of the changes: (+2 -2) bitcount.ll | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/test/Transforms/InstCombine/bitcount.ll diff -u llvm/test/Transforms/InstCombine/bitcount.ll:1.2 llvm/test/Transforms/InstCombine/bitcount.ll:1.3 --- llvm/test/Transforms/InstCombine/bitcount.ll:1.2 Sun Apr 1 22:24:47 2007 +++ llvm/test/Transforms/InstCombine/bitcount.ll Mon Apr 2 15:46:28 2007 @@ -1,6 +1,6 @@ ; Tests to make sure bit counts of constants are folded -; RUN: llvm-as < %s | opt -instcombine | llvm-dis -o /dev/null -f && -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'llvm.ct' +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep 'ret i32 19' && +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v declare | not grep 'llvm.ct' declare i32 @llvm.ctpop.i31(i31 %val) declare i32 @llvm.cttz.i32(i32 %val) From scottm at aero.org Mon Apr 2 16:36:49 2007 From: scottm at aero.org (Scott Michel) Date: Mon, 2 Apr 2007 16:36:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp Message-ID: <200704022136.l32Lanso026971@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.284 -> 1.285 LegalizeDAG.cpp updated: 1.485 -> 1.486 --- Log message: 1. Insert custom lowering hooks for ISD::ROTR and ISD::ROTL. 2. Help DAGCombiner recognize zero/sign/any-extended versions of ROTR and ROTL patterns. This was motivated by the X86/rotate.ll testcase, which should now generate code for other platforms (and soon-to-come platforms.) Rewrote code slightly to make it easier to read. --- Diffs of the changes: (+76 -25) DAGCombiner.cpp | 81 ++++++++++++++++++++++++++++++++++++++++---------------- LegalizeDAG.cpp | 20 +++++++++++-- 2 files changed, 76 insertions(+), 25 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.284 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.285 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.284 Fri Mar 30 16:38:07 2007 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Apr 2 16:36:32 2007 @@ -1488,23 +1488,24 @@ } unsigned OpSizeInBits = MVT::getSizeInBits(VT); + SDOperand LHSShiftArg = LHSShift.getOperand(0); + SDOperand LHSShiftAmt = LHSShift.getOperand(1); + SDOperand RHSShiftAmt = RHSShift.getOperand(1); // fold (or (shl x, C1), (srl x, C2)) -> (rotl x, C1) // fold (or (shl x, C1), (srl x, C2)) -> (rotr x, C2) - if (LHSShift.getOperand(1).getOpcode() == ISD::Constant && - RHSShift.getOperand(1).getOpcode() == ISD::Constant) { - uint64_t LShVal = cast(LHSShift.getOperand(1))->getValue(); - uint64_t RShVal = cast(RHSShift.getOperand(1))->getValue(); + if (LHSShiftAmt.getOpcode() == ISD::Constant && + RHSShiftAmt.getOpcode() == ISD::Constant) { + uint64_t LShVal = cast(LHSShiftAmt)->getValue(); + uint64_t RShVal = cast(RHSShiftAmt)->getValue(); if ((LShVal + RShVal) != OpSizeInBits) return 0; SDOperand Rot; if (HasROTL) - Rot = DAG.getNode(ISD::ROTL, VT, LHSShift.getOperand(0), - LHSShift.getOperand(1)); + Rot = DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt); else - Rot = DAG.getNode(ISD::ROTR, VT, LHSShift.getOperand(0), - RHSShift.getOperand(1)); + Rot = DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt); // If there is an AND of either shifted operand, apply it to the result. if (LHSMask.Val || RHSMask.Val) { @@ -1532,33 +1533,69 @@ // fold (or (shl x, y), (srl x, (sub 32, y))) -> (rotl x, y) // fold (or (shl x, y), (srl x, (sub 32, y))) -> (rotr x, (sub 32, y)) - if (RHSShift.getOperand(1).getOpcode() == ISD::SUB && - LHSShift.getOperand(1) == RHSShift.getOperand(1).getOperand(1)) { + if (RHSShiftAmt.getOpcode() == ISD::SUB && + LHSShiftAmt == RHSShiftAmt.getOperand(1)) { if (ConstantSDNode *SUBC = - dyn_cast(RHSShift.getOperand(1).getOperand(0))) { + dyn_cast(RHSShiftAmt.getOperand(0))) { if (SUBC->getValue() == OpSizeInBits) if (HasROTL) - return DAG.getNode(ISD::ROTL, VT, LHSShift.getOperand(0), - LHSShift.getOperand(1)).Val; + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).Val; else - return DAG.getNode(ISD::ROTR, VT, LHSShift.getOperand(0), - LHSShift.getOperand(1)).Val; + return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).Val; } } // fold (or (shl x, (sub 32, y)), (srl x, r)) -> (rotr x, y) // fold (or (shl x, (sub 32, y)), (srl x, r)) -> (rotl x, (sub 32, y)) - if (LHSShift.getOperand(1).getOpcode() == ISD::SUB && - RHSShift.getOperand(1) == LHSShift.getOperand(1).getOperand(1)) { + if (LHSShiftAmt.getOpcode() == ISD::SUB && + RHSShiftAmt == LHSShiftAmt.getOperand(1)) { if (ConstantSDNode *SUBC = - dyn_cast(LHSShift.getOperand(1).getOperand(0))) { + dyn_cast(LHSShiftAmt.getOperand(0))) { if (SUBC->getValue() == OpSizeInBits) if (HasROTL) - return DAG.getNode(ISD::ROTL, VT, LHSShift.getOperand(0), - LHSShift.getOperand(1)).Val; + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).Val; else - return DAG.getNode(ISD::ROTR, VT, LHSShift.getOperand(0), - RHSShift.getOperand(1)).Val; + return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).Val; + } + } + + // Look for sign/zext/any-extended cases: + if ((LHSShiftAmt.getOpcode() == ISD::SIGN_EXTEND + || LHSShiftAmt.getOpcode() == ISD::ZERO_EXTEND + || LHSShiftAmt.getOpcode() == ISD::ANY_EXTEND) && + (RHSShiftAmt.getOpcode() == ISD::SIGN_EXTEND + || RHSShiftAmt.getOpcode() == ISD::ZERO_EXTEND + || RHSShiftAmt.getOpcode() == ISD::ANY_EXTEND)) { + SDOperand LExtOp0 = LHSShiftAmt.getOperand(0); + SDOperand RExtOp0 = RHSShiftAmt.getOperand(0); + if (RExtOp0.getOpcode() == ISD::SUB && + RExtOp0.getOperand(1) == LExtOp0) { + // fold (or (shl x, (*ext y)), (srl x, (*ext (sub 32, y)))) -> + // (rotr x, y) + // fold (or (shl x, (*ext y)), (srl x, (*ext (sub 32, y)))) -> + // (rotl x, (sub 32, y)) + if (ConstantSDNode *SUBC = cast(RExtOp0.getOperand(0))) { + if (SUBC->getValue() == OpSizeInBits) { + if (HasROTL) + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).Val; + else + return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).Val; + } + } + } else if (LExtOp0.getOpcode() == ISD::SUB && + RExtOp0 == LExtOp0.getOperand(1)) { + // fold (or (shl x, (*ext (sub 32, y))), (srl x, (*ext r))) -> + // (rotl x, y) + // fold (or (shl x, (*ext (sub 32, y))), (srl x, (*ext r))) -> + // (rotr x, (sub 32, y)) + if (ConstantSDNode *SUBC = cast(LExtOp0.getOperand(0))) { + if (SUBC->getValue() == OpSizeInBits) { + if (HasROTL) + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, RHSShiftAmt).Val; + else + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).Val; + } + } } } Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.485 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.486 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.485 Sat Mar 24 12:37:03 2007 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Apr 2 16:36:32 2007 @@ -2683,10 +2683,24 @@ case ISD::ROTR: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS - - assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) && - "Cannot handle this yet!"); Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { + default: + assert(0 && "ROTL/ROTR legalize operation not supported"); + break; + case TargetLowering::Legal: + break; + case TargetLowering::Custom: + Tmp1 = TLI.LowerOperation(Result, DAG); + if (Tmp1.Val) Result = Tmp1; + break; + case TargetLowering::Promote: + assert(0 && "Do not know how to promote ROTL/ROTR"); + break; + case TargetLowering::Expand: + assert(0 && "Do not know how to expand ROTL/ROTR"); + break; + } break; case ISD::BSWAP: From scottm at aero.org Mon Apr 2 16:44:12 2007 From: scottm at aero.org (Scott Michel) Date: Mon, 2 Apr 2007 14:44:12 -0700 Subject: [llvm-commits] Patch resubmit: ROTL/ROTR cleanups In-Reply-To: <7F0A9BF5-B95B-4A88-9C07-A4C2C224BC61@apple.com> References: <20070330190256.GA23803@rush.aero.org> <7F0A9BF5-B95B-4A88-9C07-A4C2C224BC61@apple.com> Message-ID: <1B0FB693-9496-4628-81C3-F5D7186FBB53@aero.org> On Apr 2, 2007, at 1:11 PM, Chris Lattner wrote: > On Mar 30, 2007, at 12:02 PM, Scott Michel wrote: >> Spotted what was probably a long-standing bug, since some of my >> cleanups >> were simple substitutions. > > Sorry for the delay. In general, if you keep the changes as simple > and disjoint as possible, I'm more likely to look at them soon :). > Here you could split up the "allow custom legalize of rotates" part > from the "introduce some temporary vars" part from "match ext > rotate cases" part. I did, I did, I did! Really! They're part and parcel of the same functionality... :-) >> + >> + // Look for sign/zext/any-extended cases: >> + if ((LHSShiftAmt.getOpcode() == ISD::SIGN_EXTEND >> + || LHSShiftAmt.getOpcode() == ISD::ZERO_EXTEND >> + || LHSShiftAmt.getOpcode() == ISD::ANY_EXTEND) && >> + (RHSShiftAmt.getOpcode() == ISD::SIGN_EXTEND >> + || RHSShiftAmt.getOpcode() == ISD::ZERO_EXTEND >> + || RHSShiftAmt.getOpcode() == ISD::ANY_EXTEND)) { >> + SDOperand LExtOp0 = LHSShiftAmt.getOperand(0); >> + SDOperand RExtOp0 = RHSShiftAmt.getOperand(0); >> + if (RExtOp0.getOpcode() == ISD::SUB && >> + RExtOp0.getOperand(1) == LExtOp0) { >> + // fold (or (shl x, (*ext y)), (srl x, (*ext (sub 32, y)))) -> >> + // (rotr x, y) >> + // fold (or (shl x, (*ext y)), (srl x, (*ext (sub 32, y)))) -> >> + // (rotl x, (sub 32, y)) >> + if (ConstantSDNode *SUBC = cast >> (RExtOp0.getOperand(0))) { >> + if (SUBC->getValue() == OpSizeInBits) { >> + if (HasROTL) >> + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, >> LHSShiftAmt).Val; >> + else >> + return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, >> RHSShiftAmt).Val; >> + } > > Okay, but needs an extra level of spacing for the indentation here > (2 spaces, not 1). > >> + } >> + } else if (LExtOp0.getOpcode() == ISD::SUB && >> + RExtOp0 == LExtOp0.getOperand(1)) { >> + // fold (or (shl x, (*ext (sub 32, y))), (srl x, (*ext r))) -> >> + // (rotl x, y) >> + // fold (or (shl x, (*ext (sub 32, y))), (srl x, (*ext r))) -> >> + // (rotr x, (sub 32, y)) >> + if (ConstantSDNode *SUBC = cast >> (LExtOp0.getOperand(0))) { >> + if (SUBC->getValue() == OpSizeInBits) { >> + if (HasROTL) >> + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, >> RHSShiftAmt).Val; >> + else >> + return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, >> LHSShiftAmt).Val; >> + } > > Likewise. Fixed tab violations, which made it look like incorrect indentation... -scooter From sabre at nondot.org Mon Apr 2 17:09:12 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 17:09:12 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/PowerPC/rotl-2.ll Message-ID: <200704022209.l32M9CU3027891@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/PowerPC: rotl-2.ll added (r1.1) --- Log message: Add a regtest for cases we now recognize as rotates, thanks to Scott Michel's recent dagcombine patch --- Diffs of the changes: (+38 -0) rotl-2.ll | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+) Index: llvm/test/CodeGen/PowerPC/rotl-2.ll diff -c /dev/null llvm/test/CodeGen/PowerPC/rotl-2.ll:1.1 *** /dev/null Mon Apr 2 17:09:04 2007 --- llvm/test/CodeGen/PowerPC/rotl-2.ll Mon Apr 2 17:08:54 2007 *************** *** 0 **** --- 1,38 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 | grep rlwinm | wc -l | grep 4 && + ; RUN: llvm-as < %s | llc -march=ppc32 | grep rlwnm | wc -l | grep 2 && + ; RUN: llvm-as < %s | llc -march=ppc32 | not grep or + + define i32 @rotl32(i32 %A, i8 %Amt) { + %shift.upgrd.1 = zext i8 %Amt to i32 ; [#uses=1] + %B = shl i32 %A, %shift.upgrd.1 ; [#uses=1] + %Amt2 = sub i8 32, %Amt ; [#uses=1] + %shift.upgrd.2 = zext i8 %Amt2 to i32 ; [#uses=1] + %C = lshr i32 %A, %shift.upgrd.2 ; [#uses=1] + %D = or i32 %B, %C ; [#uses=1] + ret i32 %D + } + + define i32 @rotr32(i32 %A, i8 %Amt) { + %shift.upgrd.3 = zext i8 %Amt to i32 ; [#uses=1] + %B = lshr i32 %A, %shift.upgrd.3 ; [#uses=1] + %Amt2 = sub i8 32, %Amt ; [#uses=1] + %shift.upgrd.4 = zext i8 %Amt2 to i32 ; [#uses=1] + %C = shl i32 %A, %shift.upgrd.4 ; [#uses=1] + %D = or i32 %B, %C ; [#uses=1] + ret i32 %D + } + + define i32 @rotli32(i32 %A) { + %B = shl i32 %A, 5 ; [#uses=1] + %C = lshr i32 %A, 27 ; [#uses=1] + %D = or i32 %B, %C ; [#uses=1] + ret i32 %D + } + + define i32 @rotri32(i32 %A) { + %B = lshr i32 %A, 5 ; [#uses=1] + %C = shl i32 %A, 27 ; [#uses=1] + %D = or i32 %B, %C ; [#uses=1] + ret i32 %D + } + From clattner at apple.com Mon Apr 2 17:10:00 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 2 Apr 2007 15:10:00 -0700 Subject: [llvm-commits] Patch resubmit: ROTL/ROTR cleanups In-Reply-To: <1B0FB693-9496-4628-81C3-F5D7186FBB53@aero.org> References: <20070330190256.GA23803@rush.aero.org> <7F0A9BF5-B95B-4A88-9C07-A4C2C224BC61@apple.com> <1B0FB693-9496-4628-81C3-F5D7186FBB53@aero.org> Message-ID: <88DFEF3D-BBB4-47E5-A1FD-1F17D4329889@apple.com> On Apr 2, 2007, at 2:44 PM, Scott Michel wrote: > On Apr 2, 2007, at 1:11 PM, Chris Lattner wrote: > >> On Mar 30, 2007, at 12:02 PM, Scott Michel wrote: >>> Spotted what was probably a long-standing bug, since some of my >>> cleanups >>> were simple substitutions. >> >> Sorry for the delay. In general, if you keep the changes as simple >> and disjoint as possible, I'm more likely to look at them soon :). >> Here you could split up the "allow custom legalize of rotates" part >> from the "introduce some temporary vars" part from "match ext >> rotate cases" part. > > I did, I did, I did! Really! They're part and parcel of the same > functionality... :-) :) >> Likewise. > > Fixed tab violations, which made it look like incorrect indentation... Great, even better! -Chris From sabre at nondot.org Mon Apr 2 17:52:15 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 17:52:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200704022252.l32MqFWJ028835@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.124 -> 1.125 --- Log message: allow -1 strides to reuse "1" strides. --- Diffs of the changes: (+2 -1) LoopStrengthReduce.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.124 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.125 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.124 Mon Apr 2 01:34:44 2007 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Apr 2 17:51:58 2007 @@ -929,7 +929,8 @@ for (std::map::iterator SI= IVsByStride.begin(), SE = IVsByStride.end(); SI != SE; ++SI) { int64_t SSInt = cast(SI->first)->getValue()->getSExtValue(); - if (unsigned(abs(SInt)) < SSInt || (SInt % SSInt) != 0) + if (SInt != -SSInt && + (unsigned(abs(SInt)) < SSInt || (SInt % SSInt) != 0)) continue; int64_t Scale = SInt / SSInt; // Check that this stride is valid for all the types used for loads and From johannes at apple.com Mon Apr 2 19:10:48 2007 From: johannes at apple.com (johannes at apple.com) Date: Mon, 2 Apr 2007 17:10:48 -0700 (PDT) Subject: [llvm-commits] [125637] arm EABI patch (from Lauro Ramos Venancio) Message-ID: <20070403001048.7E8FFCB7FEFE@src> Revision: 125637 Author: johannes Date: 2007-04-02 17:10:47 -0700 (Mon, 02 Apr 2007) Log Message: ----------- arm EABI patch (from Lauro Ramos Venancio) Modified Paths: -------------- apple-local/branches/llvm/libstdc++-v3/Makefile.in apple-local/branches/llvm/libstdc++-v3/acinclude.m4 apple-local/branches/llvm/libstdc++-v3/aclocal.m4 apple-local/branches/llvm/libstdc++-v3/configure apple-local/branches/llvm/libstdc++-v3/include/Makefile.in apple-local/branches/llvm/libstdc++-v3/libmath/Makefile.in apple-local/branches/llvm/libstdc++-v3/libsupc++/Makefile.am apple-local/branches/llvm/libstdc++-v3/libsupc++/Makefile.in apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_catch.cc apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_personality.cc apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_throw.cc apple-local/branches/llvm/libstdc++-v3/libsupc++/unwind-cxx.h apple-local/branches/llvm/libstdc++-v3/po/Makefile.in apple-local/branches/llvm/libstdc++-v3/src/Makefile.in Modified: apple-local/branches/llvm/libstdc++-v3/Makefile.in =================================================================== --- apple-local/branches/llvm/libstdc++-v3/Makefile.in 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/Makefile.in 2007-04-03 00:10:47 UTC (rev 125637) @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -408,7 +408,13 @@ # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): - @set fnord $$MAKEFLAGS; amf=$$2; \ + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ @@ -420,7 +426,7 @@ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ @@ -428,7 +434,13 @@ mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: - @set fnord $$MAKEFLAGS; amf=$$2; \ + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ @@ -449,7 +461,7 @@ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ Modified: apple-local/branches/llvm/libstdc++-v3/acinclude.m4 =================================================================== --- apple-local/branches/llvm/libstdc++-v3/acinclude.m4 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/acinclude.m4 2007-04-03 00:10:47 UTC (rev 125637) @@ -1675,6 +1675,10 @@ enable_sjlj_exceptions=yes elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then enable_sjlj_exceptions=no + #APPLE LOCAL begin LLVM + elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no + #APPLE LOCAL end LLVM fi fi # APPLE LOCAL LLVM HACK! Modified: apple-local/branches/llvm/libstdc++-v3/aclocal.m4 =================================================================== --- apple-local/branches/llvm/libstdc++-v3/aclocal.m4 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/aclocal.m4 2007-04-03 00:10:47 UTC (rev 125637) @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.9.3 -*- Autoconf -*- +# generated automatically by aclocal 1.9.5 -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -# Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,24 +11,12 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -# -*- Autoconf -*- -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. -# Generated from amversion.in; do not edit by hand. +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been @@ -40,27 +28,16 @@ # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.3])]) + [AM_AUTOMAKE_VERSION([1.9.5])]) -# AM_AUX_DIR_EXPAND +# AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. @@ -106,27 +83,17 @@ am_aux_dir=`cd $ac_aux_dir && pwd` ]) -# AM_CONDITIONAL -*- Autoconf -*- +# AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# serial 7 -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 6 - # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. @@ -149,31 +116,20 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Do all the work for Automake. -*- Autoconf -*- +# Do all the work for Automake. -*- Autoconf -*- -# This macro actually does too much some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# serial 12 -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 11 - # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -333,29 +289,18 @@ rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) -# Add --enable-maintainer-mode option to configure. +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004 +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# serial 4 -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 - AC_DEFUN([AM_MAINTAINER_MODE], [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode is disabled by default @@ -373,28 +318,17 @@ AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) -# -*- Autoconf -*- +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. +# serial 4 -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -419,27 +353,16 @@ fi ]) +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. - -# Copyright (C) 2003, 2004 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - +# # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). @@ -493,26 +416,15 @@ fi AC_SUBST([mkdir_p])]) -# Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 +# Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# serial 5 -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 4 - # AM_ENABLE_MULTILIB([MAKEFILE], [REL-TO-TOP-SRCDIR]) # --------------------------------------------------- # Add --enable-multilib to configure. @@ -562,27 +474,16 @@ CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} CC="$CC"])])dnl -# Helper functions for option handling. -*- Autoconf -*- +# Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# serial 3 -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 2 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -606,29 +507,17 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. # -# Check to make sure that the build environment is sane. -# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. +# serial 4 -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 - # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], @@ -670,25 +559,14 @@ fi AC_MSG_RESULT(yes)]) -# AM_PROG_INSTALL_STRIP +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# Copyright (C) 2001, 2003 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - +# AM_PROG_INSTALL_STRIP +# --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip @@ -711,26 +589,14 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004 Free Software Foundation, Inc. +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# serial 2 -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 1 - - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. Modified: apple-local/branches/llvm/libstdc++-v3/configure =================================================================== --- apple-local/branches/llvm/libstdc++-v3/configure 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/configure 2007-04-03 00:10:47 UTC (rev 125637) @@ -5031,6 +5031,8 @@ enable_sjlj_exceptions=yes elif grep _Unwind_Resume conftest.s >/dev/null 2>&1 ; then enable_sjlj_exceptions=no + elif grep __cxa_end_cleanup conftest.s >/dev/null 2>&1 ; then + enable_sjlj_exceptions=no fi fi # APPLE LOCAL LLVM HACK! Modified: apple-local/branches/llvm/libstdc++-v3/include/Makefile.in =================================================================== --- apple-local/branches/llvm/libstdc++-v3/include/Makefile.in 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/include/Makefile.in 2007-04-03 00:10:47 UTC (rev 125637) @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. Modified: apple-local/branches/llvm/libstdc++-v3/libmath/Makefile.in =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libmath/Makefile.in 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/libmath/Makefile.in 2007-04-03 00:10:47 UTC (rev 125637) @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. Modified: apple-local/branches/llvm/libstdc++-v3/libsupc++/Makefile.am =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libsupc++/Makefile.am 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/libsupc++/Makefile.am 2007-04-03 00:10:47 UTC (rev 125637) @@ -45,7 +45,13 @@ del_opv.cc \ del_opvnt.cc \ eh_alloc.cc \ +#APPLE LOCAL begin LLVM \ + eh_arm.cc \ +#APPLE LOCAL end LLVM \ eh_aux_runtime.cc \ +#APPLE LOCAL begin LLVM \ + eh_call.cc \ +#APPLE LOCAL end LLVM \ eh_catch.cc \ eh_exception.cc \ eh_globals.cc \ Modified: apple-local/branches/llvm/libstdc++-v3/libsupc++/Makefile.in =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libsupc++/Makefile.in 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/libsupc++/Makefile.in 2007-04-03 00:10:47 UTC (rev 125637) @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -65,29 +65,31 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES) libsupc___la_LIBADD = am__libsupc___la_SOURCES_DIST = del_op.cc del_opnt.cc del_opv.cc \ - del_opvnt.cc eh_alloc.cc eh_aux_runtime.cc eh_catch.cc \ - eh_exception.cc eh_globals.cc eh_personality.cc \ - eh_term_handler.cc eh_terminate.cc eh_throw.cc eh_type.cc \ - eh_unex_handler.cc guard.cc new_handler.cc new_op.cc \ - new_opnt.cc new_opv.cc new_opvnt.cc pure.cc tinfo.cc tinfo2.cc \ - vec.cc vterminate.cc cp-demangle.c + del_opvnt.cc eh_alloc.cc eh_arm.cc eh_aux_runtime.cc \ + eh_call.cc eh_catch.cc eh_exception.cc eh_globals.cc \ + eh_personality.cc eh_term_handler.cc eh_terminate.cc \ + eh_throw.cc eh_type.cc eh_unex_handler.cc guard.cc \ + new_handler.cc new_op.cc new_opnt.cc new_opv.cc new_opvnt.cc \ + pure.cc tinfo.cc tinfo2.cc vec.cc vterminate.cc cp-demangle.c am__objects_1 = del_op.lo del_opnt.lo del_opv.lo del_opvnt.lo \ - eh_alloc.lo eh_aux_runtime.lo eh_catch.lo eh_exception.lo \ - eh_globals.lo eh_personality.lo eh_term_handler.lo \ - eh_terminate.lo eh_throw.lo eh_type.lo eh_unex_handler.lo \ - guard.lo new_handler.lo new_op.lo new_opnt.lo new_opv.lo \ - new_opvnt.lo pure.lo tinfo.lo tinfo2.lo vec.lo vterminate.lo + eh_alloc.lo eh_arm.lo eh_aux_runtime.lo eh_call.lo eh_catch.lo \ + eh_exception.lo eh_globals.lo eh_personality.lo \ + eh_term_handler.lo eh_terminate.lo eh_throw.lo eh_type.lo \ + eh_unex_handler.lo guard.lo new_handler.lo new_op.lo \ + new_opnt.lo new_opv.lo new_opvnt.lo pure.lo tinfo.lo tinfo2.lo \ + vec.lo vterminate.lo @GLIBCXX_HOSTED_TRUE at am__objects_2 = cp-demangle.lo am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2) libsupc___la_OBJECTS = $(am_libsupc___la_OBJECTS) libsupc__convenience_la_LIBADD = am__libsupc__convenience_la_SOURCES_DIST = del_op.cc del_opnt.cc \ - del_opv.cc del_opvnt.cc eh_alloc.cc eh_aux_runtime.cc \ - eh_catch.cc eh_exception.cc eh_globals.cc eh_personality.cc \ - eh_term_handler.cc eh_terminate.cc eh_throw.cc eh_type.cc \ - eh_unex_handler.cc guard.cc new_handler.cc new_op.cc \ - new_opnt.cc new_opv.cc new_opvnt.cc pure.cc tinfo.cc tinfo2.cc \ - vec.cc vterminate.cc cp-demangle.c + del_opv.cc del_opvnt.cc eh_alloc.cc eh_arm.cc \ + eh_aux_runtime.cc eh_call.cc eh_catch.cc eh_exception.cc \ + eh_globals.cc eh_personality.cc eh_term_handler.cc \ + eh_terminate.cc eh_throw.cc eh_type.cc eh_unex_handler.cc \ + guard.cc new_handler.cc new_op.cc new_opnt.cc new_opv.cc \ + new_opvnt.cc pure.cc tinfo.cc tinfo2.cc vec.cc vterminate.cc \ + cp-demangle.c am_libsupc__convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2) libsupc__convenience_la_OBJECTS = \ $(am_libsupc__convenience_la_OBJECTS) @@ -310,7 +312,13 @@ del_opv.cc \ del_opvnt.cc \ eh_alloc.cc \ +#APPLE LOCAL begin LLVM \ + eh_arm.cc \ +#APPLE LOCAL end LLVM \ eh_aux_runtime.cc \ +#APPLE LOCAL begin LLVM \ + eh_call.cc \ +#APPLE LOCAL end LLVM \ eh_catch.cc \ eh_exception.cc \ eh_globals.cc \ Modified: apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_catch.cc =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_catch.cc 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_catch.cc 2007-04-03 00:10:47 UTC (rev 125637) @@ -38,9 +38,10 @@ { _Unwind_Exception *exceptionObject = reinterpret_cast <_Unwind_Exception *>(exc_obj_in); - __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); - return header->adjustedPtr; +// APPLE LOCAL begin LLVM + return __gxx_caught_object(exceptionObject); +// APPLE LOCAL end LLVM } extern "C" void * @@ -51,12 +52,17 @@ __cxa_eh_globals *globals = __cxa_get_globals (); __cxa_exception *prev = globals->caughtExceptions; __cxa_exception *header = __get_exception_header_from_ue (exceptionObject); +// APPLE LOCAL begin LLVM + void* objectp; +// APPLE LOCAL end LLVM // Foreign exceptions can't be stacked here. If the exception stack is // empty, then fine. Otherwise we really have no choice but to terminate. // Note that this use of "header" is a lie. It's fine so long as we only // examine header->unwindHeader though. - if (header->unwindHeader.exception_class != __gxx_exception_class) +// APPLE LOCAL begin LLVM + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) +// APPLE LOCAL end LLVM { if (prev != 0) std::terminate (); @@ -85,7 +91,13 @@ globals->caughtExceptions = header; } - return header->adjustedPtr; +// APPLE LOCAL begin LLVM + objectp = __gxx_caught_object(exceptionObject); +#ifdef __ARM_EABI_UNWINDER__ + _Unwind_Complete(exceptionObject); +#endif + return objectp; +// APPLE LOCAL end LLVM } @@ -102,7 +114,9 @@ // A foreign exception couldn't have been stacked (see above), // so by definition processing must be complete. - if (header->unwindHeader.exception_class != __gxx_exception_class) +// APPLE LOCAL begin LLVM + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) +// APPLE LOCAL end LLVM { globals->caughtExceptions = 0; _Unwind_DeleteException (&header->unwindHeader); Modified: apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_personality.cc =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_personality.cc 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_personality.cc 2007-04-03 00:10:47 UTC (rev 125637) @@ -35,6 +35,12 @@ using namespace __cxxabiv1; +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ +#define NO_SIZE_OF_ENCODED_VALUE +#endif +// APPLE LOCAL end LLVM + #include "unwind-pe.h" @@ -84,6 +90,119 @@ return p; } +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ + +// Return an element from a type table. + +static const std::type_info* +get_ttype_entry(lsda_header_info* info, _Unwind_Word i) +{ + _Unwind_Ptr ptr; + + ptr = (_Unwind_Ptr) (info->TType - (i * 4)); + ptr = _Unwind_decode_target2(ptr); + + return reinterpret_cast(ptr); +} + +// The ABI provides a routine for matching exception object types. +typedef _Unwind_Control_Block _throw_typet; +#define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \ + (__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \ + != ctm_failed) + +// Return true if THROW_TYPE matches one if the filter types. + +static bool +check_exception_spec(lsda_header_info* info, _throw_typet* throw_type, + void* thrown_ptr, _Unwind_Sword filter_value) +{ + const _Unwind_Word* e = ((const _Unwind_Word*) info->TType) + - filter_value - 1; + + while (1) + { + const std::type_info* catch_type; + _Unwind_Word tmp; + + tmp = *e; + + // Zero signals the end of the list. If we've not found + // a match by now, then we've failed the specification. + if (tmp == 0) + return false; + + tmp = _Unwind_decode_target2((_Unwind_Word) e); + + // Match a ttype entry. + catch_type = reinterpret_cast(tmp); + + // ??? There is currently no way to ask the RTTI code about the + // relationship between two types without reference to a specific + // object. There should be; then we wouldn't need to mess with + // thrown_ptr here. + if (get_adjusted_ptr(catch_type, throw_type, &thrown_ptr)) + return true; + + // Advance to the next entry. + e++; + } +} + + +// Save stage1 handler information in the exception object + +static inline void +save_caught_exception(struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context, + void* thrown_ptr, + int handler_switch_value, + const unsigned char* language_specific_data, + _Unwind_Ptr landing_pad, + const unsigned char* action_record + __attribute__((__unused__))) +{ + ue_header->barrier_cache.sp = _Unwind_GetGR(context, 13); + ue_header->barrier_cache.bitpattern[0] = (_uw) thrown_ptr; + ue_header->barrier_cache.bitpattern[1] + = (_uw) handler_switch_value; + ue_header->barrier_cache.bitpattern[2] + = (_uw) language_specific_data; + ue_header->barrier_cache.bitpattern[3] = (_uw) landing_pad; +} + + +// Restore the catch handler data saved during phase1. + +static inline void +restore_caught_exception(struct _Unwind_Exception* ue_header, + int& handler_switch_value, + const unsigned char*& language_specific_data, + _Unwind_Ptr& landing_pad) +{ + handler_switch_value = (int) ue_header->barrier_cache.bitpattern[1]; + language_specific_data = + (const unsigned char*) ue_header->barrier_cache.bitpattern[2]; + landing_pad = (_Unwind_Ptr) ue_header->barrier_cache.bitpattern[3]; +} + +#define CONTINUE_UNWINDING \ + do \ + { \ + if (__gnu_unwind_frame(ue_header, context) != _URC_OK) \ + return _URC_FAILURE; \ + return _URC_CONTINUE_UNWIND; \ + } \ + while (0) + +#else +// APPLE LOCAL end LLVM +typedef const std::type_info _throw_typet; + + +// Return an element from a type table. + static const std::type_info * get_ttype_entry (lsda_header_info *info, _Unwind_Word i) { @@ -127,8 +246,10 @@ // Return true if THROW_TYPE matches one if the filter types. static bool -check_exception_spec (lsda_header_info *info, const std::type_info *throw_type, - void *thrown_ptr, _Unwind_Sword filter_value) +// APPLE LOCAL begin LLVM +check_exception_spec(lsda_header_info* info, _throw_typet* throw_type, + void* thrown_ptr, _Unwind_Sword filter_value) +// APPLE LOCAL end LLVM { const unsigned char *e = info->TType - filter_value - 1; @@ -156,6 +277,52 @@ } } + +// APPLE LOCAL begin LLVM +// Save stage1 handler information in the exception object + +static inline void +save_caught_exception(struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context + __attribute__((__unused__)), + void* thrown_ptr, + int handler_switch_value, + const unsigned char* language_specific_data, + _Unwind_Ptr landing_pad __attribute__((__unused__)), + const unsigned char* action_record) +{ + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + + xh->handlerSwitchValue = handler_switch_value; + xh->actionRecord = action_record; + xh->languageSpecificData = language_specific_data; + xh->adjustedPtr = thrown_ptr; + + // ??? Completely unknown what this field is supposed to be for. + // ??? Need to cache TType encoding base for call_unexpected. + xh->catchTemp = landing_pad; +} + + +// Restore the catch handler information saved during phase1. + +static inline void +restore_caught_exception(struct _Unwind_Exception* ue_header, + int& handler_switch_value, + const unsigned char*& language_specific_data, + _Unwind_Ptr& landing_pad) +{ + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + handler_switch_value = xh->handlerSwitchValue; + language_specific_data = xh->languageSpecificData; + landing_pad = (_Unwind_Ptr) xh->catchTemp; +} + +#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND + +#endif // !__ARM_EABI_UNWINDER__ +// APPLE LOCAL end LLVM + // Return true if the filter spec is empty, ie throw(). static bool @@ -178,14 +345,20 @@ #endif extern "C" _Unwind_Reason_Code +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ +PERSONALITY_FUNCTION (_Unwind_State state, + struct _Unwind_Exception* ue_header, + struct _Unwind_Context* context) +#else +// APPLE LOCAL end LLVM PERSONALITY_FUNCTION (int version, _Unwind_Action actions, _Unwind_Exception_Class exception_class, struct _Unwind_Exception *ue_header, struct _Unwind_Context *context) +#endif { - __cxa_exception *xh = __get_exception_header_from_ue (ue_header); - enum found_handler_type { found_nothing, @@ -200,19 +373,66 @@ const unsigned char *p; _Unwind_Ptr landing_pad, ip; int handler_switch_value; - void *thrown_ptr = xh + 1; +// APPLE LOCAL begin LLVM + void* thrown_ptr = ue_header + 1; + bool foreign_exception; +#ifdef __ARM_EABI_UNWINDER__ + _Unwind_Action actions; + + switch (state) + { + case _US_VIRTUAL_UNWIND_FRAME: + actions = _UA_SEARCH_PHASE; + break; + + case _US_UNWIND_FRAME_STARTING: + actions = _UA_CLEANUP_PHASE; + if (ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13)) + actions |= _UA_HANDLER_FRAME; + break; + + case _US_UNWIND_FRAME_RESUME: + CONTINUE_UNWINDING; + break; + + default: + abort(); + } + + // We don't know which runtime we're working with, so can't check this. + // However the ABI routines hide this from us, and we don't actually need + // to know. + foreign_exception = false; + + // The dwarf unwinder assumes the context structure holds things like the + // function and LSDA pointers. The ARM implementation caches these in + // the exception header (UCB). To avoid rewriting everything we make the + // virtual IP register point at the UCB. + ip = (_Unwind_Ptr) ue_header; + _Unwind_SetGR(context, 12, ip); +#else + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); +// APPLE LOCAL end LLVM + // Interface version check. if (version != 1) return _URC_FATAL_PHASE1_ERROR; +// APPLE LOCAL begin LLVM + foreign_exception = !__is_gxx_exception_class(exception_class); +#endif +// APPLE LOCAL end LLVM // Shortcut for phase 2 found handler for domestic exception. +// APPLE LOCAL begin LLVM if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) - && exception_class == __gxx_exception_class) + && !foreign_exception) +// APPLE LOCAL end LLVM { - handler_switch_value = xh->handlerSwitchValue; - language_specific_data = xh->languageSpecificData; - landing_pad = (_Unwind_Ptr) xh->catchTemp; +// APPLE LOCAL begin LLVM + restore_caught_exception(ue_header, handler_switch_value, + language_specific_data, landing_pad); +// APPLE LOCAL end LLVM found_type = (landing_pad == 0 ? found_terminate : found_handler); goto install_context; } @@ -222,11 +442,15 @@ // If no LSDA, then there are no handlers or cleanups. if (! language_specific_data) - return _URC_CONTINUE_UNWIND; +// APPLE LOCAL begin LLVM + CONTINUE_UNWINDING; +// APPLE LOCAL end LLVM // Parse the LSDA header. p = parse_lsda_header (context, language_specific_data, &info); - info.ttype_base = base_of_encoded_value (info.ttype_encoding, context); +// APPLE LOCAL begin LLVM + info.ttype_base = 0; +// APPLE LOCAL end LLVM ip = _Unwind_GetIP (context) - 1; landing_pad = 0; action_record = 0; @@ -312,7 +536,10 @@ // Otherwise we have a catch handler or exception specification. _Unwind_Sword ar_filter, ar_disp; - const std::type_info *throw_type, *catch_type; +// APPLE LOCAL begin LLVM + const std::type_info* catch_type; + _throw_typet* throw_type; +// APPLE LOCAL end LLVM bool saw_cleanup = false; bool saw_handler = false; @@ -320,11 +547,21 @@ // exception class, there's no exception type. // ??? What to do about GNU Java and GNU Ada exceptions. +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ + throw_type = ue_header; +#else +// APPLE LOCAL end LLVM if ((actions & _UA_FORCE_UNWIND) - || exception_class != __gxx_exception_class) +// APPLE LOCAL begin LLVM + || foreign_exception) +// APPLE LOCAL end LLVM throw_type = 0; else throw_type = xh->exceptionType; +// APPLE LOCAL begin LLVM +#endif +// APPLE LOCAL end LLVM while (1) { @@ -387,34 +624,41 @@ do_something: if (found_type == found_nothing) - return _URC_CONTINUE_UNWIND; +// APPLE LOCAL begin LLVM + CONTINUE_UNWINDING; +// APPLE LOCAL end LLVM if (actions & _UA_SEARCH_PHASE) { if (found_type == found_cleanup) - return _URC_CONTINUE_UNWIND; +// APPLE LOCAL begin LLVM + CONTINUE_UNWINDING; +// APPLE LOCAL end LLVM // For domestic exceptions, we cache data from phase 1 for phase 2. - if (exception_class == __gxx_exception_class) +// APPLE LOCAL begin LLVM + if (!foreign_exception) { - xh->handlerSwitchValue = handler_switch_value; - xh->actionRecord = action_record; - xh->languageSpecificData = language_specific_data; - xh->adjustedPtr = thrown_ptr; - - // ??? Completely unknown what this field is supposed to be for. - // ??? Need to cache TType encoding base for call_unexpected. - xh->catchTemp = landing_pad; + save_caught_exception(ue_header, context, thrown_ptr, + handler_switch_value, language_specific_data, + landing_pad, action_record); } +//APPLE LOCAL end LLVM return _URC_HANDLER_FOUND; } install_context: + +// APPLE LOCAL begin LLVM +#ifndef __ARM_EABI_UNWINDER__ +// APPLE LOCAL end LLVM // We can't use any of the cxa routines with foreign exceptions, // because they all expect ue_header to be a struct __cxa_exception. // So in that case, call terminate or unexpected directly. if ((actions & _UA_FORCE_UNWIND) - || exception_class != __gxx_exception_class) +// APPLE LOCAL begin LLVM + || foreign_exception) +// APPLE LOCAL end LLVM { if (found_type == found_terminate) std::terminate (); @@ -427,32 +671,74 @@ } } else +// APPLE LOCAL begin LLVM +#endif +// APPLE LOCAL end LLVM { if (found_type == found_terminate) - { - __cxa_begin_catch (&xh->unwindHeader); - __terminate (xh->terminateHandler); - } +// APPLE LOCAL begin LLVM + __cxa_call_terminate(ue_header); +// APPLE LOCAL end LLVM // Cache the TType base value for __cxa_call_unexpected, as we won't // have an _Unwind_Context then. if (handler_switch_value < 0) { parse_lsda_header (context, language_specific_data, &info); + +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ + const _Unwind_Word* e; + _Unwind_Word n; + + e = ((const _Unwind_Word*) info.TType) - handler_switch_value - 1; + // Count the number of rtti objects. + n = 0; + while (e[n] != 0) + n++; + + // Count. + ue_header->barrier_cache.bitpattern[1] = n; + // Base (obsolete) + ue_header->barrier_cache.bitpattern[2] = 0; + // Stride. + ue_header->barrier_cache.bitpattern[3] = 4; + // List head. + ue_header->barrier_cache.bitpattern[4] = (_Unwind_Word) e; +#else +// APPLE LOCAL end LLVM xh->catchTemp = base_of_encoded_value (info.ttype_encoding, context); +// APPLE LOCAL begin LLVM +#endif +// APPLE LOCAL end LLVM } } /* For targets with pointers smaller than the word size, we must extend the pointer, and this extension is target dependent. */ _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), - __builtin_extend_pointer (&xh->unwindHeader)); +// APPLE LOCAL begin LLVM + __builtin_extend_pointer (ue_header)); +// APPLE LOCAL end LLVM _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), handler_switch_value); _Unwind_SetIP (context, landing_pad); +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ + if (found_type == found_cleanup) + __cxa_begin_cleanup(ue_header); +#endif +// APPLE LOCAL end LLVM return _URC_INSTALL_CONTEXT; } +// APPLE LOCAL begin LLVM +/* The ARM EABI implementation of __cxa_call_unexpected is in a different + file so that the personality routine san be used standalone. The generic + routine sahred datastructures with the PR so it is most convenient to + implement it here. */ +#ifndef __ARM_EABI_UNWINDER__ +// APPLE LOCAL end LLVM extern "C" void __cxa_call_unexpected (void *exc_obj_in) { @@ -507,9 +793,12 @@ const std::type_info &bad_exc = typeid (std::bad_exception); if (check_exception_spec (&info, &bad_exc, 0, xh_switch_value)) throw std::bad_exception(); +// APPLE LOCAL begin LLVM #endif +// APPLE LOCAL end LLVM // Otherwise, die. __terminate (xh_terminate_handler); } } +#endif Modified: apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_throw.cc =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_throw.cc 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_throw.cc 2007-04-03 00:10:47 UTC (rev 125637) @@ -63,7 +63,9 @@ header->exceptionDestructor = dest; header->unexpectedHandler = __unexpected_handler; header->terminateHandler = __terminate_handler; - header->unwindHeader.exception_class = __gxx_exception_class; +// APPLE LOCAL begin LLVM + __GXX_INIT_EXCEPTION_CLASS(header->unwindHeader.exception_class); +// APPLE LOCAL end LLVM header->unwindHeader.exception_cleanup = __gxx_exception_cleanup; #ifdef _GLIBCXX_SJLJ_EXCEPTIONS @@ -89,7 +91,9 @@ if (header) { // Tell __cxa_end_catch this is a rethrow. - if (header->unwindHeader.exception_class != __gxx_exception_class) +// APPLE LOCAL begin LLVM + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) +// APPLE LOCAL end LLVM globals->caughtExceptions = 0; else header->handlerCount = -header->handlerCount; @@ -97,7 +101,9 @@ #ifdef _GLIBCXX_SJLJ_EXCEPTIONS _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader); #else -#ifdef _LIBUNWIND_STD_ABI +// APPLE LOCAL begin LLVM +#if defined(_LIBUNWIND_STD_ABI) || defined (__ARM_EABI_UNWINDER__) +// APPLE LOCAL end LLVM _Unwind_RaiseException (&header->unwindHeader); #else _Unwind_Resume_or_Rethrow (&header->unwindHeader); Modified: apple-local/branches/llvm/libstdc++-v3/libsupc++/unwind-cxx.h =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libsupc++/unwind-cxx.h 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/libsupc++/unwind-cxx.h 2007-04-03 00:10:47 UTC (rev 125637) @@ -67,6 +67,15 @@ // value is a signal that this object has been rethrown. int handlerCount; +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ + // Stack of exceptions in cleanups. + __cxa_exception* nextPropagatingException; + + // The nuber of active cleanup handlers for this exception. + int propagationCount; +#else +// APPLE LOCAL end LLVM // Cache parsed handler data from the personality routine Phase 1 // for Phase 2 and __cxa_call_unexpected. int handlerSwitchValue; @@ -74,6 +83,9 @@ const unsigned char *languageSpecificData; _Unwind_Ptr catchTemp; void *adjustedPtr; +// APPLE LOCAL begin LLVM +#endif +// APPLE LOCAL end LLVM // The generic exception header. Must be last. _Unwind_Exception unwindHeader; @@ -84,6 +96,11 @@ { __cxa_exception *caughtExceptions; unsigned int uncaughtExceptions; +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ + __cxa_exception* propagatingExceptions; +#endif +// APPLE LOCAL end LLVM }; @@ -122,7 +139,25 @@ // throws, and if bad_exception needs to be thrown. Called from the // compiler. extern "C" void __cxa_call_unexpected (void *) __attribute__((noreturn)); +// APPLE LOCAL begin LLVM +extern "C" void __cxa_call_terminate (void*) __attribute__((noreturn)); +// APPLE LOCAL end LLVM +// APPLE LOCAL begin LLVM +#ifdef __ARM_EABI_UNWINDER__ +// Arm EABI specified routines. +typedef enum { + ctm_failed = 0, + ctm_succeeded = 1, + ctm_succeeded_with_ptr_to_base = 2 +} __cxa_type_match_result; +extern "C" bool __cxa_type_match(_Unwind_Exception*, const std::type_info*, + bool, void**); +extern "C" void __cxa_begin_cleanup (_Unwind_Exception*); +extern "C" void __cxa_end_cleanup (void); +#endif +// APPLE LOCAL end LLVM + // Invokes given handler, dying appropriately if the user handler was // so inconsiderate as to return. extern void __terminate(std::terminate_handler) __attribute__((noreturn)); @@ -134,6 +169,56 @@ // These are explicitly GNU C++ specific. +// APPLE LOCAL begin LLVM +// Acquire the C++ exception header from the C++ object. +static inline __cxa_exception * +__get_exception_header_from_obj (void *ptr) +{ + return reinterpret_cast<__cxa_exception *>(ptr) - 1; +} + +// Acquire the C++ exception header from the generic exception header. +static inline __cxa_exception * +__get_exception_header_from_ue (_Unwind_Exception *exc) +{ + return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; +} + +#ifdef __ARM_EABI_UNWINDER__ +static inline bool +__is_gxx_exception_class(_Unwind_Exception_Class c) +{ + // TODO: Take advantage of the fact that c will always be word aligned. + return c[0] == 'G' + && c[1] == 'N' + && c[2] == 'U' + && c[3] == 'C' + && c[4] == 'C' + && c[5] == '+' + && c[6] == '+' + && c[7] == '\0'; +} + +static inline void +__GXX_INIT_EXCEPTION_CLASS(_Unwind_Exception_Class c) +{ + c[0] = 'G'; + c[1] = 'N'; + c[2] = 'U'; + c[3] = 'C'; + c[4] = 'C'; + c[5] = '+'; + c[6] = '+'; + c[7] = '\0'; +} + +static inline void* +__gxx_caught_object(_Unwind_Exception* eo) +{ + return (void*)eo->barrier_cache.bitpattern[0]; +} +#else // !__ARM_EABI_UNWINDER__ +// APPLE LOCAL end LLVM // This is the exception class we report -- "GNUCC++\0". const _Unwind_Exception_Class __gxx_exception_class = ((((((((_Unwind_Exception_Class) 'G' @@ -145,6 +230,16 @@ << 8 | (_Unwind_Exception_Class) '+') << 8 | (_Unwind_Exception_Class) '\0'); +// APPLE LOCAL begin LLVM +static inline bool +__is_gxx_exception_class(_Unwind_Exception_Class c) +{ + return c == __gxx_exception_class; +} + +#define __GXX_INIT_EXCEPTION_CLASS(c) c = __gxx_exception_class +// APPLE LOCAL end LLVM + // GNU C++ personality routine, Version 0. extern "C" _Unwind_Reason_Code __gxx_personality_v0 (int, _Unwind_Action, _Unwind_Exception_Class, @@ -155,20 +250,16 @@ (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, struct _Unwind_Context *); -// Acquire the C++ exception header from the C++ object. -static inline __cxa_exception * -__get_exception_header_from_obj (void *ptr) +// APPLE LOCAL begin LLVM +static inline void* +__gxx_caught_object(_Unwind_Exception* eo) { - return reinterpret_cast<__cxa_exception *>(ptr) - 1; + __cxa_exception* header = __get_exception_header_from_ue (eo); + return header->adjustedPtr; } +#endif // !__ARM_EABI_UNWINDER__ +// APPLE LOCAL end LLVM -// Acquire the C++ exception header from the generic exception header. -static inline __cxa_exception * -__get_exception_header_from_ue (_Unwind_Exception *exc) -{ - return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; -} - } /* namespace __cxxabiv1 */ #pragma GCC visibility pop Modified: apple-local/branches/llvm/libstdc++-v3/po/Makefile.in =================================================================== --- apple-local/branches/llvm/libstdc++-v3/po/Makefile.in 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/po/Makefile.in 2007-04-03 00:10:47 UTC (rev 125637) @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. Modified: apple-local/branches/llvm/libstdc++-v3/src/Makefile.in =================================================================== --- apple-local/branches/llvm/libstdc++-v3/src/Makefile.in 2007-04-02 21:58:58 UTC (rev 125636) +++ apple-local/branches/llvm/libstdc++-v3/src/Makefile.in 2007-04-03 00:10:47 UTC (rev 125637) @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. From sabre at nondot.org Mon Apr 2 19:13:33 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 19:13:33 -0500 Subject: [llvm-commits] CVS: llvm/test/CodeGen/ARM/arm-negative-stride.ll Message-ID: <200704030013.l330DXNQ030767@zion.cs.uiuc.edu> Changes in directory llvm/test/CodeGen/ARM: arm-negative-stride.ll added (r1.1) --- Log message: new testcase, where we should use a negative stride --- Diffs of the changes: (+20 -0) arm-negative-stride.ll | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+) Index: llvm/test/CodeGen/ARM/arm-negative-stride.ll diff -c /dev/null llvm/test/CodeGen/ARM/arm-negative-stride.ll:1.1 *** /dev/null Mon Apr 2 19:13:26 2007 --- llvm/test/CodeGen/ARM/arm-negative-stride.ll Mon Apr 2 19:13:16 2007 *************** *** 0 **** --- 1,20 ---- + ; RUN: llvm-as < %s | llc -march=arm | grep -F 'str r1, [r3, -r0, lsl #2]' + + define void @test(i32* %P, i32 %A, i32 %i) { + entry: + icmp eq i32 %i, 0 ; :0 [#uses=1] + br i1 %0, label %return, label %bb + + bb: ; preds = %bb, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; [#uses=2] + %i_addr.09.0 = sub i32 %i, %indvar ; [#uses=1] + %tmp2 = getelementptr i32* %P, i32 %i_addr.09.0 ; [#uses=1] + store i32 %A, i32* %tmp2 + %indvar.next = add i32 %indvar, 1 ; [#uses=2] + icmp eq i32 %indvar.next, %i ; :1 [#uses=1] + br i1 %1, label %return, label %bb + + return: ; preds = %bb, %entry + ret void + } + From johannes at apple.com Mon Apr 2 19:13:00 2007 From: johannes at apple.com (johannes at apple.com) Date: Mon, 2 Apr 2007 17:13:00 -0700 (PDT) Subject: [llvm-commits] [125638] arm EABI patch (Lauro Ramos Venancio) Message-ID: <20070403001300.D6582CB80647@src> Revision: 125638 Author: johannes Date: 2007-04-02 17:13:00 -0700 (Mon, 02 Apr 2007) Log Message: ----------- arm EABI patch (Lauro Ramos Venancio) Modified Paths: -------------- apple-local/branches/llvm/gcc/Makefile.in apple-local/branches/llvm/gcc/ada/misc.c apple-local/branches/llvm/gcc/c-decl.c apple-local/branches/llvm/gcc/config/arm/arm.c apple-local/branches/llvm/gcc/config/arm/arm.h apple-local/branches/llvm/gcc/config/arm/bpabi.h apple-local/branches/llvm/gcc/config/arm/elf.h apple-local/branches/llvm/gcc/config/arm/lib1funcs.asm apple-local/branches/llvm/gcc/config/arm/libgcc-bpabi.ver apple-local/branches/llvm/gcc/config/arm/t-bpabi apple-local/branches/llvm/gcc/config/arm/t-symbian apple-local/branches/llvm/gcc/config/i386/t-netware apple-local/branches/llvm/gcc/config/ia64/ia64.h apple-local/branches/llvm/gcc/cp/Make-lang.in apple-local/branches/llvm/gcc/cp/decl.c apple-local/branches/llvm/gcc/cp/except.c apple-local/branches/llvm/gcc/except.c apple-local/branches/llvm/gcc/except.h apple-local/branches/llvm/gcc/java/decl.c apple-local/branches/llvm/gcc/objc/objc-act.c apple-local/branches/llvm/gcc/optabs.c apple-local/branches/llvm/gcc/opts.c apple-local/branches/llvm/gcc/target-def.h apple-local/branches/llvm/gcc/target.h apple-local/branches/llvm/gcc/unwind-c.c Modified: apple-local/branches/llvm/gcc/Makefile.in =================================================================== --- apple-local/branches/llvm/gcc/Makefile.in 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/Makefile.in 2007-04-03 00:13:00 UTC (rev 125638) @@ -340,10 +340,11 @@ $(srcdir)/ginclude/stddef.h \ $(srcdir)/ginclude/tgmath.h \ $(srcdir)/ginclude/varargs.h \ - $(srcdir)/unwind.h \ $(EXTRA_HEADERS) # APPLE LOCAL end radar 2872232 add tgmath.h +UNWIND_H = $(srcdir)/unwind-generic.h + # The GCC to use for compiling libgcc.a and crt*.o. # Usually the one we just built. # Don't use this as a dependency--use $(GCC_PASSES) or $(GCC_PARTS). @@ -582,7 +583,7 @@ $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c LIB2ADDEHSTATIC = $(LIB2ADDEH) LIB2ADDEHSHARED = $(LIB2ADDEH) -LIB2ADDEHDEP = unwind.h unwind-pe.h unwind.inc unwind-dw2-fde.h unwind-dw2.h +LIB2ADDEHDEP = $(UNWIND_H) unwind-pe.h unwind.inc unwind-dw2-fde.h unwind-dw2.h # Don't build libunwind by default. LIBUNWIND = @@ -3129,7 +3130,7 @@ # be rebuilt. # Build the include directory -stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) xlimits.h +stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) xlimits.h $(UNWIND_H) # Copy in the headers provided with gcc. # The sed command gets just the last file name component; # this is necessary because VPATH could add a dirname. @@ -3147,6 +3148,7 @@ done rm -f include/limits.h cp xlimits.h include/limits.h + cp $(UNWIND_H) include/unwind.h chmod a+r include/limits.h # Install the README rm -f include/README @@ -3772,6 +3774,7 @@ $(DESTDIR)$(itoolsdatadir)/include/$$realfile ; \ done $(INSTALL_DATA) xlimits.h $(DESTDIR)$(itoolsdatadir)/include/limits.h + $(INSTALL_DATA) $(UNWIND_H) $(DESTDIR)$(itoolsdatadir)/include/unwind.h $(INSTALL_DATA) $(srcdir)/gsyslimits.h \ $(DESTDIR)$(itoolsdatadir)/gsyslimits.h $(INSTALL_DATA) macro_list $(DESTDIR)$(itoolsdatadir)/macro_list Modified: apple-local/branches/llvm/gcc/ada/misc.c =================================================================== --- apple-local/branches/llvm/gcc/ada/misc.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/ada/misc.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -478,6 +478,9 @@ using_eh_for_cleanups (); eh_personality_libfunc = init_one_libfunc ("__gnat_eh_personality"); + /* APPLE LOCAL begin LLVM */ + default_init_unwind_resume_libfunc (); + /* APPLE LOCAL end LLVM */ lang_eh_type_covers = gnat_eh_type_covers; lang_eh_runtime_type = gnat_eh_runtime_type; Modified: apple-local/branches/llvm/gcc/c-decl.c =================================================================== --- apple-local/branches/llvm/gcc/c-decl.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/c-decl.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -3765,6 +3765,9 @@ = init_one_libfunc (USING_SJLJ_EXCEPTIONS ? "__gcc_personality_sj0" : "__gcc_personality_v0"); + /* APPLE LOCAL begin LLVM */ + default_init_unwind_resume_libfunc (); + /* APPLE LOCAL end LLVM */ using_eh_for_cleanups (); } Modified: apple-local/branches/llvm/gcc/config/arm/arm.c =================================================================== --- apple-local/branches/llvm/gcc/config/arm/arm.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/arm/arm.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -171,6 +171,14 @@ static bool arm_promote_prototypes (tree); static bool arm_default_short_enums (void); static bool arm_align_anon_bitfield (void); +/* APPLE LOCAL begin LLVM */ +static bool arm_return_in_msb (tree); +static bool arm_must_pass_in_stack (enum machine_mode, tree); +#ifdef TARGET_UNWIND_INFO +static void arm_unwind_emit (FILE *, rtx); +static bool arm_output_ttype (rtx); +#endif +/* APPLE LOCAL end LLVM */ static tree arm_cxx_guard_type (void); static bool arm_cxx_guard_mask_bit (void); @@ -182,6 +190,9 @@ static void arm_cxx_determine_class_data_visibility (tree); static bool arm_cxx_class_data_always_comdat (void); /* APPLE LOCAL end mainline 4.2 2006-03-01 4311680 */ +/* APPLE LOCAL begin LLVM */ +static bool arm_cxx_use_aeabi_atexit (void); +/* APPLE LOCAL end LLVM */ static void arm_init_libfuncs (void); static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode); @@ -325,6 +336,30 @@ #define TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT arm_cxx_class_data_always_comdat /* APPLE LOCAL end mainline 4.2 2006-03-01 4311680 */ + +/* APPLE LOCAL begin LLVM */ +#undef TARGET_CXX_USE_AEABI_ATEXIT +#define TARGET_CXX_USE_AEABI_ATEXIT arm_cxx_use_aeabi_atexit + +#undef TARGET_RETURN_IN_MSB +#define TARGET_RETURN_IN_MSB arm_return_in_msb + +#undef TARGET_MUST_PASS_IN_STACK +#define TARGET_MUST_PASS_IN_STACK arm_must_pass_in_stack + +#ifdef TARGET_UNWIND_INFO +#undef TARGET_UNWIND_EMIT +#define TARGET_UNWIND_EMIT arm_unwind_emit + +/* EABI unwinding tables use a different format for the typeinfo tables. */ +#undef TARGET_ASM_TTYPE +#define TARGET_ASM_TTYPE arm_output_ttype + +#undef TARGET_ARM_EABI_UNWINDER +#define TARGET_ARM_EABI_UNWINDER true +#endif /* TARGET_UNWIND_INFO */ +/* APPLE LOCAL end LLVM */ + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -2316,11 +2351,25 @@ int unsignedp ATTRIBUTE_UNUSED; rtx r ATTRIBUTE_UNUSED; - mode = TYPE_MODE (type); /* Promote integer types. */ if (INTEGRAL_TYPE_P (type)) PROMOTE_FUNCTION_MODE (mode, unsignedp, type); + + /* APPLE LOCAL begin LLVM */ + /* Promotes small structs returned in a register to full-word size + for big-endian AAPCS. */ + if (arm_return_in_msb (type)) + { + HOST_WIDE_INT size = int_size_in_bytes (type); + if (size % UNITS_PER_WORD != 0) + { + size += UNITS_PER_WORD - size % UNITS_PER_WORD; + mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0); + } + } + /* APPLE LOCAL end LLVM */ + return LIBCALL_VALUE(mode); } @@ -4886,7 +4935,20 @@ return GENERAL_REGS; } +/* APPLE LOCAL begin LLVM */ +/* Values which must be returned in the most-significant end of the return + register. */ +static bool +arm_return_in_msb (tree valtype) +{ + return (TARGET_AAPCS_BASED + && BYTES_BIG_ENDIAN + && (AGGREGATE_TYPE_P (valtype) + || TREE_CODE (valtype) == COMPLEX_TYPE)); +} +/* APPLE LOCAL end LLVM */ + /* Returns TRUE if INSN is an "LDR REG, ADDR" instruction. Use by the Cirrus Maverick code which has to workaround a hardware bug triggered by such instructions. */ @@ -6462,6 +6524,60 @@ gen_lowpart (QImode, scratch))); } } + +/* APPLE LOCAL begin LLVM */ +/* Return true if a type must be passed in memory. For AAPCS, small aggregates + (padded to the size of a word) should be passed in a register. */ + +static bool +arm_must_pass_in_stack (enum machine_mode mode, tree type) +{ + if (TARGET_AAPCS_BASED) + return must_pass_in_stack_var_size (mode, type); + else + return must_pass_in_stack_var_size_or_pad (mode, type); +} + + +/* For use by FUNCTION_ARG_PADDING (MODE, TYPE). + Return true if an argument passed on the stack should be padded upwards, + i.e. if the least-significant byte has useful data. */ + +bool +arm_pad_arg_upward (enum machine_mode mode, tree type) +{ + if (!TARGET_AAPCS_BASED) + return DEFAULT_FUNCTION_ARG_PADDING(mode, type); + + if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type)) + return false; + + return true; +} + + +/* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST). + For non-AAPCS, return !BYTES_BIG_ENDIAN if the least significant + byte of the register has useful data, and return the opposite if the + most significant byte does. + For AAPCS, small aggregates and small complex types are always padded + upwards. */ + +bool +arm_pad_reg_upward (enum machine_mode mode ATTRIBUTE_UNUSED, + tree type, int first ATTRIBUTE_UNUSED) +{ + if (TARGET_AAPCS_BASED + && BYTES_BIG_ENDIAN + && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE) + && int_size_in_bytes (type) <= 4) + return true; + + /* Otherwise, use default padding. */ + return !BYTES_BIG_ENDIAN; +} +/* APPLE LOCAL end LLVM */ + /* Print a symbolic form of X to the debug file, F. */ static void @@ -12690,6 +12806,23 @@ return; } + /* APPLE LOCAL begin LLVM */ + if (ARM_EABI_UNWIND_TABLES && push) + { + fprintf (f, "\t.save\t{"); + for (regno = 0; regno < 15; regno++) + { + if (real_regs & (1 << regno)) + { + if (real_regs & ((1 << regno) -1)) + fprintf (f, ", "); + asm_fprintf (f, "%r", regno); + } + } + fprintf (f, "}\n"); + } + /* APPLE LOCAL end LLVM */ + fprintf (f, "\t%s\t{", push ? "push" : "pop"); /* Look at the low registers first. */ @@ -13374,6 +13507,13 @@ if (current_function_pretend_args_size) { + /* APPLE LOCAL begin LLVM */ + /* Output unwind directive for the stack adjustment. */ + if (ARM_EABI_UNWIND_TABLES) + fprintf (f, "\t.pad #%d\n", + current_function_pretend_args_size); + /* APPLE LOCAL end LLVM */ + if (cfun->machine->uses_anonymous_args) { int num_pushes; @@ -13435,6 +13575,11 @@ work_register = thumb_find_work_register (live_regs_mask); + /* APPLE LOCAL begin LLVM */ + if (ARM_EABI_UNWIND_TABLES) + asm_fprintf (f, "\t.pad #16\n"); + /* APPLE LOCAL end LLVM */ + asm_fprintf (f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n", SP_REGNUM, SP_REGNUM); @@ -14511,6 +14656,14 @@ /* APPLE LOCAL end mainline 4.2 2006-03-01 4311680 */ } +/* APPLE LOCAL begin LLVM */ +static bool +arm_cxx_use_aeabi_atexit (void) +{ + return TARGET_AAPCS_BASED; +} +/* APPLE LOCAL end LLVM */ + void arm_set_return_address (rtx source, rtx scratch) { @@ -14624,3 +14777,290 @@ { return mode == SImode ? 255 : 0; } + + +/* APPLE LOCAL begin LLVM */ +/* Map internal gcc register numbers to DWARF2 register numbers. */ + +unsigned int +arm_dbx_register_number (unsigned int regno) +{ + if (regno < 16) + return regno; + + /* TODO: Legacy targets output FPA regs as registers 16-23 for backwards + compatibility. The EABI defines them as registers 96-103. */ + if (IS_FPA_REGNUM (regno)) + return (TARGET_AAPCS_BASED ? 96 : 16) + regno - FIRST_FPA_REGNUM; + + if (IS_VFP_REGNUM (regno)) + return 64 + regno - FIRST_VFP_REGNUM; + + if (IS_IWMMXT_GR_REGNUM (regno)) + return 104 + regno - FIRST_IWMMXT_GR_REGNUM; + + if (IS_IWMMXT_REGNUM (regno)) + return 112 + regno - FIRST_IWMMXT_REGNUM; + + abort (); +} + + +#ifdef TARGET_UNWIND_INFO +/* Emit unwind directives for a store-multiple instruction. This should + only ever be generated by the function prologue code, so we expect it + to have a particular form. */ + +static void +arm_unwind_emit_stm (FILE * asm_out_file, rtx p) +{ + int i; + HOST_WIDE_INT offset; + HOST_WIDE_INT nregs; + int reg_size; + unsigned reg; + unsigned lastreg; + rtx e; + + /* First insn will adjust the stack pointer. */ + e = XVECEXP (p, 0, 0); + if (GET_CODE (e) != SET + || GET_CODE (XEXP (e, 0)) != REG + || REGNO (XEXP (e, 0)) != SP_REGNUM + || GET_CODE (XEXP (e, 1)) != PLUS) + abort (); + + offset = -INTVAL (XEXP (XEXP (e, 1), 1)); + nregs = XVECLEN (p, 0) - 1; + + reg = REGNO (XEXP (XVECEXP (p, 0, 1), 1)); + if (reg < 16) + { + /* The function prologue may also push pc, but not annotate it as it is + never restored. We turn this into an stack pointer adjustment. */ + if (nregs * 4 == offset - 4) + { + fprintf (asm_out_file, "\t.pad #4\n"); + offset -= 4; + } + reg_size = 4; + } + else if (IS_VFP_REGNUM (reg)) + { + /* FPA register saves use an additional word. */ + offset -= 4; + reg_size = 8; + } + else if (reg >= FIRST_FPA_REGNUM && reg <= LAST_FPA_REGNUM) + { + /* FPA registers are done differently. */ + asm_fprintf (asm_out_file, "\t.save %r, %lld\n", reg, nregs); + return; + } + else + /* Unknown register type. */ + abort (); + + /* If the stack increment doesn't match the size of the saved registers, + something has gone horribly wrong. */ + if (offset != nregs * reg_size) + abort (); + + fprintf (asm_out_file, "\t.save {"); + + offset = 0; + lastreg = 0; + /* The remaining insns will describe the stores. */ + for (i = 1; i <= nregs; i++) + { + /* Expect (set (mem ) (reg)). + Where is (reg:SP) or (plus (reg:SP) (const_int)). */ + e = XVECEXP (p, 0, i); + if (GET_CODE (e) != SET + || GET_CODE (XEXP (e, 0)) != MEM + || GET_CODE (XEXP (e, 1)) != REG) + abort (); + + reg = REGNO (XEXP (e, 1)); + if (reg < lastreg) + abort (); + + if (i != 1) + fprintf (asm_out_file, ", "); + /* We can't use %r for vfp because we need to use the + double precision register names. */ + if (IS_VFP_REGNUM (reg)) + asm_fprintf (asm_out_file, "d%d", (reg - FIRST_VFP_REGNUM) / 2); + else + asm_fprintf (asm_out_file, "%r", reg); + +#ifdef ENABLE_CHECKING + /* Check that the addresses are consecutive. */ + e = XEXP (XEXP (e, 0), 0); + if (GET_CODE (e) == PLUS) + { + offset += reg_size; + if (GET_CODE (XEXP (e, 0)) != REG + || REGNO (XEXP (e, 0)) != SP_REGNUM + || GET_CODE (XEXP (e, 1)) != CONST_INT + || offset != INTVAL (XEXP (e, 1))) + abort (); + } + else if (i != 1 + || GET_CODE (e) != REG + || REGNO (e) != SP_REGNUM) + abort (); +#endif + } + fprintf (asm_out_file, "}\n"); +} + +/* Emit unwind directives for a SET. */ + +static void +arm_unwind_emit_set (FILE * asm_out_file, rtx p) +{ + rtx e0; + rtx e1; + + e0 = XEXP (p, 0); + e1 = XEXP (p, 1); + switch (GET_CODE (e0)) + { + case MEM: + /* Pushing a single register. */ + if (GET_CODE (XEXP (e0, 0)) != PRE_DEC + || GET_CODE (XEXP (XEXP (e0, 0), 0)) != REG + || REGNO (XEXP (XEXP (e0, 0), 0)) != SP_REGNUM) + abort (); + + asm_fprintf (asm_out_file, "\t.save "); + if (IS_VFP_REGNUM (REGNO (e1))) + asm_fprintf(asm_out_file, "{d%d}\n", + (REGNO (e1) - FIRST_VFP_REGNUM) / 2); + else + asm_fprintf(asm_out_file, "{%r}\n", REGNO (e1)); + break; + + case REG: + if (REGNO (e0) == SP_REGNUM) + { + /* A stack increment. */ + if (GET_CODE (e1) != PLUS + || GET_CODE (XEXP (e1, 0)) != REG + || REGNO (XEXP (e1, 0)) != SP_REGNUM + || GET_CODE (XEXP (e1, 1)) != CONST_INT) + abort (); + + asm_fprintf (asm_out_file, "\t.pad #%lld\n", + -INTVAL (XEXP (e1, 1))); + } + else if (REGNO (e0) == HARD_FRAME_POINTER_REGNUM) + { + HOST_WIDE_INT offset; + unsigned reg; + + if (GET_CODE (e1) == PLUS) + { + if (GET_CODE (XEXP (e1, 0)) != REG + || GET_CODE (XEXP (e1, 1)) != CONST_INT) + abort (); + reg = REGNO (XEXP (e1, 0)); + offset = INTVAL (XEXP (e1, 1)); + asm_fprintf (asm_out_file, "\t.setfp %r, %r, #%lld\n", + HARD_FRAME_POINTER_REGNUM, reg, + INTVAL (XEXP (e1, 1))); + } + else if (GET_CODE (e1) == REG) + { + reg = REGNO (e1); + asm_fprintf (asm_out_file, "\t.setfp %r, %r\n", + HARD_FRAME_POINTER_REGNUM, reg); + } + else + abort (); + } + else if (GET_CODE (e1) == REG && REGNO (e1) == SP_REGNUM) + { + /* Move from sp to reg. */ + asm_fprintf (asm_out_file, "\t.movsp %r\n", REGNO (e0)); + } + else + abort (); + break; + + default: + abort (); + } +} + + +/* Emit unwind directives for the given insn. */ + +static void +arm_unwind_emit (FILE * asm_out_file, rtx insn) +{ + rtx pat; + + if (!ARM_EABI_UNWIND_TABLES) + return; + + if (GET_CODE (insn) == NOTE || !RTX_FRAME_RELATED_P (insn)) + return; + + pat = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX); + if (pat) + pat = XEXP (pat, 0); + else + pat = PATTERN (insn); + + switch (GET_CODE (pat)) + { + case SET: + arm_unwind_emit_set (asm_out_file, pat); + break; + + case SEQUENCE: + /* Store multiple. */ + arm_unwind_emit_stm (asm_out_file, pat); + break; + + default: + abort(); + } +} + + +/* Output a reference from a function exception table to the type_info + object X. The EABI specifies that the symbol should be relocated by + an R_ARM_TARGET2 relocation. */ + +static bool +arm_output_ttype (rtx x) +{ + fputs ("\t.word\t", asm_out_file); + output_addr_const (asm_out_file, x); + /* Use special relocations for symbol references. */ + if (GET_CODE (x) != CONST_INT) + fputs ("(TARGET2)", asm_out_file); + fputc ('\n', asm_out_file); + + return TRUE; +} +#endif /* TARGET_UNWIND_INFO */ + + +/* Output unwind directives for the start/end of a function. */ + +void +arm_output_fn_unwind (FILE * f, bool prologue) +{ + if (!ARM_EABI_UNWIND_TABLES) + return; + + if (prologue) + fputs ("\t.fnstart\n", f); + else + fputs ("\t.fnend\n", f); +} +/* APPLE LOCAL end LLVM */ Modified: apple-local/branches/llvm/gcc/config/arm/arm.h =================================================================== --- apple-local/branches/llvm/gcc/config/arm/arm.h 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/arm/arm.h 2007-04-03 00:13:00 UTC (rev 125638) @@ -609,10 +609,13 @@ (MODE) = SImode; \ } +/* APPLE LOCAL begin LLVM */ #define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < 4) \ - (MODE) = SImode; \ + if ((GET_MODE_CLASS (MODE) == MODE_INT \ + || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT) \ + && GET_MODE_SIZE (MODE) < 4) \ + (MODE) = SImode; \ +/* APPLE LOCAL end LLVM */ /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */ @@ -992,8 +995,13 @@ #define FIRST_HI_REGNUM 8 #define LAST_HI_REGNUM 11 +/* APPLE LOCAL begin LLVM */ +#ifndef TARGET_UNWIND_INFO /* We use sjlj exceptions for backwards compatibility. */ #define MUST_USE_SJLJ_EXCEPTIONS 1 +#endif +/* APPLE LOCAL end LLVM */ + /* We can generate DWARF2 Unwind info, even though we don't use it. */ #define DWARF2_UNWIND_INFO 1 @@ -1041,6 +1049,10 @@ /* ARM floating pointer registers. */ #define FIRST_FPA_REGNUM 16 #define LAST_FPA_REGNUM 23 +/* APPLE LOCAL begin LLVM */ +#define IS_FPA_REGNUM(REGNUM) \ + (((REGNUM) >= FIRST_FPA_REGNUM) && ((REGNUM) <= LAST_FPA_REGNUM)) +/* APPLE LOCAL end LLVM */ #define FIRST_IWMMXT_GR_REGNUM 43 #define LAST_IWMMXT_GR_REGNUM 46 @@ -1073,6 +1085,10 @@ /* VFP adds 32 + 1 more. */ #define FIRST_PSEUDO_REGISTER 96 +/* APPLE LOCAL begin LLVM */ +#define DBX_REGISTER_NUMBER(REGNO) arm_dbx_register_number (REGNO) +/* APPLE LOCAL end LLVM */ + /* Value should be nonzero if functions must have frame pointers. Zero means the frame pointer need not be set up (and parms may be accessed via the stack pointer) in functions that seem suitable. @@ -1764,6 +1780,19 @@ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED)) +/* APPLE LOCAL begin LLVM */ +#define FUNCTION_ARG_PADDING(MODE, TYPE) \ + (arm_pad_arg_upward (MODE, TYPE) ? upward : downward) + +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ + (arm_pad_reg_upward (MODE, TYPE, FIRST) ? upward : downward) + +/* For AAPCS, padding should never be below the argument. For other ABIs, + * mimic the default. */ +#define PAD_VARARGS_DOWN \ + ((TARGET_AAPCS_BASED) ? 0 : BYTES_BIG_ENDIAN) +/* APPLE LOCAL end LLVM */ + /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. For a library call, FNTYPE is 0. @@ -2128,6 +2157,17 @@ if (!TARGET_LONG_CALLS || ! DECL_SECTION_NAME (DECL)) \ arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR) +/* APPLE LOCAL begin LLVM */ +#define ARM_OUTPUT_FN_UNWIND(F, PROLOGUE) arm_output_fn_unwind (F, PROLOGUE) + +#ifdef TARGET_UNWIND_INFO +#define ARM_EABI_UNWIND_TABLES \ + ((!USING_SJLJ_EXCEPTIONS && flag_exceptions) || flag_unwind_tables) +#else +#define ARM_EABI_UNWIND_TABLES 0 +#endif +/* APPLE LOCAL end LLVM */ + /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. We have two alternate definitions for each of them. Modified: apple-local/branches/llvm/gcc/config/arm/bpabi.h =================================================================== --- apple-local/branches/llvm/gcc/config/arm/bpabi.h 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/arm/bpabi.h 2007-04-03 00:13:00 UTC (rev 125638) @@ -26,6 +26,11 @@ /* Assume that AAPCS ABIs should adhere to the full BPABI. */ #define TARGET_BPABI (TARGET_AAPCS_BASED) +/* APPLE LOCAL begin LLVM */ +/* BPABI targets use EABI frame unwinding tables. */ +#define TARGET_UNWIND_INFO 1 +/* APPLE LOCAL end LLVM */ + /* Section 4.1 of the AAPCS requires the use of VFP format. */ /* APPLE LOCAL begin LLVM */ #undef FPUTYPE_DEFAULT Modified: apple-local/branches/llvm/gcc/config/arm/elf.h =================================================================== --- apple-local/branches/llvm/gcc/config/arm/elf.h 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/arm/elf.h 2007-04-03 00:13:00 UTC (rev 125638) @@ -77,6 +77,9 @@ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ ASM_OUTPUT_LABEL(FILE, NAME); \ +/* APPLE LOCAL begin LLVM */ \ + ARM_OUTPUT_FN_UNWIND (FILE, TRUE); \ +/* APPLE LOCAL end LLVM */ \ } \ while (0) @@ -85,6 +88,9 @@ #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ do \ { \ +/* APPLE LOCAL begin LLVM */ \ + ARM_OUTPUT_FN_UNWIND (FILE, FALSE); \ +/* APPLE LOCAL end LLVM */ \ ARM_DECLARE_FUNCTION_SIZE (FILE, FNAME, DECL); \ if (!flag_inhibit_size_directive) \ ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \ Modified: apple-local/branches/llvm/gcc/config/arm/lib1funcs.asm =================================================================== --- apple-local/branches/llvm/gcc/config/arm/lib1funcs.asm 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/arm/lib1funcs.asm 2007-04-03 00:13:00 UTC (rev 125638) @@ -637,6 +637,9 @@ #ifdef L_udivsi3 FUNC_START udivsi3 +/* APPLE LOCAL begin LLVM */ + FUNC_ALIAS aeabi_uidiv udivsi3 +/* APPLE LOCAL end LLVM */ #ifdef __thumb__ @@ -747,6 +750,9 @@ #ifdef L_divsi3 FUNC_START divsi3 +/* APPLE LOCAL begin LLVM */ + FUNC_ALIAS aeabi_idiv divsi3 +/* APPLE LOCAL end LLVM */ #ifdef __thumb__ cmp divisor, #0 @@ -1230,4 +1236,7 @@ #include "ieee754-df.S" #include "ieee754-sf.S" #include "bpabi.S" +/* APPLE LOCAL begin LLVM */ +#include "libunwind.S" +/* APPLE LOCAL end LLVM */ #endif /* __symbian__ */ Modified: apple-local/branches/llvm/gcc/config/arm/libgcc-bpabi.ver =================================================================== --- apple-local/branches/llvm/gcc/config/arm/libgcc-bpabi.ver 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/arm/libgcc-bpabi.ver 2007-04-03 00:13:00 UTC (rev 125638) @@ -42,6 +42,9 @@ __aeabi_fsub __aeabi_i2d __aeabi_i2f +#APPLE LOCAL begin LLVM + __aeabi_idiv +#APPLE LOCAL end LLVM __aeabi_idiv0 __aeabi_idivmod __aeabi_l2d @@ -55,9 +58,32 @@ __aeabi_lmul __aeabi_ui2d __aeabi_ui2f +#APPLE LOCAL begin LLVM + __aeabi_uidiv +#APPLE LOCAL end LLVM __aeabi_uidivmod __aeabi_uldivmod __aeabi_ulcmp __aeabi_ul2d __aeabi_ul2f +#APPLE LOCAL begin LLVM + __aeabi_uread4 + __aeabi_uread8 + __aeabi_uwrite4 + __aeabi_uwrite8 + + # Exception-Handling + # \S 7.5 + _Unwind_Complete + _Unwind_VRS_Get + _Unwind_VRS_Set + _Unwind_VRS_Pop + # \S 9.2 + __aeabi_unwind_cpp_pr0 + __aeabi_unwind_cpp_pr1 + __aeabi_unwind_cpp_pr2 + # The libstdc++ exception-handling personality routine uses this + # GNU-specific entry point. + __gnu_unwind_frame +#APPLE LOCAL end LLVM } Modified: apple-local/branches/llvm/gcc/config/arm/t-bpabi =================================================================== --- apple-local/branches/llvm/gcc/config/arm/t-bpabi 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/arm/t-bpabi 2007-04-03 00:13:00 UTC (rev 125638) @@ -1,9 +1,20 @@ # Add the bpabi.S functions. -LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod +#APPLE LOCAL begin LLVM +LIB1ASMFUNCS += _aeabi_lcmp _aeabi_ulcmp _aeabi_ldivmod _aeabi_uldivmod \ + _unwind +#APPLE LOCAL end LLVM # Add the BPABI C functions. -LIB2FUNCS_EXTRA = $(srcdir)/config/arm/bpabi.c +#APPLE LOCAL begin LLVM +LIB2FUNCS_EXTRA = $(srcdir)/config/arm/bpabi.c \ + $(srcdir)/config/arm/unaligned-funcs.c +UNWIND_H = $(srcdir)/config/arm/unwind-arm.h +LIB2ADDEH = $(srcdir)/config/arm/unwind-arm.c \ + $(srcdir)/config/arm/pr-support.c $(srcdir)/unwind-c.c +LIB2ADDEHDEP = $(UNWIND_H) +#APPLE LOCAL end LLVM + # Add the BPABI names. SHLIB_MAPFILES += $(srcdir)/config/arm/libgcc-bpabi.ver Modified: apple-local/branches/llvm/gcc/config/arm/t-symbian =================================================================== --- apple-local/branches/llvm/gcc/config/arm/t-symbian 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/arm/t-symbian 2007-04-03 00:13:00 UTC (rev 125638) @@ -12,6 +12,13 @@ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \ _fixsfsi _fixunssfsi +#APPLE LOCAL begin LLVM +# Include the gcc personality routine +UNWIND_H = $(srcdir)/config/arm/unwind-arm.h +LIB2ADDEH = $(srcdir)/unwind-c.c +LIB2ADDEHDEP = $(UNWIND_H) +#APPLE LOCAL end LLVM + # Create a multilib for processors with VFP floating-point, and a # multilib for those without -- using the soft-float ABI in both # cases. Symbian OS object should be compiled with interworking Modified: apple-local/branches/llvm/gcc/config/i386/t-netware =================================================================== --- apple-local/branches/llvm/gcc/config/i386/t-netware 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/i386/t-netware 2007-04-03 00:13:00 UTC (rev 125638) @@ -6,5 +6,4 @@ # We don't need some of GCC's own include files. USER_H = $(srcdir)/ginclude/stdarg.h \ $(srcdir)/ginclude/varargs.h \ - $(srcdir)/unwind.h \ $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS) Modified: apple-local/branches/llvm/gcc/config/ia64/ia64.h =================================================================== --- apple-local/branches/llvm/gcc/config/ia64/ia64.h 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/config/ia64/ia64.h 2007-04-03 00:13:00 UTC (rev 125638) @@ -2176,6 +2176,10 @@ #define TARGET_UNWIND_INFO 1 +/* APPLE LOCAL begin LLVM */ +#define TARGET_UNWIND_TABLES_DEFAULT true +/* APPLE LOCAL end LLVM */ + #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 15 : INVALID_REGNUM) /* This function contains machine specific function data. */ Modified: apple-local/branches/llvm/gcc/cp/Make-lang.in =================================================================== --- apple-local/branches/llvm/gcc/cp/Make-lang.in 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/cp/Make-lang.in 2007-04-03 00:13:00 UTC (rev 125638) @@ -291,8 +291,8 @@ # APPLE LOCAL end mainline cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H) cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h convert.h -cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h toplev.h \ - cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h +cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h \ + toplev.h cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h $(TARGET_H) cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \ except.h $(TM_P_H) # APPLE LOCAL begin mainline Modified: apple-local/branches/llvm/gcc/cp/decl.c =================================================================== --- apple-local/branches/llvm/gcc/cp/decl.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/cp/decl.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -5216,6 +5216,9 @@ tree fn_type; tree fn_ptr_type; const char *name; + /* APPLE LOCAL begin LLVM */ + bool use_aeabi_atexit; + /* APPLE LOCAL end LLVM */ if (atexit_node) return atexit_node; @@ -5229,6 +5232,9 @@ We build up the argument types and then then function type itself. */ + /* APPLE LOCAL begin LLVM */ + use_aeabi_atexit = targetm.cxx.use_aeabi_atexit (); + /* APPLE LOCAL end LLVM */ /* First, build the pointer-to-function type for the first argument. */ arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node); @@ -5236,12 +5242,27 @@ fn_ptr_type = build_pointer_type (fn_type); /* Then, build the rest of the argument types. */ arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node); - arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types); - arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types); + /* APPLE LOCAL begin LLVM */ + if (use_aeabi_atexit) + { + arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types); + arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types); + } + else + { + arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types); + arg_types = tree_cons (NULL_TREE, fn_ptr_type, arg_types); + } + /* APPLE LOCAL end LLVM */ /* And the final __cxa_atexit type. */ fn_type = build_function_type (integer_type_node, arg_types); fn_ptr_type = build_pointer_type (fn_type); - name = "__cxa_atexit"; + /* APPLE LOCAL begin LLVM */ + if (use_aeabi_atexit) + name = "__aeabi_atexit"; + else + name = "__cxa_atexit"; + /* APPLE LOCAL end LLVM */ } else { @@ -5402,8 +5423,18 @@ args = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0), NULL_TREE); - args = tree_cons (NULL_TREE, null_pointer_node, args); - args = tree_cons (NULL_TREE, cleanup, args); + /* APPLE LOCAL begin LLVM */ + if (targetm.cxx.use_aeabi_atexit ()) + { + args = tree_cons (NULL_TREE, cleanup, args); + args = tree_cons (NULL_TREE, null_pointer_node, args); + } + else + { + args = tree_cons (NULL_TREE, null_pointer_node, args); + args = tree_cons (NULL_TREE, cleanup, args); + } + /* APPLE LOCAL end LLVM */ } else args = tree_cons (NULL_TREE, cleanup, NULL_TREE); Modified: apple-local/branches/llvm/gcc/cp/except.c =================================================================== --- apple-local/branches/llvm/gcc/cp/except.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/cp/except.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -38,6 +38,9 @@ #include "toplev.h" #include "tree-inline.h" #include "tree-iterator.h" +/* APPLE LOCAL begin LLVM */ +#include "target.h" +/* APPLE LOCAL end LLVM */ static void push_eh_cleanup (tree); static tree prepare_eh_type (tree); @@ -79,6 +82,12 @@ eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS ? "__gxx_personality_sj0" : "__gxx_personality_v0"); +/* APPLE LOCAL begin LLVM */ + if (targetm.arm_eabi_unwinder) + unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup"); + else + default_init_unwind_resume_libfunc (); +/* APPLE LOCAL end LLVM */ lang_eh_runtime_type = build_eh_type_type; lang_protect_cleanup_actions = &cp_protect_cleanup_actions; Modified: apple-local/branches/llvm/gcc/except.c =================================================================== --- apple-local/branches/llvm/gcc/except.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/except.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -235,7 +235,9 @@ int built_landing_pads; int last_region_number; - varray_type ttype_data; +/* APPLE LOCAL begin LLVM */ + VEC(tree) *ttype_data; +/* APPLE LOCAL end LLVM */ varray_type ehspec_data; varray_type action_record_data; @@ -967,10 +969,14 @@ n = xmalloc (sizeof (*n)); n->t = type; - n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1; +/* APPLE LOCAL begin LLVM */ + n->filter = VEC_length (tree, cfun->eh->ttype_data) + 1; +/* APPLE LOCAL end LLVM */ *slot = n; - VARRAY_PUSH_TREE (cfun->eh->ttype_data, type); +/* APPLE LOCAL begin LLVM */ + VEC_safe_push (tree, cfun->eh->ttype_data, type); +/* APPLE LOCAL end LLVM */ } return n->filter; @@ -998,12 +1004,25 @@ n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1); *slot = n; - /* Look up each type in the list and encode its filter - value as a uleb128. Terminate the list with 0. */ +/* APPLE LOCAL begin LLVM */ + /* Generate a 0 terminated list of filter values. */ for (; list ; list = TREE_CHAIN (list)) - push_uleb128 (&cfun->eh->ehspec_data, - add_ttypes_entry (ttypes_hash, TREE_VALUE (list))); - VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0); + { + if (targetm.arm_eabi_unwinder) + VARRAY_PUSH_TREE (cfun->eh->ehspec_data, TREE_VALUE (list)); + else + { + /* Look up each type in the list and encode its filter + value as a uleb128. */ + push_uleb128 (&cfun->eh->ehspec_data, + add_ttypes_entry (ttypes_hash, TREE_VALUE (list))); + } + } + if (targetm.arm_eabi_unwinder) + VARRAY_PUSH_TREE (cfun->eh->ehspec_data, NULL_TREE); + else + VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0); +/* APPLE LOCAL end LLVM */ } return n->filter; @@ -1020,8 +1039,13 @@ int i; htab_t ttypes, ehspec; - VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data"); - VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data"); +/* APPLE LOCAL begin LLVM */ + cfun->eh->ttype_data = VEC_alloc (tree, 16); + if (targetm.arm_eabi_unwinder) + VARRAY_TREE_INIT (cfun->eh->ehspec_data, 64, "ehspec_data"); + else + VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data"); +/* APPLE LOCAL end LLVM */ ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free); ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free); @@ -3228,6 +3252,56 @@ readonly_data_section (); } + +/* APPLE LOCAL begin LLVM */ +/* Output a reference from an exception table to the type_info object TYPE. + TT_FORMAT and TT_FORMAT_SIZE descibe the DWARF encoding method used for + the value. */ + +static void +output_ttype (tree type, int tt_format, int tt_format_size) +{ + rtx value; + + if (type == NULL_TREE) + value = const0_rtx; + else + { + struct cgraph_varpool_node *node; + + type = lookup_type_for_runtime (type); + value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER); + + /* Let cgraph know that the rtti decl is used. Not all of the + paths below go through assemble_integer, which would take + care of this for us. */ + STRIP_NOPS (type); + if (TREE_CODE (type) == ADDR_EXPR) + { + type = TREE_OPERAND (type, 0); + if (TREE_CODE (type) == VAR_DECL) + { + node = cgraph_varpool_node (type); + if (node) + cgraph_varpool_mark_needed_node (node); + } + } + else if (TREE_CODE (type) != INTEGER_CST) + abort (); + } + + /* Allow the target to override the type table entry format. */ + if (targetm.asm_out.ttype (value)) + return; + + if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned) + assemble_integer (value, tt_format_size, + tt_format_size * BITS_PER_UNIT, 1); + else + dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL); +} +/* APPLE LOCAL end LLVM */ + void output_function_exception_table (void) { @@ -3263,8 +3337,10 @@ targetm.asm_out.except_table_label (asm_out_file); /* APPLE LOCAL end mainline */ - have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0 +/* APPLE LOCAL begin LLVM */ + have_tt_data = (VEC_length (tree, cfun->eh->ttype_data) > 0 || VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0); +/* APPLE LOCAL end LLVM */ /* Indicate the format of the @TType entries. */ if (! have_tt_data) @@ -3326,7 +3402,9 @@ after_disp = (1 + size_of_uleb128 (call_site_len) + call_site_len + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) - + (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) +/* APPLE LOCAL begin LLVM */ + + (VEC_length (tree, cfun->eh->ttype_data) +/* APPLE LOCAL end LLVM */ * tt_format_size)); disp = after_disp; @@ -3388,44 +3466,15 @@ if (have_tt_data) assemble_align (tt_format_size * BITS_PER_UNIT); - i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data); +/* APPLE LOCAL begin LLVM */ + i = VEC_length (tree, cfun->eh->ttype_data); +/* APPLE LOCAL end LLVM */ while (i-- > 0) { - tree type = VARRAY_TREE (cfun->eh->ttype_data, i); - rtx value; - - if (type == NULL_TREE) - value = const0_rtx; - else - { - struct cgraph_varpool_node *node; - - type = lookup_type_for_runtime (type); - value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER); - - /* Let cgraph know that the rtti decl is used. Not all of the - paths below go through assemble_integer, which would take - care of this for us. */ - STRIP_NOPS (type); - if (TREE_CODE (type) == ADDR_EXPR) - { - type = TREE_OPERAND (type, 0); - if (TREE_CODE (type) == VAR_DECL) - { - node = cgraph_varpool_node (type); - if (node) - cgraph_varpool_mark_needed_node (node); - } - } - else - gcc_assert (TREE_CODE (type) == INTEGER_CST); - } - - if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned) - assemble_integer (value, tt_format_size, - tt_format_size * BITS_PER_UNIT, 1); - else - dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL); +/* APPLE LOCAL begin LLVM */ + tree type = VEC_index (tree, cfun->eh->ttype_data, i); + output_ttype (type, tt_format, tt_format_size); +/* APPLE LOCAL end LLVM */ } #ifdef HAVE_AS_LEB128 @@ -3436,10 +3485,35 @@ /* ??? Decode and interpret the data for flag_debug_asm. */ n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data); for (i = 0; i < n; ++i) - dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i), - (i ? NULL : "Exception specification table")); +/* APPLE LOCAL begin LLVM */ + { + if (targetm.arm_eabi_unwinder) + { + tree type = VARRAY_TREE (cfun->eh->ehspec_data, i); + output_ttype (type, tt_format, tt_format_size); + } + else + dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i), + (i ? NULL : "Exception specification table")); + } +/* APPLE LOCAL end LLVM */ function_section (current_function_decl); } + + +/* APPLE LOCAL begin LLVM */ +/* Initialize unwind_resume_libfunc. */ + +void +default_init_unwind_resume_libfunc (void) +{ + /* The default c++ routines aren't actually c++ specific, so use those. */ + unwind_resume_libfunc = + init_one_libfunc ( USING_SJLJ_EXCEPTIONS ? "_Unwind_SjLj_Resume" + : "_Unwind_Resume"); +} +/* APPLE LOCAL end LLVM */ + #include "gt-except.h" Modified: apple-local/branches/llvm/gcc/except.h =================================================================== --- apple-local/branches/llvm/gcc/except.h 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/except.h 2007-04-03 00:13:00 UTC (rev 125638) @@ -84,6 +84,9 @@ extern int check_handled (tree, tree); extern void sjlj_emit_function_exit_after (rtx); +/* APPLE LOCAL begin LLVM */ +extern void default_init_unwind_resume_libfunc (void); +/* APPLE LOCAL end LLVM */ extern struct eh_region *gen_eh_region_cleanup (struct eh_region *, struct eh_region *); Modified: apple-local/branches/llvm/gcc/java/decl.c =================================================================== --- apple-local/branches/llvm/gcc/java/decl.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/java/decl.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -1185,6 +1185,9 @@ eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS ? "__gcj_personality_sj0" : "__gcj_personality_v0"); + /* APPLE LOCAL begin LLVM */ + default_init_unwind_resume_libfunc (); + /* APPLE LOCAL end LLVM */ lang_eh_runtime_type = do_nothing; Modified: apple-local/branches/llvm/gcc/objc/objc-act.c =================================================================== --- apple-local/branches/llvm/gcc/objc/objc-act.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/objc/objc-act.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -7063,6 +7063,9 @@ = init_one_libfunc (USING_SJLJ_EXCEPTIONS ? "__gnu_objc_personality_sj0" : "__gnu_objc_personality_v0"); +/* APPLE LOCAL begin LLVM */ + default_init_unwind_resume_libfunc (); +/* APPLE LOCAL end LLVM */ using_eh_for_cleanups (); lang_eh_runtime_type = objc_eh_runtime_type; } Modified: apple-local/branches/llvm/gcc/optabs.c =================================================================== --- apple-local/branches/llvm/gcc/optabs.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/optabs.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -5207,9 +5207,6 @@ memset_libfunc = init_one_libfunc ("memset"); setbits_libfunc = init_one_libfunc ("__setbits"); - unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "_Unwind_SjLj_Resume" - : "_Unwind_Resume"); #ifndef DONT_USE_BUILTIN_SETJMP setjmp_libfunc = init_one_libfunc ("__builtin_setjmp"); longjmp_libfunc = init_one_libfunc ("__builtin_longjmp"); Modified: apple-local/branches/llvm/gcc/opts.c =================================================================== --- apple-local/branches/llvm/gcc/opts.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/opts.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -722,11 +722,10 @@ target_flags = 0; set_target_switch (""); - /* Unwind tables are always present when a target has ABI-specified unwind - tables, so the default should be ON. */ -#ifdef TARGET_UNWIND_INFO - flag_unwind_tables = TARGET_UNWIND_INFO; -#endif +/* APPLE LOCAL begin LLVM */ + /* Some tagets have ABI-specified unwind tables. */ + flag_unwind_tables = targetm.unwind_tables_default; +/* APPLE LOCAL end LLVM */ #ifdef OPTIMIZATION_OPTIONS /* Allow default optimizations to be specified on a per-machine basis. */ Modified: apple-local/branches/llvm/gcc/target-def.h =================================================================== --- apple-local/branches/llvm/gcc/target-def.h 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/target-def.h 2007-04-03 00:13:00 UTC (rev 125638) @@ -75,6 +75,12 @@ #define TARGET_ASM_INTERNAL_LABEL default_internal_label #endif +/* APPLE LOCAL begin LLVM */ +#ifndef TARGET_ARM_TTYPE +#define TARGET_ASM_TTYPE hook_bool_rtx_false +#endif +/* APPLE LOCAL end LLVM */ + #ifndef TARGET_ASM_ASSEMBLE_VISIBILITY #define TARGET_ASM_ASSEMBLE_VISIBILITY default_assemble_visibility #endif @@ -216,6 +222,9 @@ TARGET_ASM_EMIT_EXCEPT_TABLE_LABEL, \ TARGET_UNWIND_EMIT, \ TARGET_ASM_INTERNAL_LABEL, \ +/* APPLE LOCAL begin LLVM */ \ + TARGET_ASM_TTYPE, \ +/* APPLE LOCAL end LLVM */ \ TARGET_ASM_ASSEMBLE_VISIBILITY, \ TARGET_ASM_FUNCTION_PROLOGUE, \ TARGET_ASM_FUNCTION_END_PROLOGUE, \ @@ -422,6 +431,10 @@ #endif /* APPLE LOCAL end mainline 2005-10-12 */ +/* APPLE LOCAL begin LLVM */ +#define TARGET_ARM_EABI_UNWINDER false +/* APPLE LOCAL end LLVM */ + #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_false #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_false #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false @@ -485,6 +498,11 @@ } /* APPLE LOCAL end mainline 2005-04-14 */ +/* APPLE LOCAL begin LLVM */ +#ifndef TARGET_UNWIND_TABLES_DEFAULT +#define TARGET_UNWIND_TABLES_DEFAULT false +#endif +/* APPLE LOCAL end LLVM */ #ifndef TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME #define TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME 0 @@ -543,6 +561,12 @@ #endif /* APPLE LOCAL begin mainline 2005-10-12 */ +/* APPLE LOCAL begin LLVM */ +#ifndef TARGET_CXX_USE_AEABI_ATEXIT +#define TARGET_CXX_USE_AEABI_ATEXIT hook_bool_void_false +#endif +/* APPLE LOCAL end LLVM */ + #define TARGET_CXX \ { \ TARGET_CXX_GUARD_TYPE, \ @@ -557,8 +581,11 @@ TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT, \ /* APPLE LOCAL end mainline 4.2 2006-03-01 4311680 */ \ /* APPLE LOCAL begin mainline 2005-10-12 */ \ - TARGET_CXX_ADJUST_CLASS_AT_DEFINITION \ + TARGET_CXX_ADJUST_CLASS_AT_DEFINITION, \ /* APPLE LOCAL end mainline 2005-10-12 */ \ + /* APPLE LOCAL begin LLVM */ \ + TARGET_CXX_USE_AEABI_ATEXIT, \ + /* APPLE LOCAL end LLVM */ \ } /* The whole shebang. */ @@ -625,6 +652,9 @@ /* APPLE LOCAL end mainline 2005-10-12 */ \ TARGET_CALLS, \ TARGET_CXX, \ +/* APPLE LOCAL begin LLVM */ \ + TARGET_UNWIND_TABLES_DEFAULT, \ +/* APPLE LOCAL end LLVM */ \ TARGET_HAVE_NAMED_SECTIONS, \ TARGET_HAVE_CTORS_DTORS, \ TARGET_HAVE_TLS, \ @@ -637,6 +667,9 @@ TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME, \ TARGET_HANDLE_PRAGMA_EXTERN_PREFIX, \ TARGET_RELAXED_ORDERING, \ +/* APPLE LOCAL begin LLVM */ \ + TARGET_ARM_EABI_UNWINDER \ +/* APPLE LOCAL end LLVM */ \ } #include "hooks.h" Modified: apple-local/branches/llvm/gcc/target.h =================================================================== --- apple-local/branches/llvm/gcc/target.h 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/target.h 2007-04-03 00:13:00 UTC (rev 125638) @@ -97,6 +97,11 @@ /* Output an internal label. */ void (* internal_label) (FILE *, const char *, unsigned long); +/* APPLE LOCAL begin LLVM */ + /* Emit a ttype table reference to a typeinfo object. */ + bool (* ttype) (rtx); +/* APPLE LOCAL end LLVM */ + /* Emit an assembler directive to set visibility for the symbol associated with the tree decl. */ void (* visibility) (tree, int); @@ -642,8 +647,16 @@ target modifications). */ void (*adjust_class_at_definition) (tree type); /* APPLE LOCAL end mainline 2005-10-12 */ + /* APPLE LOCAL begin LLVM */ + bool (*use_aeabi_atexit) (void); + /* APPLE LOCAL end LLVM */ } cxx; + /* APPLE LOCAL begin LLVM */ + /* True if unwinding tables should be generated by default. */ + bool unwind_tables_default; + /* APPLE LOCAL end LLVM */ + /* Leave the boolean fields at the end. */ /* True if arbitrary sections are supported. */ @@ -691,6 +704,13 @@ synchronization is explicitly requested. */ bool relaxed_ordering; +/* APPLE LOCAL begin LLVM */ + /* Returns true if we should generate exception tables for use with the + ARM EABI. The effects the encoding of function exception specifications. + */ + bool arm_eabi_unwinder; +/* APPLE LOCAL end LLVM */ + /* Leave the boolean fields at the end. */ }; Modified: apple-local/branches/llvm/gcc/unwind-c.c =================================================================== --- apple-local/branches/llvm/gcc/unwind-c.c 2007-04-03 00:10:47 UTC (rev 125637) +++ apple-local/branches/llvm/gcc/unwind-c.c 2007-04-03 00:13:00 UTC (rev 125638) @@ -81,6 +81,22 @@ return p; } +/* APPLE LOCAL begin LLVM */ +#ifdef __ARM_EABI_UNWINDER__ +/* ARM EABI personality routines must also unwind the stack. */ +#define CONTINUE_UNWINDING \ + do \ + { \ + if (__gnu_unwind_frame (ue_header, context) != _URC_OK) \ + return _URC_FAILURE; \ + return _URC_CONTINUE_UNWIND; \ + } \ + while (0) +#else +#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND +#endif +/* APPLE LOCAL end LLVM */ + #ifdef __USING_SJLJ_EXCEPTIONS__ #define PERSONALITY_FUNCTION __gcc_personality_sj0 #define __builtin_eh_return_data_regno(x) x @@ -88,7 +104,19 @@ #define PERSONALITY_FUNCTION __gcc_personality_v0 #endif +/* APPLE LOCAL begin LLVM */ +#ifdef __ARM_EABI_UNWINDER__ _Unwind_Reason_Code +PERSONALITY_FUNCTION (_Unwind_State, struct _Unwind_Exception *, + struct _Unwind_Context *); + +_Unwind_Reason_Code +PERSONALITY_FUNCTION (_Unwind_State state, + struct _Unwind_Exception * ue_header, + struct _Unwind_Context * context) +#else +/* APPLE LOCAL end LLVM */ +_Unwind_Reason_Code PERSONALITY_FUNCTION (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, struct _Unwind_Context *); @@ -98,24 +126,45 @@ _Unwind_Exception_Class exception_class ATTRIBUTE_UNUSED, struct _Unwind_Exception *ue_header, struct _Unwind_Context *context) +/* APPLE LOCAL begin LLVM */ +#endif +/* APPLE LOCAL end LLVM */ { lsda_header_info info; const unsigned char *language_specific_data, *p, *action_record; _Unwind_Ptr landing_pad, ip; +/* APPLE LOCAL begin LLVM */ +#ifdef __ARM_EABI_UNWINDER__ + if (state != _US_UNWIND_FRAME_STARTING) + CONTINUE_UNWINDING; + + /* The dwarf unwinder assumes the context structure holds things like the + function and LSDA pointers. The ARM implementation caches these in + the exception header (UCB). To avoid rewriting everything we make the + virtual IP register point at the UCB. */ + ip = (_Unwind_Ptr) ue_header; + _Unwind_SetGR (context, 12, ip); +#else +/* APPLE LOCAL end LLVM */ if (version != 1) return _URC_FATAL_PHASE1_ERROR; /* Currently we only support cleanups for C. */ if ((actions & _UA_CLEANUP_PHASE) == 0) - return _URC_CONTINUE_UNWIND; +/* APPLE LOCAL begin LLVM */ + CONTINUE_UNWINDING; +#endif +/* APPLE LOCAL end LLVM */ language_specific_data = (const unsigned char *) _Unwind_GetLanguageSpecificData (context); /* If no LSDA, then there are no handlers or cleanups. */ if (! language_specific_data) - return _URC_CONTINUE_UNWIND; +/* APPLE LOCAL begin LLVM */ + CONTINUE_UNWINDING; +/* APPLE LOCAL end LLVM */ /* Parse the LSDA header. */ p = parse_lsda_header (context, language_specific_data, &info); @@ -171,20 +220,23 @@ goto found_something; } } - #endif /* IP is not in table. No associated cleanups. */ /* ??? This is where C++ calls std::terminate to catch throw from a destructor. */ - return _URC_CONTINUE_UNWIND; +/* APPLE LOCAL begin LLVM */ + CONTINUE_UNWINDING; +/* APPLE LOCAL end LLVM */ found_something: if (landing_pad == 0) { /* IP is present, but has a null landing pad. No handler to be run. */ - return _URC_CONTINUE_UNWIND; +/* APPLE LOCAL begin LLVM */ + CONTINUE_UNWINDING; +/* APPLE LOCAL end LLVM */ } _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), From sabre at nondot.org Mon Apr 2 19:14:15 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 19:14:15 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelLowering.cpp Message-ID: <200704030014.l330EFo7030792@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMISelLowering.cpp updated: 1.37 -> 1.38 --- Log message: Arm supports negative strides as well, add them. This lets us compile: CodeGen/ARM/arm-negative-stride.ll to: LBB1_2: @bb str r1, [r3, -r0, lsl #2] add r0, r0, #1 cmp r0, r2 bne LBB1_2 @bb --- Diffs of the changes: (+6 -3) ARMISelLowering.cpp | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) Index: llvm/lib/Target/ARM/ARMISelLowering.cpp diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.37 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.38 --- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.37 Mon Apr 2 13:51:18 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp Mon Apr 2 19:13:57 2007 @@ -1323,7 +1323,7 @@ // This assumes i64 is legalized to a pair of i32. If not (i.e. // ldrd / strd are used, then its address mode is same as i16. // r + r - if (AM.Scale == 2) + if (AM.Scale == 1) return true; // r + r << imm if (!isPowerOf2_32(AM.Scale & ~1)) @@ -1422,7 +1422,9 @@ case MVT::i1: case MVT::i8: case MVT::i32: - // Allow: r + r + if (S < 0) S = -S; + if (S == 1) return true; // Allow: r + r + // Allow: r << imm // Allow: r + r << imm S &= ~1; @@ -1431,7 +1433,8 @@ // Note, we allow "void" uses (basically, uses that aren't loads or // stores), because arm allows folding a scale into many arithmetic // operations. This should be made more precise and revisited later. - + if (S == 1) return true; // Allow: r + r + // Allow r << imm, but the imm has to be a multiple of two. if (S & 1) return false; return isPowerOf2_32(S); From johannes at apple.com Mon Apr 2 19:13:59 2007 From: johannes at apple.com (johannes at apple.com) Date: Mon, 2 Apr 2007 17:13:59 -0700 (PDT) Subject: [llvm-commits] [125639] arm EABI patch (Lauro Ramos Venancio) Message-ID: <20070403001359.AA7B3CB80E8B@src> Revision: 125639 Author: johannes Date: 2007-04-02 17:13:59 -0700 (Mon, 02 Apr 2007) Log Message: ----------- arm EABI patch (Lauro Ramos Venancio) Added Paths: ----------- apple-local/branches/llvm/gcc/unwind-generic.h apple-local/branches/llvm/gcc/unwind.h.removed Removed Paths: ------------- apple-local/branches/llvm/gcc/unwind.h Added: apple-local/branches/llvm/gcc/unwind-generic.h =================================================================== --- apple-local/branches/llvm/gcc/unwind-generic.h (rev 0) +++ apple-local/branches/llvm/gcc/unwind-generic.h 2007-04-03 00:13:59 UTC (rev 125639) @@ -0,0 +1,240 @@ +/* Exception handling and frame unwind runtime interface routines. + Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* This is derived from the C++ ABI for IA-64. Where we diverge + for cross-architecture compatibility are noted with "@@@". */ + +#ifndef _UNWIND_H +#define _UNWIND_H + +#ifndef HIDE_EXPORTS +#pragma GCC visibility push(default) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Level 1: Base ABI */ + +/* @@@ The IA-64 ABI uses uint64 throughout. Most places this is + inefficient for 32-bit and smaller machines. */ +typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); +typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); +#if defined(__ia64__) && defined(__hpux__) +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__))); +#else +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); +#endif +typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); + +/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and + consumer of an exception. We'll go along with this for now even on + 32-bit machines. We'll need to provide some other option for + 16-bit machines and for machines with > 8 bits per byte. */ +typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); + +/* The unwind interface uses reason codes in several contexts to + identify the reasons for failures or other actions. */ +typedef enum +{ + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 +} _Unwind_Reason_Code; + + +/* The unwind interface uses a pointer to an exception header object + as its representation of an exception being thrown. In general, the + full representation of an exception object is language- and + implementation-specific, but it will be prefixed by a header + understood by the unwind interface. */ + +struct _Unwind_Exception; + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + +struct _Unwind_Exception +{ + _Unwind_Exception_Class exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + _Unwind_Word private_1; + _Unwind_Word private_2; + + /* @@@ The IA-64 ABI says that this structure must be double-word aligned. + Taking that literally does not make much sense generically. Instead we + provide the maximum alignment required by any type for the machine. */ +} __attribute__((__aligned__)); + + +/* The ACTIONS argument to the personality routine is a bitwise OR of one + or more of the following constants. */ +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 +#define _UA_END_OF_STACK 16 + +/* This is an opaque type used to refer to a system-specific data + structure used by the system unwinder. This context is created and + destroyed by the system, and passed to the personality routine + during unwinding. */ +struct _Unwind_Context; + +/* Raise an exception, passing along the given exception object. */ +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); + +/* Raise an exception for forced unwinding. */ + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, + _Unwind_Stop_Fn, + void *); + +/* Helper to invoke the exception_cleanup routine. */ +extern void _Unwind_DeleteException (struct _Unwind_Exception *); + +/* Resume propagation of an existing exception. This is used after + e.g. executing cleanup code, and not to implement rethrowing. */ +extern void _Unwind_Resume (struct _Unwind_Exception *); + +/* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow + a normal exception that was handled. */ +extern _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* @@@ Use unwind data to perform a stack backtrace. The trace callback + is called for every stack frame in the call chain, but no cleanup + actions are performed. */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) + (struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + +/* These functions are used for communicating information about the unwind + context (i.e. the unwind descriptors and the user register state) between + the unwind library and the personality routine and landing pad. Only + selected registers maybe manipulated. */ + +extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); + +extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); +extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); + +/* @@@ Retrieve the CFA of the given context. */ +extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); + +extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *); + +extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *); + + +/* The personality routine is the function in the C++ (or other language) + runtime library which serves as an interface between the system unwind + library and language-specific exception handling semantics. It is + specific to the code fragment described by an unwind info block, and + it is always referenced via the pointer in the unwind info block, and + hence it has no ABI-specified name. + + Note that this implies that two different C++ implementations can + use different names, and have different contents in the language + specific data area. Moreover, that the language specific data + area contains no version info because name of the function invoked + provides more effective versioning by detecting at link time the + lack of code to handle the different data format. */ + +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *); + +/* @@@ The following alternate entry points are for setjmp/longjmp + based unwinding. */ + +struct SjLj_Function_Context; +extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *); +extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *); + +extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException + (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind + (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); +extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* @@@ The following provide access to the base addresses for text + and data-relative addressing in the LDSA. In order to stay link + compatible with the standard ABI for IA-64, we inline these. */ + +#ifdef __ia64__ +#include + +static inline _Unwind_Ptr +_Unwind_GetDataRelBase (struct _Unwind_Context *_C) +{ + /* The GP is stored in R1. */ + return _Unwind_GetGR (_C, 1); +} + +static inline _Unwind_Ptr +_Unwind_GetTextRelBase (struct _Unwind_Context *_C __attribute__ ((__unused__))) +{ + abort (); + return 0; +} + +/* @@@ Retrieve the Backing Store Pointer of the given context. */ +extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *); +#else +extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *); +extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *); +#endif + +/* @@@ Given an address, return the entry point of the function that + contains it. */ +extern void * _Unwind_FindEnclosingFunction (void *pc); + +#ifdef __cplusplus +} +#endif + +#ifndef HIDE_EXPORTS +#pragma GCC visibility pop +#endif + +#endif /* unwind.h */ Deleted: apple-local/branches/llvm/gcc/unwind.h =================================================================== --- apple-local/branches/llvm/gcc/unwind.h 2007-04-03 00:13:00 UTC (rev 125638) +++ apple-local/branches/llvm/gcc/unwind.h 2007-04-03 00:13:59 UTC (rev 125639) @@ -1,240 +0,0 @@ -/* Exception handling and frame unwind runtime interface routines. - Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING. If not, write to the Free - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* As a special exception, if you include this header file into source - files compiled by GCC, this header file does not by itself cause - the resulting executable to be covered by the GNU General Public - License. This exception does not however invalidate any other - reasons why the executable file might be covered by the GNU General - Public License. */ - -/* This is derived from the C++ ABI for IA-64. Where we diverge - for cross-architecture compatibility are noted with "@@@". */ - -#ifndef _UNWIND_H -#define _UNWIND_H - -#ifndef HIDE_EXPORTS -#pragma GCC visibility push(default) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Level 1: Base ABI */ - -/* @@@ The IA-64 ABI uses uint64 throughout. Most places this is - inefficient for 32-bit and smaller machines. */ -typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); -typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); -#if defined(__ia64__) && defined(__hpux__) -typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__))); -#else -typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); -#endif -typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); - -/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and - consumer of an exception. We'll go along with this for now even on - 32-bit machines. We'll need to provide some other option for - 16-bit machines and for machines with > 8 bits per byte. */ -typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); - -/* The unwind interface uses reason codes in several contexts to - identify the reasons for failures or other actions. */ -typedef enum -{ - _URC_NO_REASON = 0, - _URC_FOREIGN_EXCEPTION_CAUGHT = 1, - _URC_FATAL_PHASE2_ERROR = 2, - _URC_FATAL_PHASE1_ERROR = 3, - _URC_NORMAL_STOP = 4, - _URC_END_OF_STACK = 5, - _URC_HANDLER_FOUND = 6, - _URC_INSTALL_CONTEXT = 7, - _URC_CONTINUE_UNWIND = 8 -} _Unwind_Reason_Code; - - -/* The unwind interface uses a pointer to an exception header object - as its representation of an exception being thrown. In general, the - full representation of an exception object is language- and - implementation-specific, but it will be prefixed by a header - understood by the unwind interface. */ - -struct _Unwind_Exception; - -typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, - struct _Unwind_Exception *); - -struct _Unwind_Exception -{ - _Unwind_Exception_Class exception_class; - _Unwind_Exception_Cleanup_Fn exception_cleanup; - _Unwind_Word private_1; - _Unwind_Word private_2; - - /* @@@ The IA-64 ABI says that this structure must be double-word aligned. - Taking that literally does not make much sense generically. Instead we - provide the maximum alignment required by any type for the machine. */ -} __attribute__((__aligned__)); - - -/* The ACTIONS argument to the personality routine is a bitwise OR of one - or more of the following constants. */ -typedef int _Unwind_Action; - -#define _UA_SEARCH_PHASE 1 -#define _UA_CLEANUP_PHASE 2 -#define _UA_HANDLER_FRAME 4 -#define _UA_FORCE_UNWIND 8 -#define _UA_END_OF_STACK 16 - -/* This is an opaque type used to refer to a system-specific data - structure used by the system unwinder. This context is created and - destroyed by the system, and passed to the personality routine - during unwinding. */ -struct _Unwind_Context; - -/* Raise an exception, passing along the given exception object. */ -extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); - -/* Raise an exception for forced unwinding. */ - -typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) - (int, _Unwind_Action, _Unwind_Exception_Class, - struct _Unwind_Exception *, struct _Unwind_Context *, void *); - -extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, - _Unwind_Stop_Fn, - void *); - -/* Helper to invoke the exception_cleanup routine. */ -extern void _Unwind_DeleteException (struct _Unwind_Exception *); - -/* Resume propagation of an existing exception. This is used after - e.g. executing cleanup code, and not to implement rethrowing. */ -extern void _Unwind_Resume (struct _Unwind_Exception *); - -/* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow - a normal exception that was handled. */ -extern _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); - -/* @@@ Use unwind data to perform a stack backtrace. The trace callback - is called for every stack frame in the call chain, but no cleanup - actions are performed. */ -typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) - (struct _Unwind_Context *, void *); - -extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); - -/* These functions are used for communicating information about the unwind - context (i.e. the unwind descriptors and the user register state) between - the unwind library and the personality routine and landing pad. Only - selected registers maybe manipulated. */ - -extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int); -extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); - -extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); -extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); - -/* @@@ Retrieve the CFA of the given context. */ -extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); - -extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *); - -extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *); - - -/* The personality routine is the function in the C++ (or other language) - runtime library which serves as an interface between the system unwind - library and language-specific exception handling semantics. It is - specific to the code fragment described by an unwind info block, and - it is always referenced via the pointer in the unwind info block, and - hence it has no ABI-specified name. - - Note that this implies that two different C++ implementations can - use different names, and have different contents in the language - specific data area. Moreover, that the language specific data - area contains no version info because name of the function invoked - provides more effective versioning by detecting at link time the - lack of code to handle the different data format. */ - -typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) - (int, _Unwind_Action, _Unwind_Exception_Class, - struct _Unwind_Exception *, struct _Unwind_Context *); - -/* @@@ The following alternate entry points are for setjmp/longjmp - based unwinding. */ - -struct SjLj_Function_Context; -extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *); -extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *); - -extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException - (struct _Unwind_Exception *); -extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind - (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); -extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *); -extern _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *); - -/* @@@ The following provide access to the base addresses for text - and data-relative addressing in the LDSA. In order to stay link - compatible with the standard ABI for IA-64, we inline these. */ - -#ifdef __ia64__ -#include - -static inline _Unwind_Ptr -_Unwind_GetDataRelBase (struct _Unwind_Context *_C) -{ - /* The GP is stored in R1. */ - return _Unwind_GetGR (_C, 1); -} - -static inline _Unwind_Ptr -_Unwind_GetTextRelBase (struct _Unwind_Context *_C __attribute__ ((__unused__))) -{ - abort (); - return 0; -} - -/* @@@ Retrieve the Backing Store Pointer of the given context. */ -extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *); -#else -extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *); -extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *); -#endif - -/* @@@ Given an address, return the entry point of the function that - contains it. */ -extern void * _Unwind_FindEnclosingFunction (void *pc); - -#ifdef __cplusplus -} -#endif - -#ifndef HIDE_EXPORTS -#pragma GCC visibility pop -#endif - -#endif /* unwind.h */ Added: apple-local/branches/llvm/gcc/unwind.h.removed =================================================================== --- apple-local/branches/llvm/gcc/unwind.h.removed (rev 0) +++ apple-local/branches/llvm/gcc/unwind.h.removed 2007-04-03 00:13:59 UTC (rev 125639) @@ -0,0 +1,240 @@ +/* Exception handling and frame unwind runtime interface routines. + Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +/* As a special exception, if you include this header file into source + files compiled by GCC, this header file does not by itself cause + the resulting executable to be covered by the GNU General Public + License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General + Public License. */ + +/* This is derived from the C++ ABI for IA-64. Where we diverge + for cross-architecture compatibility are noted with "@@@". */ + +#ifndef _UNWIND_H +#define _UNWIND_H + +#ifndef HIDE_EXPORTS +#pragma GCC visibility push(default) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Level 1: Base ABI */ + +/* @@@ The IA-64 ABI uses uint64 throughout. Most places this is + inefficient for 32-bit and smaller machines. */ +typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); +typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); +#if defined(__ia64__) && defined(__hpux__) +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__))); +#else +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); +#endif +typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); + +/* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and + consumer of an exception. We'll go along with this for now even on + 32-bit machines. We'll need to provide some other option for + 16-bit machines and for machines with > 8 bits per byte. */ +typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); + +/* The unwind interface uses reason codes in several contexts to + identify the reasons for failures or other actions. */ +typedef enum +{ + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 +} _Unwind_Reason_Code; + + +/* The unwind interface uses a pointer to an exception header object + as its representation of an exception being thrown. In general, the + full representation of an exception object is language- and + implementation-specific, but it will be prefixed by a header + understood by the unwind interface. */ + +struct _Unwind_Exception; + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + +struct _Unwind_Exception +{ + _Unwind_Exception_Class exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + _Unwind_Word private_1; + _Unwind_Word private_2; + + /* @@@ The IA-64 ABI says that this structure must be double-word aligned. + Taking that literally does not make much sense generically. Instead we + provide the maximum alignment required by any type for the machine. */ +} __attribute__((__aligned__)); + + +/* The ACTIONS argument to the personality routine is a bitwise OR of one + or more of the following constants. */ +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 +#define _UA_END_OF_STACK 16 + +/* This is an opaque type used to refer to a system-specific data + structure used by the system unwinder. This context is created and + destroyed by the system, and passed to the personality routine + during unwinding. */ +struct _Unwind_Context; + +/* Raise an exception, passing along the given exception object. */ +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); + +/* Raise an exception for forced unwinding. */ + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, + _Unwind_Stop_Fn, + void *); + +/* Helper to invoke the exception_cleanup routine. */ +extern void _Unwind_DeleteException (struct _Unwind_Exception *); + +/* Resume propagation of an existing exception. This is used after + e.g. executing cleanup code, and not to implement rethrowing. */ +extern void _Unwind_Resume (struct _Unwind_Exception *); + +/* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow + a normal exception that was handled. */ +extern _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* @@@ Use unwind data to perform a stack backtrace. The trace callback + is called for every stack frame in the call chain, but no cleanup + actions are performed. */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) + (struct _Unwind_Context *, void *); + +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + +/* These functions are used for communicating information about the unwind + context (i.e. the unwind descriptors and the user register state) between + the unwind library and the personality routine and landing pad. Only + selected registers maybe manipulated. */ + +extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); + +extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); +extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); + +/* @@@ Retrieve the CFA of the given context. */ +extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); + +extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *); + +extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *); + + +/* The personality routine is the function in the C++ (or other language) + runtime library which serves as an interface between the system unwind + library and language-specific exception handling semantics. It is + specific to the code fragment described by an unwind info block, and + it is always referenced via the pointer in the unwind info block, and + hence it has no ABI-specified name. + + Note that this implies that two different C++ implementations can + use different names, and have different contents in the language + specific data area. Moreover, that the language specific data + area contains no version info because name of the function invoked + provides more effective versioning by detecting at link time the + lack of code to handle the different data format. */ + +typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) + (int, _Unwind_Action, _Unwind_Exception_Class, + struct _Unwind_Exception *, struct _Unwind_Context *); + +/* @@@ The following alternate entry points are for setjmp/longjmp + based unwinding. */ + +struct SjLj_Function_Context; +extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *); +extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *); + +extern _Unwind_Reason_Code _Unwind_SjLj_RaiseException + (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind + (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); +extern void _Unwind_SjLj_Resume (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* @@@ The following provide access to the base addresses for text + and data-relative addressing in the LDSA. In order to stay link + compatible with the standard ABI for IA-64, we inline these. */ + +#ifdef __ia64__ +#include + +static inline _Unwind_Ptr +_Unwind_GetDataRelBase (struct _Unwind_Context *_C) +{ + /* The GP is stored in R1. */ + return _Unwind_GetGR (_C, 1); +} + +static inline _Unwind_Ptr +_Unwind_GetTextRelBase (struct _Unwind_Context *_C __attribute__ ((__unused__))) +{ + abort (); + return 0; +} + +/* @@@ Retrieve the Backing Store Pointer of the given context. */ +extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *); +#else +extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *); +extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *); +#endif + +/* @@@ Given an address, return the entry point of the function that + contains it. */ +extern void * _Unwind_FindEnclosingFunction (void *pc); + +#ifdef __cplusplus +} +#endif + +#ifndef HIDE_EXPORTS +#pragma GCC visibility pop +#endif + +#endif /* unwind.h */ From johannes at apple.com Mon Apr 2 19:14:25 2007 From: johannes at apple.com (johannes at apple.com) Date: Mon, 2 Apr 2007 17:14:25 -0700 (PDT) Subject: [llvm-commits] [125640] arm EABI patch (Lauro Ramos Venancio) Message-ID: <20070403001425.A434ECB811D2@src> Revision: 125640 Author: johannes Date: 2007-04-02 17:14:25 -0700 (Mon, 02 Apr 2007) Log Message: ----------- arm EABI patch (Lauro Ramos Venancio) Modified Paths: -------------- apple-local/branches/llvm/libcpp/configure apple-local/branches/llvm/libcpp/configure.ac Modified: apple-local/branches/llvm/libcpp/configure =================================================================== --- apple-local/branches/llvm/libcpp/configure 2007-04-03 00:13:59 UTC (rev 125639) +++ apple-local/branches/llvm/libcpp/configure 2007-04-03 00:14:25 UTC (rev 125640) @@ -7965,7 +7965,7 @@ case $target in # APPLE LOCAL begin 4126124 alpha*-*-* | \ - arm*-*-eabi* | \ + arm*-*-*eabi* | \ arm*-*-symbianelf* | \ x86_64-*-* | \ ia64-*-* | \ Modified: apple-local/branches/llvm/libcpp/configure.ac =================================================================== --- apple-local/branches/llvm/libcpp/configure.ac 2007-04-03 00:13:59 UTC (rev 125639) +++ apple-local/branches/llvm/libcpp/configure.ac 2007-04-03 00:14:25 UTC (rev 125640) @@ -108,7 +108,9 @@ case $target in # APPLE LOCAL begin 4126124 alpha*-*-* | \ - arm*-*-eabi* | \ + #APPLE LOCAL begin LLVM + arm*-*-*eabi* | \ + #APPLE LOCAL end LLVM arm*-*-symbianelf* | \ x86_64-*-* | \ ia64-*-* | \ From johannes at apple.com Mon Apr 2 19:16:00 2007 From: johannes at apple.com (johannes at apple.com) Date: Mon, 2 Apr 2007 17:16:00 -0700 (PDT) Subject: [llvm-commits] [125641] arm EABI patch (files I missed) (Lauro Ramos Venancio) Message-ID: <20070403001600.72A50CB813E8@src> Revision: 125641 Author: johannes Date: 2007-04-02 17:16:00 -0700 (Mon, 02 Apr 2007) Log Message: ----------- arm EABI patch (files I missed) (Lauro Ramos Venancio) Modified Paths: -------------- apple-local/branches/llvm/gcc/config/arm/arm-protos.h apple-local/branches/llvm/libstdc++-v3/testsuite/Makefile.in Modified: apple-local/branches/llvm/gcc/config/arm/arm-protos.h =================================================================== --- apple-local/branches/llvm/gcc/config/arm/arm-protos.h 2007-04-03 00:14:25 UTC (rev 125640) +++ apple-local/branches/llvm/gcc/config/arm/arm-protos.h 2007-04-03 00:16:00 UTC (rev 125641) @@ -38,6 +38,10 @@ unsigned int); extern HOST_WIDE_INT thumb_compute_initial_elimination_offset (unsigned int, unsigned int); +/* APPLE LOCAL begin LLVM */ +extern unsigned int arm_dbx_register_number (unsigned int); +extern void arm_output_fn_unwind (FILE *, bool); +/* APPLE LOCAL end LLVM */ #ifdef TREE_CODE extern int arm_return_in_memory (tree); @@ -120,6 +124,10 @@ #if defined TREE_CODE extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); +/* APPLE LOCAL begin LLVM */ +extern bool arm_pad_arg_upward (enum machine_mode, tree); +extern bool arm_pad_reg_upward (enum machine_mode, tree, int); +/* APPLE LOCAL end LLVM */ extern bool arm_needs_doubleword_align (enum machine_mode, tree); extern rtx arm_function_value(tree, tree); #endif Modified: apple-local/branches/llvm/libstdc++-v3/testsuite/Makefile.in =================================================================== --- apple-local/branches/llvm/libstdc++-v3/testsuite/Makefile.in 2007-04-03 00:14:25 UTC (rev 125640) +++ apple-local/branches/llvm/libstdc++-v3/testsuite/Makefile.in 2007-04-03 00:16:00 UTC (rev 125641) @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.3 from Makefile.am. +# Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. From sabre at nondot.org Mon Apr 2 20:41:51 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 20:41:51 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/Constants.h Message-ID: <200704030141.l331fpWq032590@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constants.h updated: 1.143 -> 1.144 --- Log message: add a helper function to constantint. --- Diffs of the changes: (+3 -0) Constants.h | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.143 llvm/include/llvm/Constants.h:1.144 --- llvm/include/llvm/Constants.h:1.143 Fri Mar 30 11:50:28 2007 +++ llvm/include/llvm/Constants.h Mon Apr 2 20:41:34 2007 @@ -52,6 +52,9 @@ inline const APInt& getValue() const { return Val; } + + /// getBitWidth - Return the bitwidth of this constant. + unsigned getBitWidth() const { return Val.getBitWidth(); } /// Return the constant as a 64-bit unsigned integer value after it /// has been zero extended as appropriate for the type of this constant. Note From sabre at nondot.org Mon Apr 2 20:45:51 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 20:45:51 -0500 Subject: [llvm-commits] CVS: llvm/test/Transforms/InstCombine/xor2.ll Message-ID: <200704030145.l331jpvY032740@zion.cs.uiuc.edu> Changes in directory llvm/test/Transforms/InstCombine: xor2.ll added (r1.1) --- Log message: new testcase for PR1253: http://llvm.org/PR1253 --- Diffs of the changes: (+19 -0) xor2.ll | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+) Index: llvm/test/Transforms/InstCombine/xor2.ll diff -c /dev/null llvm/test/Transforms/InstCombine/xor2.ll:1.1 *** /dev/null Mon Apr 2 20:45:42 2007 --- llvm/test/Transforms/InstCombine/xor2.ll Mon Apr 2 20:45:32 2007 *************** *** 0 **** --- 1,19 ---- + ; This test makes sure that these instructions are properly eliminated. + ; + + ; RUN: llvm-as < %s | opt -instcombine -disable-output && + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'xor ' + + ; PR1253 + define i1 @test0(i32 %A) { + %B = xor i32 %A, -2147483648 + %C = icmp sgt i32 %B, -1 + ret i1 %C + } + + define i1 @test1(i32 %A) { + %B = xor i32 %A, 12345 + %C = icmp slt i32 %B, 0 + ret i1 %C + } + From sabre at nondot.org Mon Apr 2 20:47:58 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 20:47:58 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200704030147.l331lwsM000383@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.723 -> 1.724 --- Log message: Fix PR1253: http://llvm.org/PR1253 and xor2.ll:test[01] --- Diffs of the changes: (+30 -1) InstructionCombining.cpp | 31 ++++++++++++++++++++++++++++++- 1 files changed, 30 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.723 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.724 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.723 Mon Apr 2 08:45:30 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Apr 2 20:47:41 2007 @@ -4714,7 +4714,36 @@ // instruction can be folded into the icmp if (Instruction *LHSI = dyn_cast(Op0)) switch (LHSI->getOpcode()) { - case Instruction::And: + case Instruction::Xor: // (icmp pred (and X, XorCST), CI) + if (ConstantInt *XorCST = dyn_cast(LHSI->getOperand(1))) { + // If this is a comparison that tests the signbit (X < 0) or (x > -1), + // fold the xor. + if (I.getPredicate() == ICmpInst::ICMP_SLT && CI->isZero() || + I.getPredicate() == ICmpInst::ICMP_SGT && CI->isAllOnesValue()) { + Value *CompareVal = LHSI->getOperand(0); + + // If the sign bit of the XorCST is not set, there is no change to + // the operation, just stop using the Xor. + if (!XorCST->getValue().isNegative()) { + I.setOperand(0, CompareVal); + AddToWorkList(LHSI); + return &I; + } + + // Was the old condition true if the operand is positive? + bool isTrueIfPositive = I.getPredicate() == ICmpInst::ICMP_SGT; + + // If so, the new one isn't. + isTrueIfPositive ^= true; + + if (isTrueIfPositive) + return new ICmpInst(ICmpInst::ICMP_SGT, CompareVal, SubOne(CI)); + else + return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(CI)); + } + } + break; + case Instruction::And: // (icmp pred (and X, AndCST), CI) if (LHSI->hasOneUse() && isa(LHSI->getOperand(1)) && LHSI->getOperand(0)->hasOneUse()) { ConstantInt *AndCST = cast(LHSI->getOperand(1)); From sabre at nondot.org Mon Apr 2 23:26:03 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 23:26:03 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/ADT/APInt.h Message-ID: <200704030426.l334Q3dY003778@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ADT: APInt.h updated: 1.61 -> 1.62 --- Log message: add missing operator --- Diffs of the changes: (+4 -0) APInt.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/ADT/APInt.h diff -u llvm/include/llvm/ADT/APInt.h:1.61 llvm/include/llvm/ADT/APInt.h:1.62 --- llvm/include/llvm/ADT/APInt.h:1.61 Mon Apr 2 00:41:00 2007 +++ llvm/include/llvm/ADT/APInt.h Mon Apr 2 23:25:46 2007 @@ -542,6 +542,10 @@ APInt operator-(uint64_t RHS) const { return (*this) - APInt(BitWidth, RHS); } + + APInt operator<<(unsigned Bits) const { + return shl(Bits); + } /// Arithmetic right-shift this APInt by shiftAmt. /// @brief Arithmetic right-shift function. From sabre at nondot.org Mon Apr 2 23:47:09 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 2 Apr 2007 23:47:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200704030447.l334l9cN004177@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.724 -> 1.725 --- Log message: Split a whole ton of code out of visitICmpInst into visitICmpInstWithInstAndIntCst. --- Diffs of the changes: (+524 -520) InstructionCombining.cpp | 1044 +++++++++++++++++++++++------------------------ 1 files changed, 524 insertions(+), 520 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.724 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.725 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.724 Mon Apr 2 20:47:41 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Apr 2 23:46:52 2007 @@ -183,6 +183,9 @@ Instruction *visitFCmpInst(FCmpInst &I); Instruction *visitICmpInst(ICmpInst &I); Instruction *visitICmpInstWithCastAndCast(ICmpInst &ICI); + Instruction *visitICmpInstWithInstAndIntCst(ICmpInst &ICI, + Instruction *LHS, + ConstantInt *RHS); Instruction *FoldGEPICmp(User *GEPLHS, Value *RHS, ICmpInst::Predicate Cond, Instruction &I); @@ -4713,525 +4716,11 @@ // instruction, see if that instruction also has constants so that the // instruction can be folded into the icmp if (Instruction *LHSI = dyn_cast(Op0)) - switch (LHSI->getOpcode()) { - case Instruction::Xor: // (icmp pred (and X, XorCST), CI) - if (ConstantInt *XorCST = dyn_cast(LHSI->getOperand(1))) { - // If this is a comparison that tests the signbit (X < 0) or (x > -1), - // fold the xor. - if (I.getPredicate() == ICmpInst::ICMP_SLT && CI->isZero() || - I.getPredicate() == ICmpInst::ICMP_SGT && CI->isAllOnesValue()) { - Value *CompareVal = LHSI->getOperand(0); - - // If the sign bit of the XorCST is not set, there is no change to - // the operation, just stop using the Xor. - if (!XorCST->getValue().isNegative()) { - I.setOperand(0, CompareVal); - AddToWorkList(LHSI); - return &I; - } - - // Was the old condition true if the operand is positive? - bool isTrueIfPositive = I.getPredicate() == ICmpInst::ICMP_SGT; - - // If so, the new one isn't. - isTrueIfPositive ^= true; - - if (isTrueIfPositive) - return new ICmpInst(ICmpInst::ICMP_SGT, CompareVal, SubOne(CI)); - else - return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(CI)); - } - } - break; - case Instruction::And: // (icmp pred (and X, AndCST), CI) - if (LHSI->hasOneUse() && isa(LHSI->getOperand(1)) && - LHSI->getOperand(0)->hasOneUse()) { - ConstantInt *AndCST = cast(LHSI->getOperand(1)); - - // If the LHS is an AND of a truncating cast, we can widen the - // and/compare to be the input width without changing the value - // produced, eliminating a cast. - if (CastInst *Cast = dyn_cast(LHSI->getOperand(0))) { - // We can do this transformation if either the AND constant does not - // have its sign bit set or if it is an equality comparison. - // Extending a relational comparison when we're checking the sign - // bit would not work. - if (Cast->hasOneUse() && isa(Cast) && - (I.isEquality() || AndCST->getValue().isPositive() && - CI->getValue().isPositive())) { - ConstantInt *NewCST; - ConstantInt *NewCI; - APInt NewCSTVal(AndCST->getValue()), NewCIVal(CI->getValue()); - uint32_t BitWidth = cast( - Cast->getOperand(0)->getType())->getBitWidth(); - NewCST = ConstantInt::get(NewCSTVal.zext(BitWidth)); - NewCI = ConstantInt::get(NewCIVal.zext(BitWidth)); - Instruction *NewAnd = - BinaryOperator::createAnd(Cast->getOperand(0), NewCST, - LHSI->getName()); - InsertNewInstBefore(NewAnd, I); - return new ICmpInst(I.getPredicate(), NewAnd, NewCI); - } - } - - // If this is: (X >> C1) & C2 != C3 (where any shift and any compare - // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This - // happens a LOT in code produced by the C front-end, for bitfield - // access. - BinaryOperator *Shift = dyn_cast(LHSI->getOperand(0)); - if (Shift && !Shift->isShift()) - Shift = 0; - - ConstantInt *ShAmt; - ShAmt = Shift ? dyn_cast(Shift->getOperand(1)) : 0; - const Type *Ty = Shift ? Shift->getType() : 0; // Type of the shift. - const Type *AndTy = AndCST->getType(); // Type of the and. - - // We can fold this as long as we can't shift unknown bits - // into the mask. This can only happen with signed shift - // rights, as they sign-extend. - if (ShAmt) { - bool CanFold = Shift->isLogicalShift(); - if (!CanFold) { - // To test for the bad case of the signed shr, see if any - // of the bits shifted in could be tested after the mask. - uint32_t TyBits = Ty->getPrimitiveSizeInBits(); - int ShAmtVal = TyBits - ShAmt->getLimitedValue(TyBits); - - uint32_t BitWidth = AndTy->getPrimitiveSizeInBits(); - if ((APInt::getHighBitsSet(BitWidth, BitWidth-ShAmtVal) & - AndCST->getValue()) == 0) - CanFold = true; - } - - if (CanFold) { - Constant *NewCst; - if (Shift->getOpcode() == Instruction::Shl) - NewCst = ConstantExpr::getLShr(CI, ShAmt); - else - NewCst = ConstantExpr::getShl(CI, ShAmt); - - // Check to see if we are shifting out any of the bits being - // compared. - if (ConstantExpr::get(Shift->getOpcode(), NewCst, ShAmt) != CI){ - // If we shifted bits out, the fold is not going to work out. - // As a special case, check to see if this means that the - // result is always true or false now. - if (I.getPredicate() == ICmpInst::ICMP_EQ) - return ReplaceInstUsesWith(I, ConstantInt::getFalse()); - if (I.getPredicate() == ICmpInst::ICMP_NE) - return ReplaceInstUsesWith(I, ConstantInt::getTrue()); - } else { - I.setOperand(1, NewCst); - Constant *NewAndCST; - if (Shift->getOpcode() == Instruction::Shl) - NewAndCST = ConstantExpr::getLShr(AndCST, ShAmt); - else - NewAndCST = ConstantExpr::getShl(AndCST, ShAmt); - LHSI->setOperand(1, NewAndCST); - LHSI->setOperand(0, Shift->getOperand(0)); - AddToWorkList(Shift); // Shift is dead. - AddUsesToWorkList(I); - return &I; - } - } - } - - // Turn ((X >> Y) & C) == 0 into (X & (C << Y)) == 0. The later is - // preferable because it allows the C<hasOneUse() && CI->isNullValue() && - I.isEquality() && !Shift->isArithmeticShift() && - isa(Shift->getOperand(0))) { - // Compute C << Y. - Value *NS; - if (Shift->getOpcode() == Instruction::LShr) { - NS = BinaryOperator::createShl(AndCST, - Shift->getOperand(1), "tmp"); - } else { - // Insert a logical shift. - NS = BinaryOperator::createLShr(AndCST, - Shift->getOperand(1), "tmp"); - } - InsertNewInstBefore(cast(NS), I); - - // Compute X & (C << Y). - Instruction *NewAnd = BinaryOperator::createAnd( - Shift->getOperand(0), NS, LHSI->getName()); - InsertNewInstBefore(NewAnd, I); - - I.setOperand(0, NewAnd); - return &I; - } - } - break; - - case Instruction::Shl: // (icmp pred (shl X, ShAmt), CI) - if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { - if (I.isEquality()) { - uint32_t TypeBits = CI->getType()->getPrimitiveSizeInBits(); - - // Check that the shift amount is in range. If not, don't perform - // undefined shifts. When the shift is visited it will be - // simplified. - if (ShAmt->uge(TypeBits)) - break; - - // If we are comparing against bits always shifted out, the - // comparison cannot succeed. - Constant *Comp = - ConstantExpr::getShl(ConstantExpr::getLShr(CI, ShAmt), ShAmt); - if (Comp != CI) {// Comparing against a bit that we know is zero. - bool IsICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE; - Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE); - return ReplaceInstUsesWith(I, Cst); - } - - if (LHSI->hasOneUse()) { - // Otherwise strength reduce the shift into an and. - uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); - Constant *Mask = ConstantInt::get( - APInt::getLowBitsSet(TypeBits, TypeBits-ShAmtVal)); - - Instruction *AndI = - BinaryOperator::createAnd(LHSI->getOperand(0), - Mask, LHSI->getName()+".mask"); - Value *And = InsertNewInstBefore(AndI, I); - return new ICmpInst(I.getPredicate(), And, - ConstantExpr::getLShr(CI, ShAmt)); - } - } - } - break; - - case Instruction::LShr: // (icmp pred (shr X, ShAmt), CI) - case Instruction::AShr: - if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { - if (I.isEquality()) { - // Check that the shift amount is in range. If not, don't perform - // undefined shifts. When the shift is visited it will be - // simplified. - uint32_t TypeBits = CI->getType()->getPrimitiveSizeInBits(); - if (ShAmt->uge(TypeBits)) - break; - - // If we are comparing against bits always shifted out, the - // comparison cannot succeed. - Constant *Comp; - if (LHSI->getOpcode() == Instruction::LShr) - Comp = ConstantExpr::getLShr(ConstantExpr::getShl(CI, ShAmt), - ShAmt); - else - Comp = ConstantExpr::getAShr(ConstantExpr::getShl(CI, ShAmt), - ShAmt); - - if (Comp != CI) {// Comparing against a bit that we know is zero. - bool IsICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE; - Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE); - return ReplaceInstUsesWith(I, Cst); - } - - if (LHSI->hasOneUse() || CI->isNullValue()) { - uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); - - // Otherwise strength reduce the shift into an and. - APInt Val(APInt::getHighBitsSet(TypeBits, TypeBits - ShAmtVal)); - Constant *Mask = ConstantInt::get(Val); - - Instruction *AndI = - BinaryOperator::createAnd(LHSI->getOperand(0), - Mask, LHSI->getName()+".mask"); - Value *And = InsertNewInstBefore(AndI, I); - return new ICmpInst(I.getPredicate(), And, - ConstantExpr::getShl(CI, ShAmt)); - } - } - } - break; - - case Instruction::SDiv: - case Instruction::UDiv: - // Fold: icmp pred ([us]div X, C1), C2 -> range test - // Fold this div into the comparison, producing a range check. - // Determine, based on the divide type, what the range is being - // checked. If there is an overflow on the low or high side, remember - // it, otherwise compute the range [low, hi) bounding the new value. - // See: InsertRangeTest above for the kinds of replacements possible. - if (ConstantInt *DivRHS = dyn_cast(LHSI->getOperand(1))) { - // FIXME: If the operand types don't match the type of the divide - // then don't attempt this transform. The code below doesn't have the - // logic to deal with a signed divide and an unsigned compare (and - // vice versa). This is because (x /s C1) getOpcode() == Instruction::SDiv; - if (!I.isEquality() && DivIsSigned != I.isSignedPredicate()) - break; - if (DivRHS->isZero()) - break; // Don't hack on div by zero - - // Initialize the variables that will indicate the nature of the - // range check. - bool LoOverflow = false, HiOverflow = false; - ConstantInt *LoBound = 0, *HiBound = 0; - - // Compute Prod = CI * DivRHS. We are essentially solving an equation - // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and - // C2 (CI). By solving for X we can turn this into a range check - // instead of computing a divide. - ConstantInt *Prod = Multiply(CI, DivRHS); - - // Determine if the product overflows by seeing if the product is - // not equal to the divide. Make sure we do the same kind of divide - // as in the LHS instruction that we're folding. - bool ProdOV = (DivIsSigned ? ConstantExpr::getSDiv(Prod, DivRHS) : - ConstantExpr::getUDiv(Prod, DivRHS)) != CI; - - // Get the ICmp opcode - ICmpInst::Predicate predicate = I.getPredicate(); - - if (!DivIsSigned) { // udiv - LoBound = Prod; - LoOverflow = ProdOV; - HiOverflow = ProdOV || - AddWithOverflow(HiBound, LoBound, DivRHS, false); - } else if (DivRHS->getValue().isPositive()) { // Divisor is > 0. - if (CI->isNullValue()) { // (X / pos) op 0 - // Can't overflow. - LoBound = cast(ConstantExpr::getNeg(SubOne(DivRHS))); - HiBound = DivRHS; - } else if (CI->getValue().isPositive()) { // (X / pos) op pos - LoBound = Prod; - LoOverflow = ProdOV; - HiOverflow = ProdOV || - AddWithOverflow(HiBound, Prod, DivRHS, true); - } else { // (X / pos) op neg - Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS)); - LoOverflow = AddWithOverflow(LoBound, Prod, - cast(DivRHSH), true); - HiBound = AddOne(Prod); - HiOverflow = ProdOV; - } - } else { // Divisor is < 0. - if (CI->isNullValue()) { // (X / neg) op 0 - LoBound = AddOne(DivRHS); - HiBound = cast(ConstantExpr::getNeg(DivRHS)); - if (HiBound == DivRHS) - LoBound = 0; // - INTMIN = INTMIN - } else if (CI->getValue().isPositive()) { // (X / neg) op pos - HiOverflow = LoOverflow = ProdOV; - if (!LoOverflow) - LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS), - true); - HiBound = AddOne(Prod); - } else { // (X / neg) op neg - LoBound = Prod; - LoOverflow = HiOverflow = ProdOV; - HiBound = Subtract(Prod, DivRHS); - } - - // Dividing by a negate swaps the condition. - predicate = ICmpInst::getSwappedPredicate(predicate); - } - - if (LoBound) { - Value *X = LHSI->getOperand(0); - switch (predicate) { - default: assert(0 && "Unhandled icmp opcode!"); - case ICmpInst::ICMP_EQ: - if (LoOverflow && HiOverflow) - return ReplaceInstUsesWith(I, ConstantInt::getFalse()); - else if (HiOverflow) - return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : - ICmpInst::ICMP_UGE, X, LoBound); - else if (LoOverflow) - return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : - ICmpInst::ICMP_ULT, X, HiBound); - else - return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, - true, I); - case ICmpInst::ICMP_NE: - if (LoOverflow && HiOverflow) - return ReplaceInstUsesWith(I, ConstantInt::getTrue()); - else if (HiOverflow) - return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : - ICmpInst::ICMP_ULT, X, LoBound); - else if (LoOverflow) - return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : - ICmpInst::ICMP_UGE, X, HiBound); - else - return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, - false, I); - case ICmpInst::ICMP_ULT: - case ICmpInst::ICMP_SLT: - if (LoOverflow) - return ReplaceInstUsesWith(I, ConstantInt::getFalse()); - return new ICmpInst(predicate, X, LoBound); - case ICmpInst::ICMP_UGT: - case ICmpInst::ICMP_SGT: - if (HiOverflow) - return ReplaceInstUsesWith(I, ConstantInt::getFalse()); - if (predicate == ICmpInst::ICMP_UGT) - return new ICmpInst(ICmpInst::ICMP_UGE, X, HiBound); - else - return new ICmpInst(ICmpInst::ICMP_SGE, X, HiBound); - } - } - } - break; - } - - // Simplify icmp_eq and icmp_ne instructions with integer constant RHS. - if (I.isEquality()) { - bool isICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE; - - // If the first operand is (add|sub|and|or|xor|rem) with a constant, and - // the second operand is a constant, simplify a bit. - if (BinaryOperator *BO = dyn_cast(Op0)) { - switch (BO->getOpcode()) { - case Instruction::SRem: - // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one. - if (CI->isZero() && isa(BO->getOperand(1)) && - BO->hasOneUse()) { - const APInt& V = cast(BO->getOperand(1))->getValue(); - if (V.sgt(APInt(V.getBitWidth(), 1)) && V.isPowerOf2()) { - Value *NewRem = InsertNewInstBefore(BinaryOperator::createURem( - BO->getOperand(0), BO->getOperand(1), BO->getName()), I); - return new ICmpInst(I.getPredicate(), NewRem, - Constant::getNullValue(BO->getType())); - } - } - break; - case Instruction::Add: - // Replace ((add A, B) != C) with (A != C-B) if B & C are constants. - if (ConstantInt *BOp1C = dyn_cast(BO->getOperand(1))) { - if (BO->hasOneUse()) - return new ICmpInst(I.getPredicate(), BO->getOperand(0), - Subtract(CI, BOp1C)); - } else if (CI->isNullValue()) { - // Replace ((add A, B) != 0) with (A != -B) if A or B is - // efficiently invertible, or if the add has just this one use. - Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1); - - if (Value *NegVal = dyn_castNegVal(BOp1)) - return new ICmpInst(I.getPredicate(), BOp0, NegVal); - else if (Value *NegVal = dyn_castNegVal(BOp0)) - return new ICmpInst(I.getPredicate(), NegVal, BOp1); - else if (BO->hasOneUse()) { - Instruction *Neg = BinaryOperator::createNeg(BOp1); - InsertNewInstBefore(Neg, I); - Neg->takeName(BO); - return new ICmpInst(I.getPredicate(), BOp0, Neg); - } - } - break; - case Instruction::Xor: - // For the xor case, we can xor two constants together, eliminating - // the explicit xor. - if (Constant *BOC = dyn_cast(BO->getOperand(1))) - return new ICmpInst(I.getPredicate(), BO->getOperand(0), - ConstantExpr::getXor(CI, BOC)); - - // FALLTHROUGH - case Instruction::Sub: - // Replace (([sub|xor] A, B) != 0) with (A != B) - if (CI->isZero()) - return new ICmpInst(I.getPredicate(), BO->getOperand(0), - BO->getOperand(1)); - break; - - case Instruction::Or: - // If bits are being or'd in that are not present in the constant we - // are comparing against, then the comparison could never succeed! - if (Constant *BOC = dyn_cast(BO->getOperand(1))) { - Constant *NotCI = ConstantExpr::getNot(CI); - if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue()) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, - isICMP_NE)); - } - break; - - case Instruction::And: - if (ConstantInt *BOC = dyn_cast(BO->getOperand(1))) { - // If bits are being compared against that are and'd out, then the - // comparison can never succeed! - if (!And(CI, ConstantInt::get(~BOC->getValue()))->isZero()) - return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, - isICMP_NE)); - - // If we have ((X & C) == C), turn it into ((X & C) != 0). - if (CI == BOC && isOneBitSet(CI)) - return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : - ICmpInst::ICMP_NE, Op0, - Constant::getNullValue(CI->getType())); - - // Replace (and X, (1 << size(X)-1) != 0) with x s< 0 - if (isSignBit(BOC)) { - Value *X = BO->getOperand(0); - Constant *Zero = Constant::getNullValue(X->getType()); - ICmpInst::Predicate pred = isICMP_NE ? - ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE; - return new ICmpInst(pred, X, Zero); - } - - // ((X & ~7) == 0) --> X < 8 - if (CI->isNullValue() && isHighOnes(BOC)) { - Value *X = BO->getOperand(0); - Constant *NegX = ConstantExpr::getNeg(BOC); - ICmpInst::Predicate pred = isICMP_NE ? - ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT; - return new ICmpInst(pred, X, NegX); - } - - } - default: break; - } - } else if (IntrinsicInst *II = dyn_cast(Op0)) { - // Handle icmp {eq|ne} , intcst. - if (II->getIntrinsicID() == Intrinsic::bswap) { - AddToWorkList(II); - I.setOperand(0, II->getOperand(1)); - I.setOperand(1, ConstantInt::get(CI->getValue().byteSwap())); - return &I; - } - } - } else { // Not a ICMP_EQ/ICMP_NE - // If the LHS is a cast from an integral value of the same size, then - // since we know the RHS is a constant, try to simlify. - if (CastInst *Cast = dyn_cast(Op0)) { - Value *CastOp = Cast->getOperand(0); - const Type *SrcTy = CastOp->getType(); - uint32_t SrcTySize = SrcTy->getPrimitiveSizeInBits(); - if (SrcTy->isInteger() && - SrcTySize == Cast->getType()->getPrimitiveSizeInBits()) { - // If this is an unsigned comparison, try to make the comparison use - // smaller constant values. - switch (I.getPredicate()) { - default: break; - case ICmpInst::ICMP_ULT: { // X u< 128 => X s> -1 - ConstantInt *CUI = cast(CI); - if (CUI->getValue() == APInt::getSignBit(SrcTySize)) - return new ICmpInst(ICmpInst::ICMP_SGT, CastOp, - ConstantInt::get(APInt::getAllOnesValue(SrcTySize))); - break; - } - case ICmpInst::ICMP_UGT: { // X u> 127 => X s< 0 - ConstantInt *CUI = cast(CI); - if (CUI->getValue() == APInt::getSignedMaxValue(SrcTySize)) - return new ICmpInst(ICmpInst::ICMP_SLT, CastOp, - Constant::getNullValue(SrcTy)); - break; - } - } - - } - } - } + if (Instruction *Res = visitICmpInstWithInstAndIntCst(I, LHSI, CI)) + return Res; } - // Handle icmp with constant RHS + // Handle icmp with constant (but not simple integer constant) RHS if (Constant *RHSC = dyn_cast(Op1)) { if (Instruction *LHSI = dyn_cast(Op0)) switch (LHSI->getOpcode()) { @@ -5406,9 +4895,524 @@ return Changed ? &I : 0; } -// visitICmpInstWithCastAndCast - Handle icmp (cast x to y), (cast/cst). -// We only handle extending casts so far. -// +/// visitICmpInstWithInstAndIntCst - Handle "icmp (instr, intcst)". +/// +Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, + Instruction *LHSI, + ConstantInt *RHS) { + const APInt &RHSV = RHS->getValue(); + + switch (LHSI->getOpcode()) { + case Instruction::Xor: // (icmp pred (and X, XorCST), CI) + if (ConstantInt *XorCST = dyn_cast(LHSI->getOperand(1))) { + // If this is a comparison that tests the signbit (X < 0) or (x > -1), + // fold the xor. + if (ICI.getPredicate() == ICmpInst::ICMP_SLT && RHSV == 0 || + ICI.getPredicate() == ICmpInst::ICMP_SGT && RHSV.isAllOnesValue()) { + Value *CompareVal = LHSI->getOperand(0); + + // If the sign bit of the XorCST is not set, there is no change to + // the operation, just stop using the Xor. + if (!XorCST->getValue().isNegative()) { + ICI.setOperand(0, CompareVal); + AddToWorkList(LHSI); + return &ICI; + } + + // Was the old condition true if the operand is positive? + bool isTrueIfPositive = ICI.getPredicate() == ICmpInst::ICMP_SGT; + + // If so, the new one isn't. + isTrueIfPositive ^= true; + + if (isTrueIfPositive) + return new ICmpInst(ICmpInst::ICMP_SGT, CompareVal, SubOne(RHS)); + else + return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(RHS)); + } + } + break; + case Instruction::And: // (icmp pred (and X, AndCST), RHS) + if (LHSI->hasOneUse() && isa(LHSI->getOperand(1)) && + LHSI->getOperand(0)->hasOneUse()) { + ConstantInt *AndCST = cast(LHSI->getOperand(1)); + + // If the LHS is an AND of a truncating cast, we can widen the + // and/compare to be the input width without changing the value + // produced, eliminating a cast. + if (CastInst *Cast = dyn_cast(LHSI->getOperand(0))) { + // We can do this transformation if either the AND constant does not + // have its sign bit set or if it is an equality comparison. + // Extending a relational comparison when we're checking the sign + // bit would not work. + if (Cast->hasOneUse() && isa(Cast) && + (ICI.isEquality() || AndCST->getValue().isPositive() && + RHSV.isPositive())) { + ConstantInt *NewCST; + ConstantInt *NewCI; + APInt NewCSTVal(AndCST->getValue()), NewCIVal(RHSV); + uint32_t BitWidth = + cast(Cast->getOperand(0)->getType())->getBitWidth(); + NewCST = ConstantInt::get(NewCSTVal.zext(BitWidth)); + NewCI = ConstantInt::get(NewCIVal.zext(BitWidth)); + Instruction *NewAnd = + BinaryOperator::createAnd(Cast->getOperand(0), NewCST, + LHSI->getName()); + InsertNewInstBefore(NewAnd, ICI); + return new ICmpInst(ICI.getPredicate(), NewAnd, NewCI); + } + } + + // If this is: (X >> C1) & C2 != C3 (where any shift and any compare + // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This + // happens a LOT in code produced by the C front-end, for bitfield + // access. + BinaryOperator *Shift = dyn_cast(LHSI->getOperand(0)); + if (Shift && !Shift->isShift()) + Shift = 0; + + ConstantInt *ShAmt; + ShAmt = Shift ? dyn_cast(Shift->getOperand(1)) : 0; + const Type *Ty = Shift ? Shift->getType() : 0; // Type of the shift. + const Type *AndTy = AndCST->getType(); // Type of the and. + + // We can fold this as long as we can't shift unknown bits + // into the mask. This can only happen with signed shift + // rights, as they sign-extend. + if (ShAmt) { + bool CanFold = Shift->isLogicalShift(); + if (!CanFold) { + // To test for the bad case of the signed shr, see if any + // of the bits shifted in could be tested after the mask. + uint32_t TyBits = Ty->getPrimitiveSizeInBits(); + int ShAmtVal = TyBits - ShAmt->getLimitedValue(TyBits); + + uint32_t BitWidth = AndTy->getPrimitiveSizeInBits(); + if ((APInt::getHighBitsSet(BitWidth, BitWidth-ShAmtVal) & + AndCST->getValue()) == 0) + CanFold = true; + } + + if (CanFold) { + Constant *NewCst; + if (Shift->getOpcode() == Instruction::Shl) + NewCst = ConstantExpr::getLShr(RHS, ShAmt); + else + NewCst = ConstantExpr::getShl(RHS, ShAmt); + + // Check to see if we are shifting out any of the bits being + // compared. + if (ConstantExpr::get(Shift->getOpcode(), NewCst, ShAmt) != RHS) { + // If we shifted bits out, the fold is not going to work out. + // As a special case, check to see if this means that the + // result is always true or false now. + if (ICI.getPredicate() == ICmpInst::ICMP_EQ) + return ReplaceInstUsesWith(ICI, ConstantInt::getFalse()); + if (ICI.getPredicate() == ICmpInst::ICMP_NE) + return ReplaceInstUsesWith(ICI, ConstantInt::getTrue()); + } else { + ICI.setOperand(1, NewCst); + Constant *NewAndCST; + if (Shift->getOpcode() == Instruction::Shl) + NewAndCST = ConstantExpr::getLShr(AndCST, ShAmt); + else + NewAndCST = ConstantExpr::getShl(AndCST, ShAmt); + LHSI->setOperand(1, NewAndCST); + LHSI->setOperand(0, Shift->getOperand(0)); + AddToWorkList(Shift); // Shift is dead. + AddUsesToWorkList(ICI); + return &ICI; + } + } + } + + // Turn ((X >> Y) & C) == 0 into (X & (C << Y)) == 0. The later is + // preferable because it allows the C<hasOneUse() && RHSV == 0 && + ICI.isEquality() && !Shift->isArithmeticShift() && + isa(Shift->getOperand(0))) { + // Compute C << Y. + Value *NS; + if (Shift->getOpcode() == Instruction::LShr) { + NS = BinaryOperator::createShl(AndCST, + Shift->getOperand(1), "tmp"); + } else { + // Insert a logical shift. + NS = BinaryOperator::createLShr(AndCST, + Shift->getOperand(1), "tmp"); + } + InsertNewInstBefore(cast(NS), ICI); + + // Compute X & (C << Y). + Instruction *NewAnd = + BinaryOperator::createAnd(Shift->getOperand(0), NS, LHSI->getName()); + InsertNewInstBefore(NewAnd, ICI); + + ICI.setOperand(0, NewAnd); + return &ICI; + } + } + break; + + case Instruction::Shl: // (icmp pred (shl X, ShAmt), CI) + if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { + if (ICI.isEquality()) { + uint32_t TypeBits = RHSV.getBitWidth(); + + // Check that the shift amount is in range. If not, don't perform + // undefined shifts. When the shift is visited it will be + // simplified. + if (ShAmt->uge(TypeBits)) + break; + + // If we are comparing against bits always shifted out, the + // comparison cannot succeed. + Constant *Comp = + ConstantExpr::getShl(ConstantExpr::getLShr(RHS, ShAmt), ShAmt); + if (Comp != RHS) {// Comparing against a bit that we know is zero. + bool IsICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE; + Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE); + return ReplaceInstUsesWith(ICI, Cst); + } + + if (LHSI->hasOneUse()) { + // Otherwise strength reduce the shift into an and. + uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); + Constant *Mask = + ConstantInt::get(APInt::getLowBitsSet(TypeBits, TypeBits-ShAmtVal)); + + Instruction *AndI = + BinaryOperator::createAnd(LHSI->getOperand(0), + Mask, LHSI->getName()+".mask"); + Value *And = InsertNewInstBefore(AndI, ICI); + return new ICmpInst(ICI.getPredicate(), And, + ConstantInt::get(RHSV << ShAmtVal)); + } + } + } + break; + + case Instruction::LShr: // (icmp pred (shr X, ShAmt), CI) + case Instruction::AShr: + if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { + if (ICI.isEquality()) { + // Check that the shift amount is in range. If not, don't perform + // undefined shifts. When the shift is visited it will be + // simplified. + uint32_t TypeBits = RHSV.getBitWidth(); + if (ShAmt->uge(TypeBits)) + break; + uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); + + // If we are comparing against bits always shifted out, the + // comparison cannot succeed. + APInt Comp = RHSV << ShAmtVal; + if (LHSI->getOpcode() == Instruction::LShr) + Comp = Comp.lshr(ShAmtVal); + else + Comp = Comp.ashr(ShAmtVal); + + if (Comp != RHSV) { // Comparing against a bit that we know is zero. + bool IsICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE; + Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE); + return ReplaceInstUsesWith(ICI, Cst); + } + + if (LHSI->hasOneUse() || RHSV == 0) { + // Otherwise strength reduce the shift into an and. + APInt Val(APInt::getHighBitsSet(TypeBits, TypeBits - ShAmtVal)); + Constant *Mask = ConstantInt::get(Val); + + Instruction *AndI = + BinaryOperator::createAnd(LHSI->getOperand(0), + Mask, LHSI->getName()+".mask"); + Value *And = InsertNewInstBefore(AndI, ICI); + return new ICmpInst(ICI.getPredicate(), And, + ConstantExpr::getShl(RHS, ShAmt)); + } + } + } + break; + + case Instruction::SDiv: + case Instruction::UDiv: + // Fold: icmp pred ([us]div X, C1), C2 -> range test + // Fold this div into the comparison, producing a range check. + // Determine, based on the divide type, what the range is being + // checked. If there is an overflow on the low or high side, remember + // it, otherwise compute the range [low, hi) bounding the new value. + // See: InsertRangeTest above for the kinds of replacements possible. + if (ConstantInt *DivRHS = dyn_cast(LHSI->getOperand(1))) { + // FIXME: If the operand types don't match the type of the divide + // then don't attempt this transform. The code below doesn't have the + // logic to deal with a signed divide and an unsigned compare (and + // vice versa). This is because (x /s C1) getOpcode() == Instruction::SDiv; + if (!ICI.isEquality() && DivIsSigned != ICI.isSignedPredicate()) + break; + if (DivRHS->isZero()) + break; // Don't hack on div by zero + + // Initialize the variables that will indicate the nature of the + // range check. + bool LoOverflow = false, HiOverflow = false; + ConstantInt *LoBound = 0, *HiBound = 0; + + // Compute Prod = CI * DivRHS. We are essentially solving an equation + // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and + // C2 (CI). By solving for X we can turn this into a range check + // instead of computing a divide. + ConstantInt *Prod = Multiply(RHS, DivRHS); + + // Determine if the product overflows by seeing if the product is + // not equal to the divide. Make sure we do the same kind of divide + // as in the LHS instruction that we're folding. + bool ProdOV = (DivIsSigned ? ConstantExpr::getSDiv(Prod, DivRHS) : + ConstantExpr::getUDiv(Prod, DivRHS)) != RHS; + + // Get the ICmp opcode + ICmpInst::Predicate predicate = ICI.getPredicate(); + + if (!DivIsSigned) { // udiv + LoBound = Prod; + LoOverflow = ProdOV; + HiOverflow = ProdOV || + AddWithOverflow(HiBound, LoBound, DivRHS, false); + } else if (DivRHS->getValue().isPositive()) { // Divisor is > 0. + if (RHSV == 0) { // (X / pos) op 0 + // Can't overflow. + LoBound = cast(ConstantExpr::getNeg(SubOne(DivRHS))); + HiBound = DivRHS; + } else if (RHSV.isPositive()) { // (X / pos) op pos + LoBound = Prod; + LoOverflow = ProdOV; + HiOverflow = ProdOV || + AddWithOverflow(HiBound, Prod, DivRHS, true); + } else { // (X / pos) op neg + Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS)); + LoOverflow = AddWithOverflow(LoBound, Prod, + cast(DivRHSH), true); + HiBound = AddOne(Prod); + HiOverflow = ProdOV; + } + } else { // Divisor is < 0. + if (RHSV == 0) { // (X / neg) op 0 + LoBound = AddOne(DivRHS); + HiBound = cast(ConstantExpr::getNeg(DivRHS)); + if (HiBound == DivRHS) + LoBound = 0; // - INTMIN = INTMIN + } else if (RHSV.isPositive()) { // (X / neg) op pos + HiOverflow = LoOverflow = ProdOV; + if (!LoOverflow) + LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS), + true); + HiBound = AddOne(Prod); + } else { // (X / neg) op neg + LoBound = Prod; + LoOverflow = HiOverflow = ProdOV; + HiBound = Subtract(Prod, DivRHS); + } + + // Dividing by a negate swaps the condition. + predicate = ICmpInst::getSwappedPredicate(predicate); + } + + if (LoBound) { + Value *X = LHSI->getOperand(0); + switch (predicate) { + default: assert(0 && "Unhandled icmp opcode!"); + case ICmpInst::ICMP_EQ: + if (LoOverflow && HiOverflow) + return ReplaceInstUsesWith(ICI, ConstantInt::getFalse()); + else if (HiOverflow) + return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : + ICmpInst::ICMP_UGE, X, LoBound); + else if (LoOverflow) + return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : + ICmpInst::ICMP_ULT, X, HiBound); + else + return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, + true, ICI); + case ICmpInst::ICMP_NE: + if (LoOverflow && HiOverflow) + return ReplaceInstUsesWith(ICI, ConstantInt::getTrue()); + else if (HiOverflow) + return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : + ICmpInst::ICMP_ULT, X, LoBound); + else if (LoOverflow) + return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : + ICmpInst::ICMP_UGE, X, HiBound); + else + return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, + false, ICI); + case ICmpInst::ICMP_ULT: + case ICmpInst::ICMP_SLT: + if (LoOverflow) + return ReplaceInstUsesWith(ICI, ConstantInt::getFalse()); + return new ICmpInst(predicate, X, LoBound); + case ICmpInst::ICMP_UGT: + case ICmpInst::ICMP_SGT: + if (HiOverflow) + return ReplaceInstUsesWith(ICI, ConstantInt::getFalse()); + if (predicate == ICmpInst::ICMP_UGT) + return new ICmpInst(ICmpInst::ICMP_UGE, X, HiBound); + else + return new ICmpInst(ICmpInst::ICMP_SGE, X, HiBound); + } + } + } + break; + } + + // Simplify icmp_eq and icmp_ne instructions with integer constant RHS. + if (ICI.isEquality()) { + bool isICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE; + + // If the first operand is (add|sub|and|or|xor|rem) with a constant, and + // the second operand is a constant, simplify a bit. + if (BinaryOperator *BO = dyn_cast(LHSI)) { + switch (BO->getOpcode()) { + case Instruction::SRem: + // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one. + if (RHSV == 0 && isa(BO->getOperand(1)) &&BO->hasOneUse()){ + const APInt &V = cast(BO->getOperand(1))->getValue(); + if (V.sgt(APInt(V.getBitWidth(), 1)) && V.isPowerOf2()) { + Instruction *NewRem = + BinaryOperator::createURem(BO->getOperand(0), BO->getOperand(1), + BO->getName()); + InsertNewInstBefore(NewRem, ICI); + return new ICmpInst(ICI.getPredicate(), NewRem, + Constant::getNullValue(BO->getType())); + } + } + break; + case Instruction::Add: + // Replace ((add A, B) != C) with (A != C-B) if B & C are constants. + if (ConstantInt *BOp1C = dyn_cast(BO->getOperand(1))) { + if (BO->hasOneUse()) + return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), + Subtract(RHS, BOp1C)); + } else if (RHSV == 0) { + // Replace ((add A, B) != 0) with (A != -B) if A or B is + // efficiently invertible, or if the add has just this one use. + Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1); + + if (Value *NegVal = dyn_castNegVal(BOp1)) + return new ICmpInst(ICI.getPredicate(), BOp0, NegVal); + else if (Value *NegVal = dyn_castNegVal(BOp0)) + return new ICmpInst(ICI.getPredicate(), NegVal, BOp1); + else if (BO->hasOneUse()) { + Instruction *Neg = BinaryOperator::createNeg(BOp1); + InsertNewInstBefore(Neg, ICI); + Neg->takeName(BO); + return new ICmpInst(ICI.getPredicate(), BOp0, Neg); + } + } + break; + case Instruction::Xor: + // For the xor case, we can xor two constants together, eliminating + // the explicit xor. + if (Constant *BOC = dyn_cast(BO->getOperand(1))) + return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), + ConstantExpr::getXor(RHS, BOC)); + + // FALLTHROUGH + case Instruction::Sub: + // Replace (([sub|xor] A, B) != 0) with (A != B) + if (RHSV == 0) + return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), + BO->getOperand(1)); + break; + + case Instruction::Or: + // If bits are being or'd in that are not present in the constant we + // are comparing against, then the comparison could never succeed! + if (Constant *BOC = dyn_cast(BO->getOperand(1))) { + Constant *NotCI = ConstantExpr::getNot(RHS); + if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue()) + return ReplaceInstUsesWith(ICI, ConstantInt::get(Type::Int1Ty, + isICMP_NE)); + } + break; + + case Instruction::And: + if (ConstantInt *BOC = dyn_cast(BO->getOperand(1))) { + // If bits are being compared against that are and'd out, then the + // comparison can never succeed! + if ((RHSV & ~BOC->getValue()) != 0) + return ReplaceInstUsesWith(ICI, ConstantInt::get(Type::Int1Ty, + isICMP_NE)); + + // If we have ((X & C) == C), turn it into ((X & C) != 0). + if (RHS == BOC && RHSV.isPowerOf2()) + return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : + ICmpInst::ICMP_NE, RHS, + Constant::getNullValue(RHS->getType())); + + // Replace (and X, (1 << size(X)-1) != 0) with x s< 0 + if (isSignBit(BOC)) { + Value *X = BO->getOperand(0); + Constant *Zero = Constant::getNullValue(X->getType()); + ICmpInst::Predicate pred = isICMP_NE ? + ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE; + return new ICmpInst(pred, X, Zero); + } + + // ((X & ~7) == 0) --> X < 8 + if (RHSV == 0 && isHighOnes(BOC)) { + Value *X = BO->getOperand(0); + Constant *NegX = ConstantExpr::getNeg(BOC); + ICmpInst::Predicate pred = isICMP_NE ? + ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT; + return new ICmpInst(pred, X, NegX); + } + } + default: break; + } + } else if (IntrinsicInst *II = dyn_cast(LHSI)) { + // Handle icmp {eq|ne} , intcst. + if (II->getIntrinsicID() == Intrinsic::bswap) { + AddToWorkList(II); + ICI.setOperand(0, II->getOperand(1)); + ICI.setOperand(1, ConstantInt::get(RHSV.byteSwap())); + return &ICI; + } + } + } else { // Not a ICMP_EQ/ICMP_NE + // If the LHS is a cast from an integral value of the same size, then + // since we know the RHS is a constant, try to simlify. + if (CastInst *Cast = dyn_cast(LHSI)) { + Value *CastOp = Cast->getOperand(0); + const Type *SrcTy = CastOp->getType(); + uint32_t SrcTySize = SrcTy->getPrimitiveSizeInBits(); + if (SrcTy->isInteger() && + SrcTySize == Cast->getType()->getPrimitiveSizeInBits()) { + // If this is an unsigned comparison, try to make the comparison use + // smaller constant values. + if (ICI.getPredicate() == ICmpInst::ICMP_ULT && RHSV.isSignBit()) { + // X u< 128 => X s> -1 + return new ICmpInst(ICmpInst::ICMP_SGT, CastOp, + ConstantInt::get(APInt::getAllOnesValue(SrcTySize))); + } else if (ICI.getPredicate() == ICmpInst::ICMP_UGT && + RHSV == APInt::getSignedMaxValue(SrcTySize)) { + // X u> 127 => X s< 0 + return new ICmpInst(ICmpInst::ICMP_SLT, CastOp, + Constant::getNullValue(SrcTy)); + } + } + } + } + return 0; +} + +/// visitICmpInstWithCastAndCast - Handle icmp (cast x to y), (cast/cst). +/// We only handle extending casts so far. +/// Instruction *InstCombiner::visitICmpInstWithCastAndCast(ICmpInst &ICI) { const CastInst *LHSCI = cast(ICI.getOperand(0)); Value *LHSCIOp = LHSCI->getOperand(0); From reid at x10sys.com Mon Apr 2 23:56:39 2007 From: reid at x10sys.com (Reid Spencer) Date: Mon, 2 Apr 2007 23:56:39 -0500 Subject: [llvm-commits] CVS: llvm-www/SVNMigration.html Message-ID: <200704030456.l334udQR004396@zion.cs.uiuc.edu> Changes in directory llvm-www: SVNMigration.html updated: 1.2 -> 1.3 --- Log message: Add a note about renaming things. --- Diffs of the changes: (+34 -1) SVNMigration.html | 35 ++++++++++++++++++++++++++++++++++- 1 files changed, 34 insertions(+), 1 deletion(-) Index: llvm-www/SVNMigration.html diff -u llvm-www/SVNMigration.html:1.2 llvm-www/SVNMigration.html:1.3 --- llvm-www/SVNMigration.html:1.2 Mon Apr 2 13:52:38 2007 +++ llvm-www/SVNMigration.html Mon Apr 2 23:56:22 2007 @@ -7,6 +7,39 @@ + +
      +

      Since everything will be in one SVN repository, we thought we'd take this + opportunity to rename some top level directories to reduce redundancy. This + will be more important with Subversion because of Subversion URLs which will + already contain llvm.org (host) and llvm-something (repository). We + don't need another level of "llvm" in the top level directories as well.

      +

      The proposed renamining is shown in the table below.

      + + + + + + + + + + +
      Old NameNew Name
      llvmllvm
      llvm-testtest-suite
      llvm-stackerstacker
      llvm-javajava
      llvm-tvtelevision
      llvm-poolallocpoolalloc
      Adaptiveadaptive
      nightlytest-serversidenightly-test
      +

      NOTE: Due to synchronization of commits in the conversion process, + we will likely transition all of the above to Subversion in one shot. + This will allow SVN revision numbers to increase temporally instead + of disjointedly if the projects were imported one at a time. It also + permits revision groups to span across projects. For example, + changes to llvm and llvm-stacker made at the same time with + the same commit comment would be grouped as one SVN revision. + This increases the atomicity of commits and reduces the total number of + revisions in the SVN repository.

      +

      NOTE: we will be converting neither llvm-www (UIUC web site) nor + llvm-gcc (old version 3).

      +
      + +

      The existing branches have been categorized as shown in the table below. If @@ -118,6 +151,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
      Last modified: $Date: 2007/04/02 18:52:38 $ +
      Last modified: $Date: 2007/04/03 04:56:22 $ From reid at x10sys.com Tue Apr 3 00:03:15 2007 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Apr 2007 00:03:15 -0500 Subject: [llvm-commits] CVS: llvm-www/SVNMigration.html Message-ID: <200704030503.l3353Fpk004571@zion.cs.uiuc.edu> Changes in directory llvm-www: SVNMigration.html updated: 1.3 -> 1.4 --- Log message: Update the current status of branch/tag migration. --- Diffs of the changes: (+13 -17) SVNMigration.html | 30 +++++++++++++----------------- 1 files changed, 13 insertions(+), 17 deletions(-) Index: llvm-www/SVNMigration.html diff -u llvm-www/SVNMigration.html:1.3 llvm-www/SVNMigration.html:1.4 --- llvm-www/SVNMigration.html:1.3 Mon Apr 2 23:56:22 2007 +++ llvm-www/SVNMigration.html Tue Apr 3 00:02:58 2007 @@ -50,10 +50,12 @@ - + + + +
      NameDescription
      release_*Release branches (10 total)
      seeBranch Vikram's group is using for Secure - Code?
      seeBranch SVA project (will be renamed "SVA")
      parallelBranch for parallel features? (not sure)
      vector_llvmBranch for vector stuff? (not sure)
      PowerPC_0An early version of the PowerPC target, needed by release_13.

      Branches To Be Removed

      @@ -78,10 +80,6 @@ regalloc_linearscan has only 3 old header files in it - PowerPC_0 - Appears to be an early version of the PowerPC target. Seems not - important to keep it - pre-11, prerelease_* John created these as the first step towards a release, but it hasn't been done that way since (there's no prerelease_12 or later). @@ -104,28 +102,26 @@

      Tags To Be Kept

      - - - - - - - + +
      NameDescription
      jtcAssuming this is John Criswell's tag and he wants - it
      jtcllvaAssuming this is the LLVA tag
      RELEASE_*These are the final release tags (7 total)
      startThis seems to be the very first tag. It references an - ancient version of llvm and is only of historical interest
      RELEASE_*These are the release tags (7 total).
      startThis seems to be the very first tag. It is required + by the RELEASE_* tags.

      Tags To Be Removed

      + + + - + @@ -151,6 +147,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!">Valid HTML 4.01! -
      Last modified: $Date: 2007/04/03 04:56:22 $ +
      Last modified: $Date: 2007/04/03 05:02:58 $ From sabre at nondot.org Tue Apr 3 00:11:41 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 3 Apr 2007 00:11:41 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200704030511.l335Bfgd004749@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.125 -> 1.126 --- Log message: split some code out into a helper function --- Diffs of the changes: (+30 -18) LoopStrengthReduce.cpp | 48 ++++++++++++++++++++++++++++++------------------ 1 files changed, 30 insertions(+), 18 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.125 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.126 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.125 Mon Apr 2 17:51:58 2007 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Tue Apr 3 00:11:24 2007 @@ -176,6 +176,8 @@ SCEVHandle GetExpressionSCEV(Instruction *E, Loop *L); void OptimizeIndvars(Loop *L); + bool FindIVForUser(ICmpInst *Cond, IVStrideUse *&CondUse, + const SCEVHandle *&CondStride); unsigned CheckForIVReuse(const SCEVHandle&, IVExpr&, const Type*, const std::vector& UsersToProcess); @@ -1222,6 +1224,31 @@ // different starting values, into different PHIs. } +/// FindIVForUser - If Cond has an operand that is an expression of an IV, +/// set the IV user and stride information and return true, otherwise return +/// false. +bool LoopStrengthReduce::FindIVForUser(ICmpInst *Cond, IVStrideUse *&CondUse, + const SCEVHandle *&CondStride) { + for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e && !CondUse; + ++Stride) { + std::map::iterator SI = + IVUsesByStride.find(StrideOrder[Stride]); + assert(SI != IVUsesByStride.end() && "Stride doesn't exist!"); + + for (std::vector::iterator UI = SI->second.Users.begin(), + E = SI->second.Users.end(); UI != E; ++UI) + if (UI->User == Cond) { + // NOTE: we could handle setcc instructions with multiple uses here, but + // InstCombine does it as well for simple uses, it's not clear that it + // occurs enough in real life to handle. + CondUse = &*UI; + CondStride = &SI->first; + return true; + } + } + return false; +} + // OptimizeIndvars - Now that IVUsesByStride is set up with all of the indvar // uses in the loop, look to see if we can eliminate some, in favor of using // common indvars for the different uses. @@ -1246,24 +1273,9 @@ IVStrideUse *CondUse = 0; const SCEVHandle *CondStride = 0; - for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e && !CondUse; - ++Stride) { - std::map::iterator SI = - IVUsesByStride.find(StrideOrder[Stride]); - assert(SI != IVUsesByStride.end() && "Stride doesn't exist!"); - - for (std::vector::iterator UI = SI->second.Users.begin(), - E = SI->second.Users.end(); UI != E; ++UI) - if (UI->User == Cond) { - CondUse = &*UI; - CondStride = &SI->first; - // NOTE: we could handle setcc instructions with multiple uses here, but - // InstCombine does it as well for simple uses, it's not clear that it - // occurs enough in real life to handle. - break; - } - } - if (!CondUse) return; // setcc doesn't use the IV. + if (!FindIVForUser(Cond, CondUse, CondStride)) + return; // setcc doesn't use the IV. + // It's possible for the setcc instruction to be anywhere in the loop, and // possible for it to have multiple users. If it is not immediately before From isanbard at gmail.com Tue Apr 3 01:00:55 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 3 Apr 2007 01:00:55 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp X86InstrMMX.td Message-ID: <200704030600.l3360tpM005770@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.81 -> 1.82 X86InstrMMX.td updated: 1.28 -> 1.29 --- Log message: Add FEMMS and ADDQ. Renamed MMX recipes to prepend the MMX_ to them. --- Diffs of the changes: (+85 -69) X86InstrInfo.cpp | 10 +-- X86InstrMMX.td | 144 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 85 insertions(+), 69 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.81 llvm/lib/Target/X86/X86InstrInfo.cpp:1.82 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.81 Wed Mar 28 13:12:31 2007 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Tue Apr 3 01:00:37 2007 @@ -38,7 +38,7 @@ oc == X86::MOVAPSrr || oc == X86::MOVAPDrr || oc == X86::MOVSS2PSrr || oc == X86::MOVSD2PDrr || oc == X86::MOVPS2SSrr || oc == X86::MOVPD2SDrr || - oc == X86::MOVD64rr || oc == X86::MOVQ64rr) { + oc == X86::MMX_MOVD64rr || oc == X86::MMX_MOVQ64rr) { assert(MI.getNumOperands() == 2 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && @@ -65,8 +65,8 @@ case X86::MOVSDrm: case X86::MOVAPSrm: case X86::MOVAPDrm: - case X86::MOVD64rm: - case X86::MOVQ64rm: + case X86::MMX_MOVD64rm: + case X86::MMX_MOVQ64rm: if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && MI->getOperand(3).isRegister() && MI->getOperand(4).isImmediate() && MI->getOperand(2).getImmedValue() == 1 && @@ -95,8 +95,8 @@ case X86::MOVSDmr: case X86::MOVAPSmr: case X86::MOVAPDmr: - case X86::MOVD64mr: - case X86::MOVQ64mr: + case X86::MMX_MOVD64mr: + case X86::MMX_MOVQ64mr: if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && MI->getOperand(2).isRegister() && MI->getOperand(3).isImmediate() && MI->getOperand(1).getImmedValue() == 1 && Index: llvm/lib/Target/X86/X86InstrMMX.td diff -u llvm/lib/Target/X86/X86InstrMMX.td:1.28 llvm/lib/Target/X86/X86InstrMMX.td:1.29 --- llvm/lib/Target/X86/X86InstrMMX.td:1.28 Tue Mar 27 19:57:11 2007 +++ llvm/lib/Target/X86/X86InstrMMX.td Tue Apr 3 01:00:37 2007 @@ -118,10 +118,11 @@ } //===----------------------------------------------------------------------===// -// MMX EMMS Instruction +// MMX EMMS & FEMMS Instructions //===----------------------------------------------------------------------===// -def MMX_EMMS : MMXI<0x77, RawFrm, (ops), "emms", [(int_x86_mmx_emms)]>; +def MMX_EMMS : MMXI<0x77, RawFrm, (ops), "emms", [(int_x86_mmx_emms)]>; +def MMX_FEMMS : MMXI<0x0E, RawFrm, (ops), "femms", [(int_x86_mmx_femms)]>; //===----------------------------------------------------------------------===// // MMX Scalar Instructions @@ -130,9 +131,10 @@ // Arithmetic Instructions // -- Addition -defm MMX_PADDB : MMXI_binop_rm<0xFC, "paddb", add, v8i8, 1>; +defm MMX_PADDB : MMXI_binop_rm<0xFC, "paddb", add, v8i8, 1>; defm MMX_PADDW : MMXI_binop_rm<0xFD, "paddw", add, v4i16, 1>; defm MMX_PADDD : MMXI_binop_rm<0xFE, "paddd", add, v2i32, 1>; +defm MMX_PADDQ : MMXI_binop_rm<0xD4, "paddq", add, v1i64, 1>; defm MMX_PADDSB : MMXI_binop_rm_int<0xEC, "paddsb" , int_x86_mmx_padds_b, 1>; defm MMX_PADDSW : MMXI_binop_rm_int<0xED, "paddsw" , int_x86_mmx_padds_w, 1>; @@ -309,45 +311,52 @@ defm MMX_PACKUSWB : MMXI_binop_rm_int<0x67, "packuswb", int_x86_mmx_packuswb>; // Data Transfer Instructions -def MOVD64rr : MMXI<0x6E, MRMSrcReg, (ops VR64:$dst, GR32:$src), - "movd {$src, $dst|$dst, $src}", []>; -def MOVD64rm : MMXI<0x6E, MRMSrcMem, (ops VR64:$dst, i32mem:$src), - "movd {$src, $dst|$dst, $src}", []>; -def MOVD64mr : MMXI<0x7E, MRMDestMem, (ops i32mem:$dst, VR64:$src), - "movd {$src, $dst|$dst, $src}", []>; - -def MOVQ64rr : MMXI<0x6F, MRMSrcReg, (ops VR64:$dst, VR64:$src), - "movq {$src, $dst|$dst, $src}", []>; -def MOVQ64rm : MMXI<0x6F, MRMSrcMem, (ops VR64:$dst, i64mem:$src), - "movq {$src, $dst|$dst, $src}", - [(set VR64:$dst, (load_mmx addr:$src))]>; -def MOVQ64mr : MMXI<0x7F, MRMDestMem, (ops i64mem:$dst, VR64:$src), - "movq {$src, $dst|$dst, $src}", - [(store (v1i64 VR64:$src), addr:$dst)]>; +def MMX_MOVD64rr : MMXI<0x6E, MRMSrcReg, (ops VR64:$dst, GR32:$src), + "movd {$src, $dst|$dst, $src}", []>; +def MMX_MOVD64rm : MMXI<0x6E, MRMSrcMem, (ops VR64:$dst, i32mem:$src), + "movd {$src, $dst|$dst, $src}", []>; +def MMX_MOVD64mr : MMXI<0x7E, MRMDestMem, (ops i32mem:$dst, VR64:$src), + "movd {$src, $dst|$dst, $src}", []>; + +def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (ops VR64:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", []>; +def MMX_MOVQ64rm : MMXI<0x6F, MRMSrcMem, (ops VR64:$dst, i64mem:$src), + "movq {$src, $dst|$dst, $src}", + [(set VR64:$dst, (load_mmx addr:$src))]>; +def MMX_MOVQ64mr : MMXI<0x7F, MRMDestMem, (ops i64mem:$dst, VR64:$src), + "movq {$src, $dst|$dst, $src}", + [(store (v1i64 VR64:$src), addr:$dst)]>; // Conversion instructions -def CVTPI2PSrr : MMXI<0x2A, MRMSrcReg, (ops VR128:$dst, VR64:$src), - "cvtpi2ps {$src, $dst|$dst, $src}", []>; -def CVTPI2PSrm : MMXI<0x2A, MRMSrcMem, (ops VR128:$dst, i64mem:$src), - "cvtpi2ps {$src, $dst|$dst, $src}", []>; -def CVTPI2PDrr : MMX2I<0x2A, MRMSrcReg, (ops VR128:$dst, VR64:$src), - "cvtpi2pd {$src, $dst|$dst, $src}", []>; -def CVTPI2PDrm : MMX2I<0x2A, MRMSrcMem, (ops VR128:$dst, i64mem:$src), - "cvtpi2pd {$src, $dst|$dst, $src}", []>; -def CVTTPS2PIrr: I<0x2C, MRMSrcReg, (ops VR64:$dst, VR128:$src), - "cvttps2pi {$src, $dst|$dst, $src}", []>, TB, - Requires<[HasMMX]>; -def CVTTPS2PIrm: I<0x2C, MRMSrcMem, (ops VR64:$dst, f64mem:$src), - "cvttps2pi {$src, $dst|$dst, $src}", []>, TB, - Requires<[HasMMX]>; -def CVTPS2PIrr : MMXI<0x2D, MRMSrcReg, (ops VR64:$dst, VR128:$src), - "cvtps2pi {$src, $dst|$dst, $src}", []>; -def CVTPS2PIrm : MMXI<0x2D, MRMSrcMem, (ops VR64:$dst, f64mem:$src), - "cvtps2pi {$src, $dst|$dst, $src}", []>; -def CVTPD2PIrr : MMX2I<0x2D, MRMSrcReg, (ops VR64:$dst, VR128:$src), - "cvtpd2pi {$src, $dst|$dst, $src}", []>; -def CVTPD2PIrm : MMX2I<0x2D, MRMSrcMem, (ops VR64:$dst, f128mem:$src), - "cvtpd2pi {$src, $dst|$dst, $src}", []>; +def MMX_CVTPD2PIrr : MMX2I<0x2D, MRMSrcReg, (ops VR64:$dst, VR128:$src), + "cvtpd2pi {$src, $dst|$dst, $src}", []>; +def MMX_CVTPD2PIrm : MMX2I<0x2D, MRMSrcMem, (ops VR64:$dst, f128mem:$src), + "cvtpd2pi {$src, $dst|$dst, $src}", []>; + +def MMX_CVTPI2PDrr : MMX2I<0x2A, MRMSrcReg, (ops VR128:$dst, VR64:$src), + "cvtpi2pd {$src, $dst|$dst, $src}", []>; +def MMX_CVTPI2PDrm : MMX2I<0x2A, MRMSrcMem, (ops VR128:$dst, i64mem:$src), + "cvtpi2pd {$src, $dst|$dst, $src}", []>; + +def MMX_CVTPI2PSrr : MMXI<0x2A, MRMSrcReg, (ops VR128:$dst, VR64:$src), + "cvtpi2ps {$src, $dst|$dst, $src}", []>; +def MMX_CVTPI2PSrm : MMXI<0x2A, MRMSrcMem, (ops VR128:$dst, i64mem:$src), + "cvtpi2ps {$src, $dst|$dst, $src}", []>; + +def MMX_CVTPS2PIrr : MMXI<0x2D, MRMSrcReg, (ops VR64:$dst, VR128:$src), + "cvtps2pi {$src, $dst|$dst, $src}", []>; +def MMX_CVTPS2PIrm : MMXI<0x2D, MRMSrcMem, (ops VR64:$dst, f64mem:$src), + "cvtps2pi {$src, $dst|$dst, $src}", []>; + +def MMX_CVTTPD2PIrr: MMX2I<0x2C, MRMSrcReg, (ops VR64:$dst, VR128:$src), + "cvttpd2pi {$src, $dst|$dst, $src}", []>; +def MMX_CVTTPD2PIrm: MMX2I<0x2C, MRMSrcMem, (ops VR64:$dst, f128mem:$src), + "cvttpd2pi {$src, $dst|$dst, $src}", []>; + +def MMX_CVTTPS2PIrr: MMXI<0x2C, MRMSrcReg, (ops VR64:$dst, VR128:$src), + "cvttps2pi {$src, $dst|$dst, $src}", []>; +def MMX_CVTTPS2PIrm: MMXI<0x2C, MRMSrcMem, (ops VR64:$dst, f64mem:$src), + "cvttps2pi {$src, $dst|$dst, $src}", []>; // Shuffle and unpack instructions def PSHUFWri : MMXIi8<0x70, MRMSrcReg, @@ -387,11 +396,13 @@ // Store 64-bit integer vector values. def : Pat<(store (v8i8 VR64:$src), addr:$dst), - (MOVQ64mr addr:$dst, VR64:$src)>; + (MMX_MOVQ64mr addr:$dst, VR64:$src)>; def : Pat<(store (v4i16 VR64:$src), addr:$dst), - (MOVQ64mr addr:$dst, VR64:$src)>; + (MMX_MOVQ64mr addr:$dst, VR64:$src)>; def : Pat<(store (v2i32 VR64:$src), addr:$dst), - (MOVQ64mr addr:$dst, VR64:$src)>; + (MMX_MOVQ64mr addr:$dst, VR64:$src)>; +def : Pat<(store (v1i64 VR64:$src), addr:$dst), + (MMX_MOVQ64mr addr:$dst, VR64:$src)>; // 64-bit vector all zero's. def : Pat<(v8i8 immAllZerosV), (MMX_V_SET0)>; @@ -419,34 +430,39 @@ def : Pat<(v1i64 (bitconvert (v4i16 VR64:$src))), (v1i64 VR64:$src)>; def : Pat<(v1i64 (bitconvert (v8i8 VR64:$src))), (v1i64 VR64:$src)>; -// Splat v1i64 -// MMX_SHUFFLE_get_shuf_imm xform function: convert vector_shuffle mask to -// MMX_PSHUF*, MMX_SHUFP* etc. imm. -def MMX_SHUFFLE_get_shuf_imm : SDNodeXForm; +def MMX_X86s2vec : SDNode<"X86ISD::S2VEC", SDTypeProfile<1, 1, []>, []>; + +// Scalar to v4i16 / v8i8. The source may be a GR32, but only the lower 8 or +// 16-bits matter. +def : Pat<(v8i8 (MMX_X86s2vec GR32:$src)), (MMX_MOVD64rr GR32:$src)>; +def : Pat<(v4i16 (MMX_X86s2vec GR32:$src)), (MMX_MOVD64rr GR32:$src)>; -def MMX_splat_mask : PatLeaf<(build_vector), [{ - return X86::isSplatMask(N); -}], MMX_SHUFFLE_get_shuf_imm>; +// Recipes for: vector_shuffle v1, , <0, 0, 1, 1, ...> +def MMX_UNPCKL_v_undef_shuffle_mask : PatLeaf<(build_vector), [{ + return X86::isUNPCKL_v_undef_Mask(N); +}]>; let AddedComplexity = 10 in { - def : Pat<(vector_shuffle (v1i64 VR64:$src), (undef), - MMX_splat_mask:$sm), - (MMX_PUNPCKHDQrr VR64:$src, VR64:$src)>; - def : Pat<(vector_shuffle (v1i64 VR64:$src), (undef), - MMX_UNPCKH_shuffle_mask:$sm), - (MMX_PUNPCKHDQrr VR64:$src, VR64:$src)>; + def : Pat<(v8i8 (vector_shuffle VR64:$src, (undef), + MMX_UNPCKL_v_undef_shuffle_mask)), + (MMX_PUNPCKLBWrr VR64:$src, VR64:$src)>; + def : Pat<(v4i16 (vector_shuffle VR64:$src, (undef), + MMX_UNPCKL_v_undef_shuffle_mask)), + (MMX_PUNPCKLWDrr VR64:$src, VR64:$src)>; + def : Pat<(v2i32 (vector_shuffle VR64:$src, (undef), + MMX_UNPCKL_v_undef_shuffle_mask)), + (MMX_PUNPCKLDQrr VR64:$src, VR64:$src)>; } -def MMX_X86s2vec : SDNode<"X86ISD::S2VEC", SDTypeProfile<1, 1, []>, []>; - -// Scalar to v4i16 / v8i8. The source may be a GR32, but only the lower 8 or -// 16-bits matter. -def : Pat<(v8i8 (MMX_X86s2vec GR32:$src)), (MOVD64rr GR32:$src)>; -def : Pat<(v4i16 (MMX_X86s2vec GR32:$src)), (MOVD64rr GR32:$src)>; +let AddedComplexity = 20 in { + def : Pat<(bc_v2i32 (vector_shuffle immAllZerosV, + (v2i32 (scalar_to_vector (load_mmx addr:$src))), + MMX_UNPCKL_shuffle_mask)), + (MMX_PUNPCKLDQrm VR64:$src, VR64:$src)>; +} // Some special case PANDN patterns. +// FIXME: Get rid of these. def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v2i32 immAllOnesV))), VR64:$src2)), (MMX_PANDNrr VR64:$src1, VR64:$src2)>; From isanbard at gmail.com Tue Apr 3 01:00:56 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 3 Apr 2007 01:00:56 -0500 Subject: [llvm-commits] CVS: llvm/include/llvm/IntrinsicsX86.td Message-ID: <200704030600.l3360ueJ005776@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: IntrinsicsX86.td updated: 1.40 -> 1.41 --- Log message: Add FEMMS and ADDQ. Renamed MMX recipes to prepend the MMX_ to them. --- Diffs of the changes: (+3 -1) IntrinsicsX86.td | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/include/llvm/IntrinsicsX86.td diff -u llvm/include/llvm/IntrinsicsX86.td:1.40 llvm/include/llvm/IntrinsicsX86.td:1.41 --- llvm/include/llvm/IntrinsicsX86.td:1.40 Tue Mar 27 15:21:31 2007 +++ llvm/include/llvm/IntrinsicsX86.td Tue Apr 3 01:00:36 2007 @@ -541,7 +541,9 @@ // Empty MMX state op. let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_mmx_emms : GCCBuiltin<"__builtin_ia32_emms">, + def int_x86_mmx_emms : GCCBuiltin<"__builtin_ia32_emms">, + Intrinsic<[llvm_void_ty], [IntrWriteMem]>; + def int_x86_mmx_femms : GCCBuiltin<"__builtin_ia32_femms">, Intrinsic<[llvm_void_ty], [IntrWriteMem]>; } From bwendlin at apple.com Tue Apr 3 01:12:18 2007 From: bwendlin at apple.com (bwendlin at apple.com) Date: Mon, 2 Apr 2007 23:12:18 -0700 (PDT) Subject: [llvm-commits] [125666] Add support for the PADDQ builtin. Message-ID: <20070403061218.A2AE2CC2E950@src> Revision: 125666 Author: bwendlin Date: 2007-04-02 23:12:17 -0700 (Mon, 02 Apr 2007) Log Message: ----------- Add support for the PADDQ builtin. Modified Paths: -------------- apple-local/branches/llvm/gcc/config/i386/llvm-i386.cpp Modified: apple-local/branches/llvm/gcc/config/i386/llvm-i386.cpp =================================================================== --- apple-local/branches/llvm/gcc/config/i386/llvm-i386.cpp 2007-04-03 03:01:10 UTC (rev 125665) +++ apple-local/branches/llvm/gcc/config/i386/llvm-i386.cpp 2007-04-03 06:12:17 UTC (rev 125666) @@ -34,7 +34,9 @@ #include "toplev.h" } -/* TargetIntrinsicCastResult - This function just provides a frequently * used sequence for use inside TargetIntrinsicLower. */ +/* TargetIntrinsicCastResult - This function just provides a frequently used + * sequence for use inside TargetIntrinsicLower. + */ static void TargetIntrinsicCastResult(Value *&Result, const Type *ResultType, bool ResIsSigned, bool ExpIsSigned, BasicBlock *CurBB) { @@ -43,14 +45,16 @@ Result = CastInst::create(opcode, Result, ResultType, "tmp", CurBB); } -/* IntrinsicOpIsSigned - This function determines if a given operand * to the intrinsic is signed or not. */ +/* IntrinsicOpIsSigned - This function determines if a given operand to the + * intrinsic is signed or not. + */ static bool IntrinsicOpIsSigned(SmallVector &Args, unsigned OpNum) { return !TYPE_UNSIGNED(TREE_TYPE(Args[OpNum])); } -/* TargetIntrinsicLower - For builtins that we want to expand to normal - * LLVM code, emit the code now. If we can handle the code, this macro should - * emit the code, return true. +/* TargetIntrinsicLower - For builtins that we want to expand to normal LLVM + * code, emit the code now. If we can handle the code, this macro should emit + * the code, return true. */ bool TreeToLLVM::TargetIntrinsicLower(tree exp, unsigned FnCode, @@ -69,6 +73,7 @@ case IX86_BUILTIN_PADDB: case IX86_BUILTIN_PADDW: case IX86_BUILTIN_PADDD: + case IX86_BUILTIN_PADDQ: case IX86_BUILTIN_PADDB128: case IX86_BUILTIN_PADDW128: case IX86_BUILTIN_PADDD128: From isanbard at gmail.com Tue Apr 3 01:18:49 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 3 Apr 2007 01:18:49 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200704030618.l336In0u006111@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.208 -> 1.209 --- Log message: Changed to new MMX_ recipes. --- Diffs of the changes: (+3 -3) X86RegisterInfo.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.208 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.209 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.208 Tue Mar 20 03:09:38 2007 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Tue Apr 3 01:18:31 2007 @@ -90,7 +90,7 @@ } else if (RC == &X86::VR128RegClass) { Opc = X86::MOVAPSmr; } else if (RC == &X86::VR64RegClass) { - Opc = X86::MOVQ64mr; + Opc = X86::MMX_MOVQ64mr; } else { assert(0 && "Unknown regclass"); abort(); @@ -125,7 +125,7 @@ } else if (RC == &X86::VR128RegClass) { Opc = X86::MOVAPSrm; } else if (RC == &X86::VR64RegClass) { - Opc = X86::MOVQ64rm; + Opc = X86::MMX_MOVQ64rm; } else { assert(0 && "Unknown regclass"); abort(); @@ -159,7 +159,7 @@ } else if (RC == &X86::VR128RegClass) { Opc = X86::MOVAPSrr; } else if (RC == &X86::VR64RegClass) { - Opc = X86::MOVQ64rr; + Opc = X86::MMX_MOVQ64rr; } else { assert(0 && "Unknown regclass"); abort(); From wendling at apple.com Tue Apr 3 01:34:40 2007 From: wendling at apple.com (Bill Wendling) Date: Mon, 2 Apr 2007 23:34:40 -0700 Subject: [llvm-commits] eh_arm.cc Message-ID: I'm getting this error during llvm-gcc compilation: make[3]: *** No rule to make target `eh_arm.cc', needed by `eh_arm.lo'. Stop. make[3]: *** Waiting for unfinished jobs.... -bw From evan.cheng at apple.com Tue Apr 3 01:43:46 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 3 Apr 2007 01:43:46 -0500 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegisterScavenging.cpp Message-ID: <200704030643.l336hkHH006770@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegisterScavenging.cpp updated: 1.14 -> 1.15 --- Log message: Bad bad bug. findRegisterUseOperand() returns -1 if a use if not found. --- Diffs of the changes: (+1 -1) RegisterScavenging.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/RegisterScavenging.cpp diff -u llvm/lib/CodeGen/RegisterScavenging.cpp:1.14 llvm/lib/CodeGen/RegisterScavenging.cpp:1.15 --- llvm/lib/CodeGen/RegisterScavenging.cpp:1.14 Mon Mar 26 17:23:54 2007 +++ llvm/lib/CodeGen/RegisterScavenging.cpp Tue Apr 3 01:43:29 2007 @@ -235,7 +235,7 @@ I = next(I); while (I != MBB->end()) { Dist++; - if (I->findRegisterUseOperand(Reg)) + if (I->findRegisterUseOperand(Reg) != -1) return Dist; I = next(I); } From evan.cheng at apple.com Tue Apr 3 01:44:42 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 3 Apr 2007 01:44:42 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/ARM/ARMInstrInfo.cpp Message-ID: <200704030644.l336igMk006806@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/ARM: ARMInstrInfo.cpp updated: 1.18 -> 1.19 --- Log message: Inverted logic. --- Diffs of the changes: (+1 -1) ARMInstrInfo.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/ARM/ARMInstrInfo.cpp diff -u llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.18 llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.19 --- llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.18 Mon Mar 26 17:41:48 2007 +++ llvm/lib/Target/ARM/ARMInstrInfo.cpp Tue Apr 3 01:44:25 2007 @@ -279,7 +279,7 @@ // Look at the two new MI's in reverse order. MachineInstr *NewMI = NewMIs[j]; int NIdx = NewMI->findRegisterUseOperand(Reg); - if (NIdx != -1) + if (NIdx == -1) continue; LV.addVirtualRegisterKilled(Reg, NewMI); if (VI.removeKill(MI)) From dpatel at apple.com Tue Apr 3 02:16:35 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 3 Apr 2007 00:16:35 -0700 Subject: [llvm-commits] eh_arm.cc In-Reply-To: References: Message-ID: <124DED6F-23CB-4938-93CF-08D897B23F26@apple.com> On Apr 2, 2007, at 11:34 PM, Bill Wendling wrote: > I'm getting this error during llvm-gcc compilation: > > make[3]: *** No rule to make target `eh_arm.cc', needed by > `eh_arm.lo'. Stop. > make[3]: *** Waiting for unfinished jobs.... This is related to Lauro Ramos Venancio's patch Dale committed. - Devang From reid at x10sys.com Tue Apr 3 02:19:13 2007 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Apr 2007 02:19:13 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704030719.l337JD6O014295@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.30 -> 1.31 --- Log message: Add Evan Cheng. --- Diffs of the changes: (+4 -3) DevMtgMay2007.html | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.30 llvm-www/DevMtgMay2007.html:1.31 --- llvm-www/DevMtgMay2007.html:1.30 Mon Apr 2 14:14:17 2007 +++ llvm-www/DevMtgMay2007.html Tue Apr 3 02:17:54 2007 @@ -228,6 +228,7 @@ + @@ -241,8 +242,8 @@
      NameDescription
      byebyeContains just the old lib/Analysis/DataStructure stuff. It is inappropriately named and definitely not needed
      jtcAssuming this is John Criswell's tag and he wants + it
      jtcllvaAssuming this is the LLVA tag
      LLVM_PRE111This is a pre-release tag to go with a branch we're planning to remove.
      new_merge_vectorAppears to be a merging tag. Pretty sure its unneeded at this point
      PowerPC_0_0Root of a branch we're deleting
      PowerPC_0_0Required by PowerPC_0 branch
      PARALLEL_ROOTRoot of the parallel branch
      PRE10Root of a branch we're deleting
      PRE101Root of a branch we're deleting
      Vikram AdveUIUC
      Owen AndersonIndependent
      Ryan BrownGoogle
      Evan ChengApple, Inc.
      Jeff CohenIndependent
      Robert HundtGoogle
      Christopher LambAgeia Technologies, Inc.
      Bill WendlingApple, Inc.
      Marcel WeiherMetaObject
      -

      Total confirmed attendees: 19

      -

      Possible additional attendees: 6

      +

      Total confirmed attendees: 20

      +

      Possible additional attendeew: 5

      @@ -252,6 +253,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
      Last modified: $Date: 2007/04/02 19:14:17 $ +
      Last modified: $Date: 2007/04/03 07:17:54 $ From reid at x10sys.com Tue Apr 3 02:43:44 2007 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Apr 2007 02:43:44 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704030743.l337hiDO017050@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.31 -> 1.32 --- Log message: Portray the confirmed/unconfirmed attendees more accurately. --- Diffs of the changes: (+14 -6) DevMtgMay2007.html | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.31 llvm-www/DevMtgMay2007.html:1.32 --- llvm-www/DevMtgMay2007.html:1.31 Tue Apr 3 02:17:54 2007 +++ llvm-www/DevMtgMay2007.html Tue Apr 3 02:43:27 2007 @@ -224,6 +224,7 @@

      The table below lists the confirmed attendees for the meeting.

      + @@ -234,16 +235,23 @@ - + - + - + + + + + + + +
      Confirmed Attendees
      NameOrganization
      Vikram AdveUIUC
      Owen AndersonIndependent
      Christopher LambAgeia Technologies, Inc.
      Chris LattnerApple, Inc.
      Nick LewyckyIndependent
      Scott Michel + 2Aerospace
      Scott MichelAerospace
      Devang PatelApple, Inc.
      Mark Schimmel + 1Wind River
      Mark SchimmelWind River
      Reid SpencerIndependent
      Sarah Thompson + 1NASA, Ames Research Center
      Sarah ThompsonNASA, Ames Research Center
      Bill WendlingApple, Inc.
      Marcel WeiherMetaObject
      Unconfirmed Attendees
      NameOrganization
      Unconfirmed 3Adobe
      Unconfirmed 2+Apple
      Unconfirmed 2Aerospace
      Unconfirmed 1Wind River
      Unconfirmed 1NASA, Ames
      -

      Total confirmed attendees: 20

      -

      Possible additional attendeew: 5

      +

      Total confirmed attendees: 16

      +

      Possible additional attendeew: 9

      @@ -253,6 +261,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
      Last modified: $Date: 2007/04/03 07:17:54 $ +
      Last modified: $Date: 2007/04/03 07:43:27 $ From reid at x10sys.com Tue Apr 3 02:54:12 2007 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Apr 2007 02:54:12 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704030754.l337sCZE017304@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.32 -> 1.33 --- Log message: Fix typo. --- Diffs of the changes: (+2 -2) DevMtgMay2007.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.32 llvm-www/DevMtgMay2007.html:1.33 --- llvm-www/DevMtgMay2007.html:1.32 Tue Apr 3 02:43:27 2007 +++ llvm-www/DevMtgMay2007.html Tue Apr 3 02:53:55 2007 @@ -251,7 +251,7 @@ Unconfirmed 1NASA, Ames

      Total confirmed attendees: 16

      -

      Possible additional attendeew: 9

      +

      Possible additional attendees: 9

      @@ -261,6 +261,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
      Last modified: $Date: 2007/04/03 07:43:27 $ +
      Last modified: $Date: 2007/04/03 07:53:55 $ From reid at x10sys.com Tue Apr 3 02:56:44 2007 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Apr 2007 02:56:44 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704030756.l337uioZ017414@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.33 -> 1.34 --- Log message: Put the actual date in the title. --- Diffs of the changes: (+2 -2) DevMtgMay2007.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.33 llvm-www/DevMtgMay2007.html:1.34 --- llvm-www/DevMtgMay2007.html:1.33 Tue Apr 3 02:53:55 2007 +++ llvm-www/DevMtgMay2007.html Tue Apr 3 02:56:27 2007 @@ -1,5 +1,5 @@ -
      May 2007 LLVM Developers Meeting
      +
      May 25, 2007
      LLVM Developers' Meeting
      1. Summary
      2. Agenda @@ -261,6 +261,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
        Last modified: $Date: 2007/04/03 07:53:55 $ +
        Last modified: $Date: 2007/04/03 07:56:27 $ From evan.cheng at apple.com Tue Apr 3 03:12:08 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 3 Apr 2007 03:12:08 -0500 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200704030812.l338C85l017774@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.725 -> 1.726 --- Log message: Reverting back to 1.723. The last two commits broke JM (and possibily others) on ARM. --- Diffs of the changes: (+491 -524) InstructionCombining.cpp | 1015 ++++++++++++++++++++++------------------------- 1 files changed, 491 insertions(+), 524 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.725 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.726 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.725 Mon Apr 2 23:46:52 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Apr 3 03:11:50 2007 @@ -183,9 +183,6 @@ Instruction *visitFCmpInst(FCmpInst &I); Instruction *visitICmpInst(ICmpInst &I); Instruction *visitICmpInstWithCastAndCast(ICmpInst &ICI); - Instruction *visitICmpInstWithInstAndIntCst(ICmpInst &ICI, - Instruction *LHS, - ConstantInt *RHS); Instruction *FoldGEPICmp(User *GEPLHS, Value *RHS, ICmpInst::Predicate Cond, Instruction &I); @@ -4716,11 +4713,496 @@ // instruction, see if that instruction also has constants so that the // instruction can be folded into the icmp if (Instruction *LHSI = dyn_cast(Op0)) - if (Instruction *Res = visitICmpInstWithInstAndIntCst(I, LHSI, CI)) - return Res; + switch (LHSI->getOpcode()) { + case Instruction::And: + if (LHSI->hasOneUse() && isa(LHSI->getOperand(1)) && + LHSI->getOperand(0)->hasOneUse()) { + ConstantInt *AndCST = cast(LHSI->getOperand(1)); + + // If the LHS is an AND of a truncating cast, we can widen the + // and/compare to be the input width without changing the value + // produced, eliminating a cast. + if (CastInst *Cast = dyn_cast(LHSI->getOperand(0))) { + // We can do this transformation if either the AND constant does not + // have its sign bit set or if it is an equality comparison. + // Extending a relational comparison when we're checking the sign + // bit would not work. + if (Cast->hasOneUse() && isa(Cast) && + (I.isEquality() || AndCST->getValue().isPositive() && + CI->getValue().isPositive())) { + ConstantInt *NewCST; + ConstantInt *NewCI; + APInt NewCSTVal(AndCST->getValue()), NewCIVal(CI->getValue()); + uint32_t BitWidth = cast( + Cast->getOperand(0)->getType())->getBitWidth(); + NewCST = ConstantInt::get(NewCSTVal.zext(BitWidth)); + NewCI = ConstantInt::get(NewCIVal.zext(BitWidth)); + Instruction *NewAnd = + BinaryOperator::createAnd(Cast->getOperand(0), NewCST, + LHSI->getName()); + InsertNewInstBefore(NewAnd, I); + return new ICmpInst(I.getPredicate(), NewAnd, NewCI); + } + } + + // If this is: (X >> C1) & C2 != C3 (where any shift and any compare + // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This + // happens a LOT in code produced by the C front-end, for bitfield + // access. + BinaryOperator *Shift = dyn_cast(LHSI->getOperand(0)); + if (Shift && !Shift->isShift()) + Shift = 0; + + ConstantInt *ShAmt; + ShAmt = Shift ? dyn_cast(Shift->getOperand(1)) : 0; + const Type *Ty = Shift ? Shift->getType() : 0; // Type of the shift. + const Type *AndTy = AndCST->getType(); // Type of the and. + + // We can fold this as long as we can't shift unknown bits + // into the mask. This can only happen with signed shift + // rights, as they sign-extend. + if (ShAmt) { + bool CanFold = Shift->isLogicalShift(); + if (!CanFold) { + // To test for the bad case of the signed shr, see if any + // of the bits shifted in could be tested after the mask. + uint32_t TyBits = Ty->getPrimitiveSizeInBits(); + int ShAmtVal = TyBits - ShAmt->getLimitedValue(TyBits); + + uint32_t BitWidth = AndTy->getPrimitiveSizeInBits(); + if ((APInt::getHighBitsSet(BitWidth, BitWidth-ShAmtVal) & + AndCST->getValue()) == 0) + CanFold = true; + } + + if (CanFold) { + Constant *NewCst; + if (Shift->getOpcode() == Instruction::Shl) + NewCst = ConstantExpr::getLShr(CI, ShAmt); + else + NewCst = ConstantExpr::getShl(CI, ShAmt); + + // Check to see if we are shifting out any of the bits being + // compared. + if (ConstantExpr::get(Shift->getOpcode(), NewCst, ShAmt) != CI){ + // If we shifted bits out, the fold is not going to work out. + // As a special case, check to see if this means that the + // result is always true or false now. + if (I.getPredicate() == ICmpInst::ICMP_EQ) + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); + if (I.getPredicate() == ICmpInst::ICMP_NE) + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); + } else { + I.setOperand(1, NewCst); + Constant *NewAndCST; + if (Shift->getOpcode() == Instruction::Shl) + NewAndCST = ConstantExpr::getLShr(AndCST, ShAmt); + else + NewAndCST = ConstantExpr::getShl(AndCST, ShAmt); + LHSI->setOperand(1, NewAndCST); + LHSI->setOperand(0, Shift->getOperand(0)); + AddToWorkList(Shift); // Shift is dead. + AddUsesToWorkList(I); + return &I; + } + } + } + + // Turn ((X >> Y) & C) == 0 into (X & (C << Y)) == 0. The later is + // preferable because it allows the C<hasOneUse() && CI->isNullValue() && + I.isEquality() && !Shift->isArithmeticShift() && + isa(Shift->getOperand(0))) { + // Compute C << Y. + Value *NS; + if (Shift->getOpcode() == Instruction::LShr) { + NS = BinaryOperator::createShl(AndCST, + Shift->getOperand(1), "tmp"); + } else { + // Insert a logical shift. + NS = BinaryOperator::createLShr(AndCST, + Shift->getOperand(1), "tmp"); + } + InsertNewInstBefore(cast(NS), I); + + // Compute X & (C << Y). + Instruction *NewAnd = BinaryOperator::createAnd( + Shift->getOperand(0), NS, LHSI->getName()); + InsertNewInstBefore(NewAnd, I); + + I.setOperand(0, NewAnd); + return &I; + } + } + break; + + case Instruction::Shl: // (icmp pred (shl X, ShAmt), CI) + if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { + if (I.isEquality()) { + uint32_t TypeBits = CI->getType()->getPrimitiveSizeInBits(); + + // Check that the shift amount is in range. If not, don't perform + // undefined shifts. When the shift is visited it will be + // simplified. + if (ShAmt->uge(TypeBits)) + break; + + // If we are comparing against bits always shifted out, the + // comparison cannot succeed. + Constant *Comp = + ConstantExpr::getShl(ConstantExpr::getLShr(CI, ShAmt), ShAmt); + if (Comp != CI) {// Comparing against a bit that we know is zero. + bool IsICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE; + Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE); + return ReplaceInstUsesWith(I, Cst); + } + + if (LHSI->hasOneUse()) { + // Otherwise strength reduce the shift into an and. + uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); + Constant *Mask = ConstantInt::get( + APInt::getLowBitsSet(TypeBits, TypeBits-ShAmtVal)); + + Instruction *AndI = + BinaryOperator::createAnd(LHSI->getOperand(0), + Mask, LHSI->getName()+".mask"); + Value *And = InsertNewInstBefore(AndI, I); + return new ICmpInst(I.getPredicate(), And, + ConstantExpr::getLShr(CI, ShAmt)); + } + } + } + break; + + case Instruction::LShr: // (icmp pred (shr X, ShAmt), CI) + case Instruction::AShr: + if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { + if (I.isEquality()) { + // Check that the shift amount is in range. If not, don't perform + // undefined shifts. When the shift is visited it will be + // simplified. + uint32_t TypeBits = CI->getType()->getPrimitiveSizeInBits(); + if (ShAmt->uge(TypeBits)) + break; + + // If we are comparing against bits always shifted out, the + // comparison cannot succeed. + Constant *Comp; + if (LHSI->getOpcode() == Instruction::LShr) + Comp = ConstantExpr::getLShr(ConstantExpr::getShl(CI, ShAmt), + ShAmt); + else + Comp = ConstantExpr::getAShr(ConstantExpr::getShl(CI, ShAmt), + ShAmt); + + if (Comp != CI) {// Comparing against a bit that we know is zero. + bool IsICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE; + Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE); + return ReplaceInstUsesWith(I, Cst); + } + + if (LHSI->hasOneUse() || CI->isNullValue()) { + uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); + + // Otherwise strength reduce the shift into an and. + APInt Val(APInt::getHighBitsSet(TypeBits, TypeBits - ShAmtVal)); + Constant *Mask = ConstantInt::get(Val); + + Instruction *AndI = + BinaryOperator::createAnd(LHSI->getOperand(0), + Mask, LHSI->getName()+".mask"); + Value *And = InsertNewInstBefore(AndI, I); + return new ICmpInst(I.getPredicate(), And, + ConstantExpr::getShl(CI, ShAmt)); + } + } + } + break; + + case Instruction::SDiv: + case Instruction::UDiv: + // Fold: icmp pred ([us]div X, C1), C2 -> range test + // Fold this div into the comparison, producing a range check. + // Determine, based on the divide type, what the range is being + // checked. If there is an overflow on the low or high side, remember + // it, otherwise compute the range [low, hi) bounding the new value. + // See: InsertRangeTest above for the kinds of replacements possible. + if (ConstantInt *DivRHS = dyn_cast(LHSI->getOperand(1))) { + // FIXME: If the operand types don't match the type of the divide + // then don't attempt this transform. The code below doesn't have the + // logic to deal with a signed divide and an unsigned compare (and + // vice versa). This is because (x /s C1) getOpcode() == Instruction::SDiv; + if (!I.isEquality() && DivIsSigned != I.isSignedPredicate()) + break; + if (DivRHS->isZero()) + break; // Don't hack on div by zero + + // Initialize the variables that will indicate the nature of the + // range check. + bool LoOverflow = false, HiOverflow = false; + ConstantInt *LoBound = 0, *HiBound = 0; + + // Compute Prod = CI * DivRHS. We are essentially solving an equation + // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and + // C2 (CI). By solving for X we can turn this into a range check + // instead of computing a divide. + ConstantInt *Prod = Multiply(CI, DivRHS); + + // Determine if the product overflows by seeing if the product is + // not equal to the divide. Make sure we do the same kind of divide + // as in the LHS instruction that we're folding. + bool ProdOV = (DivIsSigned ? ConstantExpr::getSDiv(Prod, DivRHS) : + ConstantExpr::getUDiv(Prod, DivRHS)) != CI; + + // Get the ICmp opcode + ICmpInst::Predicate predicate = I.getPredicate(); + + if (!DivIsSigned) { // udiv + LoBound = Prod; + LoOverflow = ProdOV; + HiOverflow = ProdOV || + AddWithOverflow(HiBound, LoBound, DivRHS, false); + } else if (DivRHS->getValue().isPositive()) { // Divisor is > 0. + if (CI->isNullValue()) { // (X / pos) op 0 + // Can't overflow. + LoBound = cast(ConstantExpr::getNeg(SubOne(DivRHS))); + HiBound = DivRHS; + } else if (CI->getValue().isPositive()) { // (X / pos) op pos + LoBound = Prod; + LoOverflow = ProdOV; + HiOverflow = ProdOV || + AddWithOverflow(HiBound, Prod, DivRHS, true); + } else { // (X / pos) op neg + Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS)); + LoOverflow = AddWithOverflow(LoBound, Prod, + cast(DivRHSH), true); + HiBound = AddOne(Prod); + HiOverflow = ProdOV; + } + } else { // Divisor is < 0. + if (CI->isNullValue()) { // (X / neg) op 0 + LoBound = AddOne(DivRHS); + HiBound = cast(ConstantExpr::getNeg(DivRHS)); + if (HiBound == DivRHS) + LoBound = 0; // - INTMIN = INTMIN + } else if (CI->getValue().isPositive()) { // (X / neg) op pos + HiOverflow = LoOverflow = ProdOV; + if (!LoOverflow) + LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS), + true); + HiBound = AddOne(Prod); + } else { // (X / neg) op neg + LoBound = Prod; + LoOverflow = HiOverflow = ProdOV; + HiBound = Subtract(Prod, DivRHS); + } + + // Dividing by a negate swaps the condition. + predicate = ICmpInst::getSwappedPredicate(predicate); + } + + if (LoBound) { + Value *X = LHSI->getOperand(0); + switch (predicate) { + default: assert(0 && "Unhandled icmp opcode!"); + case ICmpInst::ICMP_EQ: + if (LoOverflow && HiOverflow) + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); + else if (HiOverflow) + return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : + ICmpInst::ICMP_UGE, X, LoBound); + else if (LoOverflow) + return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : + ICmpInst::ICMP_ULT, X, HiBound); + else + return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, + true, I); + case ICmpInst::ICMP_NE: + if (LoOverflow && HiOverflow) + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); + else if (HiOverflow) + return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : + ICmpInst::ICMP_ULT, X, LoBound); + else if (LoOverflow) + return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : + ICmpInst::ICMP_UGE, X, HiBound); + else + return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, + false, I); + case ICmpInst::ICMP_ULT: + case ICmpInst::ICMP_SLT: + if (LoOverflow) + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); + return new ICmpInst(predicate, X, LoBound); + case ICmpInst::ICMP_UGT: + case ICmpInst::ICMP_SGT: + if (HiOverflow) + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); + if (predicate == ICmpInst::ICMP_UGT) + return new ICmpInst(ICmpInst::ICMP_UGE, X, HiBound); + else + return new ICmpInst(ICmpInst::ICMP_SGE, X, HiBound); + } + } + } + break; + } + + // Simplify icmp_eq and icmp_ne instructions with integer constant RHS. + if (I.isEquality()) { + bool isICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE; + + // If the first operand is (add|sub|and|or|xor|rem) with a constant, and + // the second operand is a constant, simplify a bit. + if (BinaryOperator *BO = dyn_cast(Op0)) { + switch (BO->getOpcode()) { + case Instruction::SRem: + // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one. + if (CI->isZero() && isa(BO->getOperand(1)) && + BO->hasOneUse()) { + const APInt& V = cast(BO->getOperand(1))->getValue(); + if (V.sgt(APInt(V.getBitWidth(), 1)) && V.isPowerOf2()) { + Value *NewRem = InsertNewInstBefore(BinaryOperator::createURem( + BO->getOperand(0), BO->getOperand(1), BO->getName()), I); + return new ICmpInst(I.getPredicate(), NewRem, + Constant::getNullValue(BO->getType())); + } + } + break; + case Instruction::Add: + // Replace ((add A, B) != C) with (A != C-B) if B & C are constants. + if (ConstantInt *BOp1C = dyn_cast(BO->getOperand(1))) { + if (BO->hasOneUse()) + return new ICmpInst(I.getPredicate(), BO->getOperand(0), + Subtract(CI, BOp1C)); + } else if (CI->isNullValue()) { + // Replace ((add A, B) != 0) with (A != -B) if A or B is + // efficiently invertible, or if the add has just this one use. + Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1); + + if (Value *NegVal = dyn_castNegVal(BOp1)) + return new ICmpInst(I.getPredicate(), BOp0, NegVal); + else if (Value *NegVal = dyn_castNegVal(BOp0)) + return new ICmpInst(I.getPredicate(), NegVal, BOp1); + else if (BO->hasOneUse()) { + Instruction *Neg = BinaryOperator::createNeg(BOp1); + InsertNewInstBefore(Neg, I); + Neg->takeName(BO); + return new ICmpInst(I.getPredicate(), BOp0, Neg); + } + } + break; + case Instruction::Xor: + // For the xor case, we can xor two constants together, eliminating + // the explicit xor. + if (Constant *BOC = dyn_cast(BO->getOperand(1))) + return new ICmpInst(I.getPredicate(), BO->getOperand(0), + ConstantExpr::getXor(CI, BOC)); + + // FALLTHROUGH + case Instruction::Sub: + // Replace (([sub|xor] A, B) != 0) with (A != B) + if (CI->isZero()) + return new ICmpInst(I.getPredicate(), BO->getOperand(0), + BO->getOperand(1)); + break; + + case Instruction::Or: + // If bits are being or'd in that are not present in the constant we + // are comparing against, then the comparison could never succeed! + if (Constant *BOC = dyn_cast(BO->getOperand(1))) { + Constant *NotCI = ConstantExpr::getNot(CI); + if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue()) + return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, + isICMP_NE)); + } + break; + + case Instruction::And: + if (ConstantInt *BOC = dyn_cast(BO->getOperand(1))) { + // If bits are being compared against that are and'd out, then the + // comparison can never succeed! + if (!And(CI, ConstantInt::get(~BOC->getValue()))->isZero()) + return ReplaceInstUsesWith(I, ConstantInt::get(Type::Int1Ty, + isICMP_NE)); + + // If we have ((X & C) == C), turn it into ((X & C) != 0). + if (CI == BOC && isOneBitSet(CI)) + return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : + ICmpInst::ICMP_NE, Op0, + Constant::getNullValue(CI->getType())); + + // Replace (and X, (1 << size(X)-1) != 0) with x s< 0 + if (isSignBit(BOC)) { + Value *X = BO->getOperand(0); + Constant *Zero = Constant::getNullValue(X->getType()); + ICmpInst::Predicate pred = isICMP_NE ? + ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE; + return new ICmpInst(pred, X, Zero); + } + + // ((X & ~7) == 0) --> X < 8 + if (CI->isNullValue() && isHighOnes(BOC)) { + Value *X = BO->getOperand(0); + Constant *NegX = ConstantExpr::getNeg(BOC); + ICmpInst::Predicate pred = isICMP_NE ? + ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT; + return new ICmpInst(pred, X, NegX); + } + + } + default: break; + } + } else if (IntrinsicInst *II = dyn_cast(Op0)) { + // Handle icmp {eq|ne} , intcst. + if (II->getIntrinsicID() == Intrinsic::bswap) { + AddToWorkList(II); + I.setOperand(0, II->getOperand(1)); + I.setOperand(1, ConstantInt::get(CI->getValue().byteSwap())); + return &I; + } + } + } else { // Not a ICMP_EQ/ICMP_NE + // If the LHS is a cast from an integral value of the same size, then + // since we know the RHS is a constant, try to simlify. + if (CastInst *Cast = dyn_cast(Op0)) { + Value *CastOp = Cast->getOperand(0); + const Type *SrcTy = CastOp->getType(); + uint32_t SrcTySize = SrcTy->getPrimitiveSizeInBits(); + if (SrcTy->isInteger() && + SrcTySize == Cast->getType()->getPrimitiveSizeInBits()) { + // If this is an unsigned comparison, try to make the comparison use + // smaller constant values. + switch (I.getPredicate()) { + default: break; + case ICmpInst::ICMP_ULT: { // X u< 128 => X s> -1 + ConstantInt *CUI = cast(CI); + if (CUI->getValue() == APInt::getSignBit(SrcTySize)) + return new ICmpInst(ICmpInst::ICMP_SGT, CastOp, + ConstantInt::get(APInt::getAllOnesValue(SrcTySize))); + break; + } + case ICmpInst::ICMP_UGT: { // X u> 127 => X s< 0 + ConstantInt *CUI = cast(CI); + if (CUI->getValue() == APInt::getSignedMaxValue(SrcTySize)) + return new ICmpInst(ICmpInst::ICMP_SLT, CastOp, + Constant::getNullValue(SrcTy)); + break; + } + } + + } + } + } } - // Handle icmp with constant (but not simple integer constant) RHS + // Handle icmp with constant RHS if (Constant *RHSC = dyn_cast(Op1)) { if (Instruction *LHSI = dyn_cast(Op0)) switch (LHSI->getOpcode()) { @@ -4895,524 +5377,9 @@ return Changed ? &I : 0; } -/// visitICmpInstWithInstAndIntCst - Handle "icmp (instr, intcst)". -/// -Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, - Instruction *LHSI, - ConstantInt *RHS) { - const APInt &RHSV = RHS->getValue(); - - switch (LHSI->getOpcode()) { - case Instruction::Xor: // (icmp pred (and X, XorCST), CI) - if (ConstantInt *XorCST = dyn_cast(LHSI->getOperand(1))) { - // If this is a comparison that tests the signbit (X < 0) or (x > -1), - // fold the xor. - if (ICI.getPredicate() == ICmpInst::ICMP_SLT && RHSV == 0 || - ICI.getPredicate() == ICmpInst::ICMP_SGT && RHSV.isAllOnesValue()) { - Value *CompareVal = LHSI->getOperand(0); - - // If the sign bit of the XorCST is not set, there is no change to - // the operation, just stop using the Xor. - if (!XorCST->getValue().isNegative()) { - ICI.setOperand(0, CompareVal); - AddToWorkList(LHSI); - return &ICI; - } - - // Was the old condition true if the operand is positive? - bool isTrueIfPositive = ICI.getPredicate() == ICmpInst::ICMP_SGT; - - // If so, the new one isn't. - isTrueIfPositive ^= true; - - if (isTrueIfPositive) - return new ICmpInst(ICmpInst::ICMP_SGT, CompareVal, SubOne(RHS)); - else - return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(RHS)); - } - } - break; - case Instruction::And: // (icmp pred (and X, AndCST), RHS) - if (LHSI->hasOneUse() && isa(LHSI->getOperand(1)) && - LHSI->getOperand(0)->hasOneUse()) { - ConstantInt *AndCST = cast(LHSI->getOperand(1)); - - // If the LHS is an AND of a truncating cast, we can widen the - // and/compare to be the input width without changing the value - // produced, eliminating a cast. - if (CastInst *Cast = dyn_cast(LHSI->getOperand(0))) { - // We can do this transformation if either the AND constant does not - // have its sign bit set or if it is an equality comparison. - // Extending a relational comparison when we're checking the sign - // bit would not work. - if (Cast->hasOneUse() && isa(Cast) && - (ICI.isEquality() || AndCST->getValue().isPositive() && - RHSV.isPositive())) { - ConstantInt *NewCST; - ConstantInt *NewCI; - APInt NewCSTVal(AndCST->getValue()), NewCIVal(RHSV); - uint32_t BitWidth = - cast(Cast->getOperand(0)->getType())->getBitWidth(); - NewCST = ConstantInt::get(NewCSTVal.zext(BitWidth)); - NewCI = ConstantInt::get(NewCIVal.zext(BitWidth)); - Instruction *NewAnd = - BinaryOperator::createAnd(Cast->getOperand(0), NewCST, - LHSI->getName()); - InsertNewInstBefore(NewAnd, ICI); - return new ICmpInst(ICI.getPredicate(), NewAnd, NewCI); - } - } - - // If this is: (X >> C1) & C2 != C3 (where any shift and any compare - // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This - // happens a LOT in code produced by the C front-end, for bitfield - // access. - BinaryOperator *Shift = dyn_cast(LHSI->getOperand(0)); - if (Shift && !Shift->isShift()) - Shift = 0; - - ConstantInt *ShAmt; - ShAmt = Shift ? dyn_cast(Shift->getOperand(1)) : 0; - const Type *Ty = Shift ? Shift->getType() : 0; // Type of the shift. - const Type *AndTy = AndCST->getType(); // Type of the and. - - // We can fold this as long as we can't shift unknown bits - // into the mask. This can only happen with signed shift - // rights, as they sign-extend. - if (ShAmt) { - bool CanFold = Shift->isLogicalShift(); - if (!CanFold) { - // To test for the bad case of the signed shr, see if any - // of the bits shifted in could be tested after the mask. - uint32_t TyBits = Ty->getPrimitiveSizeInBits(); - int ShAmtVal = TyBits - ShAmt->getLimitedValue(TyBits); - - uint32_t BitWidth = AndTy->getPrimitiveSizeInBits(); - if ((APInt::getHighBitsSet(BitWidth, BitWidth-ShAmtVal) & - AndCST->getValue()) == 0) - CanFold = true; - } - - if (CanFold) { - Constant *NewCst; - if (Shift->getOpcode() == Instruction::Shl) - NewCst = ConstantExpr::getLShr(RHS, ShAmt); - else - NewCst = ConstantExpr::getShl(RHS, ShAmt); - - // Check to see if we are shifting out any of the bits being - // compared. - if (ConstantExpr::get(Shift->getOpcode(), NewCst, ShAmt) != RHS) { - // If we shifted bits out, the fold is not going to work out. - // As a special case, check to see if this means that the - // result is always true or false now. - if (ICI.getPredicate() == ICmpInst::ICMP_EQ) - return ReplaceInstUsesWith(ICI, ConstantInt::getFalse()); - if (ICI.getPredicate() == ICmpInst::ICMP_NE) - return ReplaceInstUsesWith(ICI, ConstantInt::getTrue()); - } else { - ICI.setOperand(1, NewCst); - Constant *NewAndCST; - if (Shift->getOpcode() == Instruction::Shl) - NewAndCST = ConstantExpr::getLShr(AndCST, ShAmt); - else - NewAndCST = ConstantExpr::getShl(AndCST, ShAmt); - LHSI->setOperand(1, NewAndCST); - LHSI->setOperand(0, Shift->getOperand(0)); - AddToWorkList(Shift); // Shift is dead. - AddUsesToWorkList(ICI); - return &ICI; - } - } - } - - // Turn ((X >> Y) & C) == 0 into (X & (C << Y)) == 0. The later is - // preferable because it allows the C<hasOneUse() && RHSV == 0 && - ICI.isEquality() && !Shift->isArithmeticShift() && - isa(Shift->getOperand(0))) { - // Compute C << Y. - Value *NS; - if (Shift->getOpcode() == Instruction::LShr) { - NS = BinaryOperator::createShl(AndCST, - Shift->getOperand(1), "tmp"); - } else { - // Insert a logical shift. - NS = BinaryOperator::createLShr(AndCST, - Shift->getOperand(1), "tmp"); - } - InsertNewInstBefore(cast(NS), ICI); - - // Compute X & (C << Y). - Instruction *NewAnd = - BinaryOperator::createAnd(Shift->getOperand(0), NS, LHSI->getName()); - InsertNewInstBefore(NewAnd, ICI); - - ICI.setOperand(0, NewAnd); - return &ICI; - } - } - break; - - case Instruction::Shl: // (icmp pred (shl X, ShAmt), CI) - if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { - if (ICI.isEquality()) { - uint32_t TypeBits = RHSV.getBitWidth(); - - // Check that the shift amount is in range. If not, don't perform - // undefined shifts. When the shift is visited it will be - // simplified. - if (ShAmt->uge(TypeBits)) - break; - - // If we are comparing against bits always shifted out, the - // comparison cannot succeed. - Constant *Comp = - ConstantExpr::getShl(ConstantExpr::getLShr(RHS, ShAmt), ShAmt); - if (Comp != RHS) {// Comparing against a bit that we know is zero. - bool IsICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE; - Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE); - return ReplaceInstUsesWith(ICI, Cst); - } - - if (LHSI->hasOneUse()) { - // Otherwise strength reduce the shift into an and. - uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); - Constant *Mask = - ConstantInt::get(APInt::getLowBitsSet(TypeBits, TypeBits-ShAmtVal)); - - Instruction *AndI = - BinaryOperator::createAnd(LHSI->getOperand(0), - Mask, LHSI->getName()+".mask"); - Value *And = InsertNewInstBefore(AndI, ICI); - return new ICmpInst(ICI.getPredicate(), And, - ConstantInt::get(RHSV << ShAmtVal)); - } - } - } - break; - - case Instruction::LShr: // (icmp pred (shr X, ShAmt), CI) - case Instruction::AShr: - if (ConstantInt *ShAmt = dyn_cast(LHSI->getOperand(1))) { - if (ICI.isEquality()) { - // Check that the shift amount is in range. If not, don't perform - // undefined shifts. When the shift is visited it will be - // simplified. - uint32_t TypeBits = RHSV.getBitWidth(); - if (ShAmt->uge(TypeBits)) - break; - uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); - - // If we are comparing against bits always shifted out, the - // comparison cannot succeed. - APInt Comp = RHSV << ShAmtVal; - if (LHSI->getOpcode() == Instruction::LShr) - Comp = Comp.lshr(ShAmtVal); - else - Comp = Comp.ashr(ShAmtVal); - - if (Comp != RHSV) { // Comparing against a bit that we know is zero. - bool IsICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE; - Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE); - return ReplaceInstUsesWith(ICI, Cst); - } - - if (LHSI->hasOneUse() || RHSV == 0) { - // Otherwise strength reduce the shift into an and. - APInt Val(APInt::getHighBitsSet(TypeBits, TypeBits - ShAmtVal)); - Constant *Mask = ConstantInt::get(Val); - - Instruction *AndI = - BinaryOperator::createAnd(LHSI->getOperand(0), - Mask, LHSI->getName()+".mask"); - Value *And = InsertNewInstBefore(AndI, ICI); - return new ICmpInst(ICI.getPredicate(), And, - ConstantExpr::getShl(RHS, ShAmt)); - } - } - } - break; - - case Instruction::SDiv: - case Instruction::UDiv: - // Fold: icmp pred ([us]div X, C1), C2 -> range test - // Fold this div into the comparison, producing a range check. - // Determine, based on the divide type, what the range is being - // checked. If there is an overflow on the low or high side, remember - // it, otherwise compute the range [low, hi) bounding the new value. - // See: InsertRangeTest above for the kinds of replacements possible. - if (ConstantInt *DivRHS = dyn_cast(LHSI->getOperand(1))) { - // FIXME: If the operand types don't match the type of the divide - // then don't attempt this transform. The code below doesn't have the - // logic to deal with a signed divide and an unsigned compare (and - // vice versa). This is because (x /s C1) getOpcode() == Instruction::SDiv; - if (!ICI.isEquality() && DivIsSigned != ICI.isSignedPredicate()) - break; - if (DivRHS->isZero()) - break; // Don't hack on div by zero - - // Initialize the variables that will indicate the nature of the - // range check. - bool LoOverflow = false, HiOverflow = false; - ConstantInt *LoBound = 0, *HiBound = 0; - - // Compute Prod = CI * DivRHS. We are essentially solving an equation - // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and - // C2 (CI). By solving for X we can turn this into a range check - // instead of computing a divide. - ConstantInt *Prod = Multiply(RHS, DivRHS); - - // Determine if the product overflows by seeing if the product is - // not equal to the divide. Make sure we do the same kind of divide - // as in the LHS instruction that we're folding. - bool ProdOV = (DivIsSigned ? ConstantExpr::getSDiv(Prod, DivRHS) : - ConstantExpr::getUDiv(Prod, DivRHS)) != RHS; - - // Get the ICmp opcode - ICmpInst::Predicate predicate = ICI.getPredicate(); - - if (!DivIsSigned) { // udiv - LoBound = Prod; - LoOverflow = ProdOV; - HiOverflow = ProdOV || - AddWithOverflow(HiBound, LoBound, DivRHS, false); - } else if (DivRHS->getValue().isPositive()) { // Divisor is > 0. - if (RHSV == 0) { // (X / pos) op 0 - // Can't overflow. - LoBound = cast(ConstantExpr::getNeg(SubOne(DivRHS))); - HiBound = DivRHS; - } else if (RHSV.isPositive()) { // (X / pos) op pos - LoBound = Prod; - LoOverflow = ProdOV; - HiOverflow = ProdOV || - AddWithOverflow(HiBound, Prod, DivRHS, true); - } else { // (X / pos) op neg - Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS)); - LoOverflow = AddWithOverflow(LoBound, Prod, - cast(DivRHSH), true); - HiBound = AddOne(Prod); - HiOverflow = ProdOV; - } - } else { // Divisor is < 0. - if (RHSV == 0) { // (X / neg) op 0 - LoBound = AddOne(DivRHS); - HiBound = cast(ConstantExpr::getNeg(DivRHS)); - if (HiBound == DivRHS) - LoBound = 0; // - INTMIN = INTMIN - } else if (RHSV.isPositive()) { // (X / neg) op pos - HiOverflow = LoOverflow = ProdOV; - if (!LoOverflow) - LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS), - true); - HiBound = AddOne(Prod); - } else { // (X / neg) op neg - LoBound = Prod; - LoOverflow = HiOverflow = ProdOV; - HiBound = Subtract(Prod, DivRHS); - } - - // Dividing by a negate swaps the condition. - predicate = ICmpInst::getSwappedPredicate(predicate); - } - - if (LoBound) { - Value *X = LHSI->getOperand(0); - switch (predicate) { - default: assert(0 && "Unhandled icmp opcode!"); - case ICmpInst::ICMP_EQ: - if (LoOverflow && HiOverflow) - return ReplaceInstUsesWith(ICI, ConstantInt::getFalse()); - else if (HiOverflow) - return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : - ICmpInst::ICMP_UGE, X, LoBound); - else if (LoOverflow) - return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : - ICmpInst::ICMP_ULT, X, HiBound); - else - return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, - true, ICI); - case ICmpInst::ICMP_NE: - if (LoOverflow && HiOverflow) - return ReplaceInstUsesWith(ICI, ConstantInt::getTrue()); - else if (HiOverflow) - return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT : - ICmpInst::ICMP_ULT, X, LoBound); - else if (LoOverflow) - return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE : - ICmpInst::ICMP_UGE, X, HiBound); - else - return InsertRangeTest(X, LoBound, HiBound, DivIsSigned, - false, ICI); - case ICmpInst::ICMP_ULT: - case ICmpInst::ICMP_SLT: - if (LoOverflow) - return ReplaceInstUsesWith(ICI, ConstantInt::getFalse()); - return new ICmpInst(predicate, X, LoBound); - case ICmpInst::ICMP_UGT: - case ICmpInst::ICMP_SGT: - if (HiOverflow) - return ReplaceInstUsesWith(ICI, ConstantInt::getFalse()); - if (predicate == ICmpInst::ICMP_UGT) - return new ICmpInst(ICmpInst::ICMP_UGE, X, HiBound); - else - return new ICmpInst(ICmpInst::ICMP_SGE, X, HiBound); - } - } - } - break; - } - - // Simplify icmp_eq and icmp_ne instructions with integer constant RHS. - if (ICI.isEquality()) { - bool isICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE; - - // If the first operand is (add|sub|and|or|xor|rem) with a constant, and - // the second operand is a constant, simplify a bit. - if (BinaryOperator *BO = dyn_cast(LHSI)) { - switch (BO->getOpcode()) { - case Instruction::SRem: - // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one. - if (RHSV == 0 && isa(BO->getOperand(1)) &&BO->hasOneUse()){ - const APInt &V = cast(BO->getOperand(1))->getValue(); - if (V.sgt(APInt(V.getBitWidth(), 1)) && V.isPowerOf2()) { - Instruction *NewRem = - BinaryOperator::createURem(BO->getOperand(0), BO->getOperand(1), - BO->getName()); - InsertNewInstBefore(NewRem, ICI); - return new ICmpInst(ICI.getPredicate(), NewRem, - Constant::getNullValue(BO->getType())); - } - } - break; - case Instruction::Add: - // Replace ((add A, B) != C) with (A != C-B) if B & C are constants. - if (ConstantInt *BOp1C = dyn_cast(BO->getOperand(1))) { - if (BO->hasOneUse()) - return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), - Subtract(RHS, BOp1C)); - } else if (RHSV == 0) { - // Replace ((add A, B) != 0) with (A != -B) if A or B is - // efficiently invertible, or if the add has just this one use. - Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1); - - if (Value *NegVal = dyn_castNegVal(BOp1)) - return new ICmpInst(ICI.getPredicate(), BOp0, NegVal); - else if (Value *NegVal = dyn_castNegVal(BOp0)) - return new ICmpInst(ICI.getPredicate(), NegVal, BOp1); - else if (BO->hasOneUse()) { - Instruction *Neg = BinaryOperator::createNeg(BOp1); - InsertNewInstBefore(Neg, ICI); - Neg->takeName(BO); - return new ICmpInst(ICI.getPredicate(), BOp0, Neg); - } - } - break; - case Instruction::Xor: - // For the xor case, we can xor two constants together, eliminating - // the explicit xor. - if (Constant *BOC = dyn_cast(BO->getOperand(1))) - return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), - ConstantExpr::getXor(RHS, BOC)); - - // FALLTHROUGH - case Instruction::Sub: - // Replace (([sub|xor] A, B) != 0) with (A != B) - if (RHSV == 0) - return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), - BO->getOperand(1)); - break; - - case Instruction::Or: - // If bits are being or'd in that are not present in the constant we - // are comparing against, then the comparison could never succeed! - if (Constant *BOC = dyn_cast(BO->getOperand(1))) { - Constant *NotCI = ConstantExpr::getNot(RHS); - if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue()) - return ReplaceInstUsesWith(ICI, ConstantInt::get(Type::Int1Ty, - isICMP_NE)); - } - break; - - case Instruction::And: - if (ConstantInt *BOC = dyn_cast(BO->getOperand(1))) { - // If bits are being compared against that are and'd out, then the - // comparison can never succeed! - if ((RHSV & ~BOC->getValue()) != 0) - return ReplaceInstUsesWith(ICI, ConstantInt::get(Type::Int1Ty, - isICMP_NE)); - - // If we have ((X & C) == C), turn it into ((X & C) != 0). - if (RHS == BOC && RHSV.isPowerOf2()) - return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : - ICmpInst::ICMP_NE, RHS, - Constant::getNullValue(RHS->getType())); - - // Replace (and X, (1 << size(X)-1) != 0) with x s< 0 - if (isSignBit(BOC)) { - Value *X = BO->getOperand(0); - Constant *Zero = Constant::getNullValue(X->getType()); - ICmpInst::Predicate pred = isICMP_NE ? - ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE; - return new ICmpInst(pred, X, Zero); - } - - // ((X & ~7) == 0) --> X < 8 - if (RHSV == 0 && isHighOnes(BOC)) { - Value *X = BO->getOperand(0); - Constant *NegX = ConstantExpr::getNeg(BOC); - ICmpInst::Predicate pred = isICMP_NE ? - ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT; - return new ICmpInst(pred, X, NegX); - } - } - default: break; - } - } else if (IntrinsicInst *II = dyn_cast(LHSI)) { - // Handle icmp {eq|ne} , intcst. - if (II->getIntrinsicID() == Intrinsic::bswap) { - AddToWorkList(II); - ICI.setOperand(0, II->getOperand(1)); - ICI.setOperand(1, ConstantInt::get(RHSV.byteSwap())); - return &ICI; - } - } - } else { // Not a ICMP_EQ/ICMP_NE - // If the LHS is a cast from an integral value of the same size, then - // since we know the RHS is a constant, try to simlify. - if (CastInst *Cast = dyn_cast(LHSI)) { - Value *CastOp = Cast->getOperand(0); - const Type *SrcTy = CastOp->getType(); - uint32_t SrcTySize = SrcTy->getPrimitiveSizeInBits(); - if (SrcTy->isInteger() && - SrcTySize == Cast->getType()->getPrimitiveSizeInBits()) { - // If this is an unsigned comparison, try to make the comparison use - // smaller constant values. - if (ICI.getPredicate() == ICmpInst::ICMP_ULT && RHSV.isSignBit()) { - // X u< 128 => X s> -1 - return new ICmpInst(ICmpInst::ICMP_SGT, CastOp, - ConstantInt::get(APInt::getAllOnesValue(SrcTySize))); - } else if (ICI.getPredicate() == ICmpInst::ICMP_UGT && - RHSV == APInt::getSignedMaxValue(SrcTySize)) { - // X u> 127 => X s< 0 - return new ICmpInst(ICmpInst::ICMP_SLT, CastOp, - Constant::getNullValue(SrcTy)); - } - } - } - } - return 0; -} - -/// visitICmpInstWithCastAndCast - Handle icmp (cast x to y), (cast/cst). -/// We only handle extending casts so far. -/// +// visitICmpInstWithCastAndCast - Handle icmp (cast x to y), (cast/cst). +// We only handle extending casts so far. +// Instruction *InstCombiner::visitICmpInstWithCastAndCast(ICmpInst &ICI) { const CastInst *LHSCI = cast(ICI.getOperand(0)); Value *LHSCIOp = LHSCI->getOperand(0); From reid at x10sys.com Tue Apr 3 03:29:02 2007 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Apr 2007 03:29:02 -0500 Subject: [llvm-commits] CVS: llvm/utils/NewNightlyTest.pl Message-ID: <200704030829.l338T27p018299@zion.cs.uiuc.edu> Changes in directory llvm/utils: NewNightlyTest.pl updated: 1.65 -> 1.66 --- Log message: Prepare for Subversion migration by implementing a -usesvn to tell the script to to check out llvm and llvm-test from Subversion instead of CVS. Without this option the script will continue to check out from CVS. To specify the Subversion URL, set the SVNURL environment variable or pass -svnurl followed by the URL. For now, -svnurl will default to Reid's temporary (read-only, daily snapshot) SVN server. Try it out if you like! --- Diffs of the changes: (+147 -62) NewNightlyTest.pl | 209 +++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 147 insertions(+), 62 deletions(-) Index: llvm/utils/NewNightlyTest.pl diff -u llvm/utils/NewNightlyTest.pl:1.65 llvm/utils/NewNightlyTest.pl:1.66 --- llvm/utils/NewNightlyTest.pl:1.65 Fri Nov 24 14:34:16 2006 +++ llvm/utils/NewNightlyTest.pl Tue Apr 3 03:28:44 2007 @@ -1,6 +1,7 @@ #!/usr/bin/perl use POSIX qw(strftime); use File::Copy; +use Date::Parse; use Socket; # @@ -45,6 +46,10 @@ # -gccpath Path to gcc/g++ used to build LLVM # -cvstag Check out a specific CVS tag to build LLVM (useful for # testing release branches) +# -usesvn Check code out from a subversion repository. With no +# argument, use the standard repository. An argument specifies +# the repository URL to use. +# -svnurl Specify the SVN URL where LLVM can be found # -target Specify the target triplet # -cflags Next argument specifies that C compilation options that # override the default. @@ -91,6 +96,8 @@ # ############################################################## my $HOME = $ENV{'HOME'}; +my $SVNURL = $ENV{"SVNURL"}; +$SVNURL = 'svn://anon at hlvm.org:3691/llvm.svn' unless $SVNURL; my $CVSRootDir = $ENV{'CVSROOT'}; $CVSRootDir = "/home/vadve/shared/PublicCVS" unless $CVSRootDir; my $BuildDir = $ENV{'BUILDDIR'}; @@ -116,6 +123,7 @@ $CONFIGUREARGS=""; $nickname=""; $NOTEST=0; +$USESVN=0; $NORUNNINGTESTS=0; $MAKECMD="make"; $SUBMITSERVER = "llvm.org"; @@ -163,6 +171,8 @@ else { $GCCPATH=""; } if (/^-cvstag/) { $CVSCOOPT .= " -r $ARGV[0]"; shift; next; } else { $CVSCOOPT="";} + if (/^-usesvn/) { $USESVN = 1; } + if (/^-svnurl/) { $SVNURL = $ARGV[0]; shift; next; } if (/^-target/) { $CONFIGUREARGS .= " --target=$ARGV[0]"; shift; next; } if (/^-cflags/) { $MAKEOPTS = "$MAKEOPTS C.Flags=\'$ARGV[0]\'"; @@ -225,7 +235,7 @@ ############################################################## my $Prefix = "$WebDir/$DATE"; my $BuildLog = "$Prefix-Build-Log.txt"; -my $CVSLog = "$Prefix-CVS-Log.txt"; +my $COLog = "$Prefix-CVS-Log.txt"; my $OldenTestsLog = "$Prefix-Olden-tests.txt"; my $SingleSourceLog = "$Prefix-SingleSource-ProgramTest.txt.gz"; my $MultiSourceLog = "$Prefix-MultiSource-ProgramTest.txt.gz"; @@ -242,11 +252,15 @@ if ($VERBOSE) { print "INITIALIZED\n"; - print "CVS Root = $CVSRootDir\n"; + if ($USESVN) { + print "SVN URL = $SVNURL\n"; + } else { + print "CVS Root = $CVSRootDir\n"; + } + print "COLog = $COLog\n"; print "BuildDir = $BuildDir\n"; print "WebDir = $WebDir\n"; print "Prefix = $Prefix\n"; - print "CVSLog = $CVSLog\n"; print "BuildLog = $BuildLog\n"; } @@ -477,39 +491,48 @@ print "Build directory exists! Removing it\n"; } system "rm -rf $BuildDir"; - mkdir $BuildDir or die "Could not create CVS checkout directory $BuildDir!"; + mkdir $BuildDir or die "Could not create checkout directory $BuildDir!"; } else { if ( $VERBOSE ) { print "Build directory exists!\n"; } } } else { - mkdir $BuildDir or die "Could not create CVS checkout directory $BuildDir!"; + mkdir $BuildDir or die "Could not create checkout directory $BuildDir!"; } } -ChangeDir( $BuildDir, "CVS checkout directory" ); +ChangeDir( $BuildDir, "checkout directory" ); ############################################################## # -# Check out the llvm tree, saving CVS messages to the cvs log... +# Check out the llvm tree, using either SVN or CVS # ############################################################## -my $CVSOPT = ""; -# Use compression if going over ssh. -$CVSOPT = "-z3" - if $CVSRootDir =~ /^:ext:/; -my $CVSCMD = "$NICE cvs $CVSOPT -d $CVSRootDir co -P $CVSCOOPT"; if (!$NOCHECKOUT) { if ( $VERBOSE ) { print "CHECKOUT STAGE:\n"; - print "( time -p $CVSCMD llvm; cd llvm/projects ; $CVSCMD llvm-test ) " . - "> $CVSLog 2>&1\n"; } - system "( time -p $CVSCMD llvm; cd llvm/projects ; " . - "$CVSCMD llvm-test ) > $CVSLog 2>&1"; - ChangeDir( $BuildDir , "CVS Checkout directory") ; + if ($USESVN) { + my $SVNCMD = "$NICE svn co $SVNURL"; + if ($VERBOSE) { + print "( time -p $SVNCMD/llvm/trunk llvm; cd llvm/projects ; " . + "$SVNCMD/llvm-test/trunk llvm-test ) > $COLog 2>&1\n"; + system "( time -p $SVNCMD/llvm/trunk llvm; cd llvm/projects ; " . + "$SVNCMD/llvm-test/trunk llvm-test ) > $COLog 2>&1\n"; + } + } else { + my $CVSOPT = ""; + $CVSOPT = "-z3" # Use compression if going over ssh. + if $CVSRootDir =~ /^:ext:/; + my $CVSCMD = "$NICE cvs $CVSOPT -d $CVSRootDir co -P $CVSCOOPT"; + print "( time -p $CVSCMD llvm; cd llvm/projects ; " . + "$CVSCMD llvm-test ) > $COLog 2>&1"; + system "( time -p $CVSCMD llvm; cd llvm/projects ; " . + "$CVSCMD llvm-test ) > $COLog 2>&1"; + } } +ChangeDir( $BuildDir , "Checkout directory") ; ChangeDir( "llvm" , "llvm source directory") ; ############################################################## @@ -519,14 +542,20 @@ # This can probably be put on the server side # ############################################################## -my $CVSCheckoutTime_Wall = GetRegex "([0-9.]+)", `grep '^real' $CVSLog`; -my $CVSCheckoutTime_User = GetRegex "([0-9.]+)", `grep '^user' $CVSLog`; -my $CVSCheckoutTime_Sys = GetRegex "([0-9.]+)", `grep '^sys' $CVSLog`; -my $CVSCheckoutTime_CPU = $CVSCheckoutTime_User + $CVSCheckoutTime_Sys; - -my $NumFilesInCVS = `egrep '^U' $CVSLog | wc -l` + 0; -my $NumDirsInCVS = - `egrep '^cvs (checkout|server|update):' $CVSLog | wc -l` + 0; +my $CheckoutTime_Wall = GetRegex "([0-9.]+)", `grep '^real' $COLog`; +my $CheckoutTime_User = GetRegex "([0-9.]+)", `grep '^user' $COLog`; +my $CheckoutTime_Sys = GetRegex "([0-9.]+)", `grep '^sys' $COLog`; +my $CheckoutTime_CPU = $CVSCheckoutTime_User + $CVSCheckoutTime_Sys; + +my $NumFilesInCVS = 0; +my $NumDirsInCVS = 0; +if ($USESVN) { + $NumFilesInCVS = `egrep '^A' $COLog | wc -l` + 0; + $NumDirsInCVS = `sed -e 's#/[^/]*$##' $COLog | sort | uniq | wc -l` + 0; +} else { + $NumFilesInCVS = `egrep '^U' $COLog | wc -l` + 0; + $NumDirsInCVS = `egrep '^cvs (checkout|server|update):' $COLog | wc -l` + 0; +} ############################################################## # @@ -538,47 +567,103 @@ my (%AddedFiles, %ModifiedFiles, %RemovedFiles, %UsersCommitted, %UsersUpdated); -if(!$NOCVSSTATS){ - +if (!$NOCVSSTATS) { if ($VERBOSE) { print "CVS HISTORY ANALYSIS STAGE\n"; } - @CVSHistory = split "\n", `cvs history -D '1 day ago' -a -xAMROCGUW`; -#print join "\n", @CVSHistory; print "\n"; - my $DateRE = '[-/:0-9 ]+\+[0-9]+'; - -# Loop over every record from the CVS history, filling in the hashes. - foreach $File (@CVSHistory) { - my ($Type, $Date, $UID, $Rev, $Filename); - if ($File =~ /([AMRUGC]) ($DateRE) ([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+)/) { - ($Type, $Date, $UID, $Rev, $Filename) = ($1, $2, $3, $4, "$6/$5"); - } elsif ($File =~ /([W]) ($DateRE) ([^ ]+)/) { - ($Type, $Date, $UID, $Rev, $Filename) = ($1, $2, $3, "", ""); - } elsif ($File =~ /([O]) ($DateRE) ([^ ]+) +([^ ]+)/) { - ($Type, $Date, $UID, $Rev, $Filename) = ($1, $2, $3, "", "$4/"); - } else { - print "UNMATCHABLE: $File\n"; - next; + if ($USESVN) { + my $delimiter = "----------------------------------------------------" . + "--------------------\n"; + @SVNHistory = split $delimiter, `svn log --verbose -r{$DATE}:HEAD`; + +# Skip very first entry. + shift @SVNHistory; + foreach $Record (@SVNHistory) { + my (@Lines, @Fields); + my ($Rev, $Author, $StrTime, $LogLines, $Time); + @Lines = split "\n", $Record; +# print join"\n", @Lines; + + ($Rev, $Author, $StrTime, $LogLines) = split ' \| ', $Lines[0]; + $Time = str2time($StrTime); + if (time() - $Time > 24*3600) { + next; } - # print "$File\nTy = $Type Date = '$Date' UID=$UID Rev=$Rev File = '$Filename'\n"; - - if ($Filename =~ /^llvm/) { - if ($Type eq 'M') { # Modified - $ModifiedFiles{$Filename} = 1; - $UsersCommitted{$UID} = 1; - } elsif ($Type eq 'A') { # Added - $AddedFiles{$Filename} = 1; - $UsersCommitted{$UID} = 1; - } elsif ($Type eq 'R') { # Removed - $RemovedFiles{$Filename} = 1; - $UsersCommitted{$UID} = 1; - } else { - $UsersUpdated{$UID} = 1; + + $UsersCommitted{$Author} = 1; + + #print $Rev, $Author, $Time, $LogLines, "\n"; + + my $i = 2; + while ($Lines[$i] ne '') { + my ($Type, $Filename, $FromFile, $FromRev); + #print $Lines[$i], "\n"; + + if ($Lines[$i] =~ / ([MAD]) ([^ ]+) \(from ([^ ]+):([^ ]+)\)/) { + ($Type, $Filename, $FromFile, $FromRev) = ($1, $2, $3, $4); + } elsif ($Lines[$i] =~ / ([MAD]) ([^ ]+)/) { + ($Type, $Filename, $FromFile, $FromRev) = ($1, $2, "", ""); + } else { + print "UNMATCHABLE: $Lines[$i]\n"; + } + + if ($Type eq 'M') { # Modified + $ModifiedFiles{$Filename} = 1; + } elsif ($Type eq 'A') { # Added + if ($FromFile eq "") { # File was added + $AddedFiles{$Filename} = 1; + } else { #File was added from another file - moved or copied. + $MovedFiles{$Filename} = 1; } + } elsif ($Type eq 'D') { # Removed + $RemovedFiles{$Filename} = 1; + } else { + print "INVALID TYPE: $Type"; + } + + #print $Filename, "\n"; + #print $Type, $File, $FromFile, $FromRev, "\n"; + ++$i; } - } + } + } else { + @CVSHistory = split "\n", `cvs history -D '1 day ago' -a -xAMROCGUW`; +#print join "\n", @CVSHistory; print "\n"; + + my $DateRE = '[-/:0-9 ]+\+[0-9]+'; - my $TestError = 1; +# Loop over every record from the CVS history, filling in the hashes. + foreach $File (@CVSHistory) { + my ($Type, $Date, $UID, $Rev, $Filename); + if ($File =~ /([AMRUGC]) ($DateRE) ([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+)/) { + ($Type, $Date, $UID, $Rev, $Filename) = ($1, $2, $3, $4, "$6/$5"); + } elsif ($File =~ /([W]) ($DateRE) ([^ ]+)/) { + ($Type, $Date, $UID, $Rev, $Filename) = ($1, $2, $3, "", ""); + } elsif ($File =~ /([O]) ($DateRE) ([^ ]+) +([^ ]+)/) { + ($Type, $Date, $UID, $Rev, $Filename) = ($1, $2, $3, "", "$4/"); + } else { + print "UNMATCHABLE: $File\n"; + next; + } + # print "$File\nTy = $Type Date = '$Date' UID=$UID Rev=$Rev File = '$Filename'\n"; + + if ($Filename =~ /^llvm/) { + if ($Type eq 'M') { # Modified + $ModifiedFiles{$Filename} = 1; + $UsersCommitted{$UID} = 1; + } elsif ($Type eq 'A') { # Added + $AddedFiles{$Filename} = 1; + $UsersCommitted{$UID} = 1; + } elsif ($Type eq 'R') { # Removed + $RemovedFiles{$Filename} = 1; + $UsersCommitted{$UID} = 1; + } else { + $UsersUpdated{$UID} = 1; + } + } + } + my $TestError = 1; + } #$USESVN }#!NOCVSSTATS my $CVSAddedFiles = join "\n", sort keys %AddedFiles; @@ -944,7 +1029,7 @@ my @CVS_DATA; my $cvs_data; - at CVS_DATA = ReadFile "$CVSLog"; + at CVS_DATA = ReadFile "$COLog"; $cvs_data = join("\n", @CVS_DATA); my @BUILD_DATA; @@ -990,8 +1075,8 @@ 'nickname' => $nickname, 'dejagnutime_wall' => $DejagnuWallTime, 'dejagnutime_cpu' => $DejagnuTime, - 'cvscheckouttime_wall' => $CVSCheckoutTime_Wall, - 'cvscheckouttime_cpu' => $CVSCheckoutTime_CPU, + 'cvscheckouttime_wall' => $CheckoutTime_Wall, + 'cvscheckouttime_cpu' => $CheckoutTime_CPU, 'configtime_wall' => $ConfigWallTime, 'configtime_cpu'=> $ConfigTime, 'buildtime_wall' => $BuildWallTime, From asl at math.spbu.ru Tue Apr 3 03:56:54 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 03 Apr 2007 12:56:54 +0400 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp In-Reply-To: <200704030812.l338C85l017774.SS49512SS@zion.cs.uiuc.edu> References: <200704030812.l338C85l017774.SS49512SS@zion.cs.uiuc.edu> Message-ID: <1175590614.9200.60.camel@asl.dorms.spbu.ru> > Reverting back to 1.723. The last two commits broke JM (and possibily others) on ARM. Definitely. Qt is broken too. Funny, but I see exactly the same errors, as soon after Reid's InstCombine APIntifiaction (some bits are missing, so tool outputs "settitle" instead of "setTitle" :) ). Will investigate this evening. Seems to be easy to reduce to one file. -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University. From nicolas.geoffray at lip6.fr Tue Apr 3 05:27:24 2007 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 3 Apr 2007 05:27:24 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCallingConv.td PPCISelLowering.cpp PPCInstr64Bit.td PPCInstrInfo.td PPCRegisterInfo.cpp Message-ID: <200704031027.l33ARO0P020780@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCCallingConv.td updated: 1.1 -> 1.2 PPCISelLowering.cpp updated: 1.265 -> 1.266 PPCInstr64Bit.td updated: 1.42 -> 1.43 PPCInstrInfo.td updated: 1.276 -> 1.277 PPCRegisterInfo.cpp updated: 1.118 -> 1.119 --- Log message: The ELF ABI specifies F1-F8 registers as argument registers for double, not F1-F10. This affects only ELF, not MachO. --- Diffs of the changes: (+12 -10) PPCCallingConv.td | 4 ++-- PPCISelLowering.cpp | 6 +++--- PPCInstr64Bit.td | 2 +- PPCInstrInfo.td | 2 +- PPCRegisterInfo.cpp | 8 +++++--- 5 files changed, 12 insertions(+), 10 deletions(-) Index: llvm/lib/Target/PowerPC/PPCCallingConv.td diff -u llvm/lib/Target/PowerPC/PPCCallingConv.td:1.1 llvm/lib/Target/PowerPC/PPCCallingConv.td:1.2 --- llvm/lib/Target/PowerPC/PPCCallingConv.td:1.1 Mon Mar 5 18:59:59 2007 +++ llvm/lib/Target/PowerPC/PPCCallingConv.td Tue Apr 3 05:27:07 2007 @@ -44,8 +44,8 @@ // Darwin passes FP values in F1 - F13 CCIfType<[f32, f64], CCIfSubtarget<"isMachoABI()", CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8,F9,F10,F11,F12,F13]>>>, - // Other sub-targets pass FP values in F1-10. - CCIfType<[f32, f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8, F9,F10]>>, + // Other sub-targets pass FP values in F1-F8. + CCIfType<[f32, f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>, // The first 12 Vector arguments are passed in altivec registers. CCIfType<[v16i8, v8i16, v4i32, v4f32], Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.265 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.266 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.265 Fri Mar 30 18:15:24 2007 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Apr 3 05:27:07 2007 @@ -1113,7 +1113,7 @@ static const unsigned FPR[] = { PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, - PPC::F8, PPC::F9, PPC::F10 + PPC::F8 }; return FPR; } @@ -1154,7 +1154,7 @@ }; const unsigned Num_GPR_Regs = sizeof(GPR_32)/sizeof(GPR_32[0]); - const unsigned Num_FPR_Regs = isMachoABI ? 13 : 10; + const unsigned Num_FPR_Regs = isMachoABI ? 13 : 8; const unsigned Num_VR_Regs = sizeof( VR)/sizeof( VR[0]); unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0; @@ -1410,7 +1410,7 @@ PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13 }; const unsigned NumGPRs = sizeof(GPR_32)/sizeof(GPR_32[0]); - const unsigned NumFPRs = isMachoABI ? 13 : 10; + const unsigned NumFPRs = isMachoABI ? 13 : 8; const unsigned NumVRs = sizeof( VR)/sizeof( VR[0]); const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32; Index: llvm/lib/Target/PowerPC/PPCInstr64Bit.td diff -u llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.42 llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.43 --- llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.42 Sat Mar 24 23:44:03 2007 +++ llvm/lib/Target/PowerPC/PPCInstr64Bit.td Tue Apr 3 05:27:07 2007 @@ -91,7 +91,7 @@ let isCall = 1, noResults = 1, PPC970_Unit = 7, // All calls clobber the PPC64 non-callee saved registers. Defs = [X0,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12, - F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10, + F0,F1,F2,F3,F4,F5,F6,F7,F8, V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19, LR8,CTR8, CR0,CR1,CR5,CR6,CR7] in { Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.276 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.277 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.276 Tue Feb 27 07:01:19 2007 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Tue Apr 3 05:27:07 2007 @@ -396,7 +396,7 @@ let isCall = 1, noResults = 1, PPC970_Unit = 7, // All calls clobber the non-callee saved registers... Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12, - F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10, + F0,F1,F2,F3,F4,F5,F6,F7,F8, V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19, LR,CTR, CR0,CR1,CR5,CR6,CR7] in { Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.118 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.119 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.118 Wed Mar 21 11:44:14 2007 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Apr 3 05:27:07 2007 @@ -278,7 +278,8 @@ PPC::R24, PPC::R25, PPC::R26, PPC::R27, PPC::R28, PPC::R29, PPC::R30, PPC::R31, - PPC::F11, PPC::F12, PPC::F13, + PPC::F9, + PPC::F10, PPC::F11, PPC::F12, PPC::F13, PPC::F14, PPC::F15, PPC::F16, PPC::F17, PPC::F18, PPC::F19, PPC::F20, PPC::F21, PPC::F22, PPC::F23, PPC::F24, PPC::F25, @@ -320,8 +321,9 @@ PPC::X20, PPC::X21, PPC::X22, PPC::X23, PPC::X24, PPC::X25, PPC::X26, PPC::X27, PPC::X28, PPC::X29, PPC::X30, PPC::X31, - - PPC::F11, PPC::F12, PPC::F13, + + PPC::F9, + PPC::F10, PPC::F11, PPC::F12, PPC::F13, PPC::F14, PPC::F15, PPC::F16, PPC::F17, PPC::F18, PPC::F19, PPC::F20, PPC::F21, PPC::F22, PPC::F23, PPC::F24, PPC::F25, From nicolas.geoffray at lip6.fr Tue Apr 3 05:58:06 2007 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 3 Apr 2007 05:58:06 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Message-ID: <200704031058.l33Aw6JE021262@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCRegisterInfo.cpp updated: 1.119 -> 1.120 --- Log message: Addition to the previous commit for getCalleeSavedRegClasses: "The ELF ABI specifies F1-F8 registers as argument registers for double, not F1-F10. This affects only ELF, not MachO." --- Diffs of the changes: (+4 -2) PPCRegisterInfo.cpp | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.119 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.120 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.119 Tue Apr 3 05:27:07 2007 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Apr 3 05:57:49 2007 @@ -378,7 +378,8 @@ &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, - &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, @@ -424,7 +425,8 @@ &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, - &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, From lauro.venancio at gmail.com Tue Apr 3 07:08:09 2007 From: lauro.venancio at gmail.com (Lauro Ramos Venancio) Date: Tue, 3 Apr 2007 09:08:09 -0300 Subject: [llvm-commits] eh_arm.cc In-Reply-To: <124DED6F-23CB-4938-93CF-08D897B23F26@apple.com> References: <124DED6F-23CB-4938-93CF-08D897B23F26@apple.com> Message-ID: <9c10c9f0704030508t6d037a1fscdbb3cac0aaec544@mail.gmail.com> The file eh_arm.cc wasn't committed. It is in the patch. I can't test and see if other files are missing because the patch doesn't reach the public svn yet. Lauro 2007/4/3, Devang Patel : > > On Apr 2, 2007, at 11:34 PM, Bill Wendling wrote: > > > I'm getting this error during llvm-gcc compilation: > > > > make[3]: *** No rule to make target `eh_arm.cc', needed by > > `eh_arm.lo'. Stop. > > make[3]: *** Waiting for unfinished jobs.... > > This is related to Lauro Ramos Venancio's patch Dale committed. > > - > Devang > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From nicolas.geoffray at lip6.fr Tue Apr 3 07:35:47 2007 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 3 Apr 2007 07:35:47 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCallingConv.td PPCFrameInfo.h PPCISelLowering.cpp PPCInstr64Bit.td PPCRegisterInfo.cpp PPCSubtarget.h Message-ID: <200704031235.l33CZl4S023016@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCCallingConv.td updated: 1.2 -> 1.3 PPCFrameInfo.h updated: 1.13 -> 1.14 PPCISelLowering.cpp updated: 1.266 -> 1.267 PPCInstr64Bit.td updated: 1.43 -> 1.44 PPCRegisterInfo.cpp updated: 1.120 -> 1.121 PPCSubtarget.h updated: 1.25 -> 1.26 --- Log message: The PPC64 ELF ABI is "intended to use the same structure layout and calling convention rules as the 64-bit PowerOpen ABI" (Reference http://www.linux-foundation.org/spec/ELF/ppc64/). Change all ELF tests to ELF32. --- Diffs of the changes: (+46 -92) PPCCallingConv.td | 4 +- PPCFrameInfo.h | 14 ++++---- PPCISelLowering.cpp | 26 +++++++-------- PPCInstr64Bit.td | 5 +-- PPCRegisterInfo.cpp | 85 +++++++++++----------------------------------------- PPCSubtarget.h | 4 +- 6 files changed, 46 insertions(+), 92 deletions(-) Index: llvm/lib/Target/PowerPC/PPCCallingConv.td diff -u llvm/lib/Target/PowerPC/PPCCallingConv.td:1.2 llvm/lib/Target/PowerPC/PPCCallingConv.td:1.3 --- llvm/lib/Target/PowerPC/PPCCallingConv.td:1.2 Tue Apr 3 05:27:07 2007 +++ llvm/lib/Target/PowerPC/PPCCallingConv.td Tue Apr 3 07:35:28 2007 @@ -41,10 +41,10 @@ CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>, CCIfType<[i64], CCAssignToReg<[X3, X4, X5, X6, X7, X8, X9, X10]>>, - // Darwin passes FP values in F1 - F13 + // Common sub-targets passes FP values in F1 - F13 CCIfType<[f32, f64], CCIfSubtarget<"isMachoABI()", CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8,F9,F10,F11,F12,F13]>>>, - // Other sub-targets pass FP values in F1-F8. + // ELF32 sub-target pass FP values in F1 - F8. CCIfType<[f32, f64], CCAssignToReg<[F1, F2, F3, F4, F5, F6, F7, F8]>>, // The first 12 Vector arguments are passed in altivec registers. Index: llvm/lib/Target/PowerPC/PPCFrameInfo.h diff -u llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.13 llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.14 --- llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.13 Sat Feb 24 23:34:32 2007 +++ llvm/lib/Target/PowerPC/PPCFrameInfo.h Tue Apr 3 07:35:28 2007 @@ -32,8 +32,8 @@ static unsigned getReturnSaveOffset(bool LP64, bool isMacho) { if (isMacho) return LP64 ? 16 : 8; - // For ELF ABI: - return LP64 ? 8 : 4; + // For ELF 32 ABI: + return 4; } /// getFramePointerSaveOffset - Return the previous frame offset to save the @@ -46,9 +46,9 @@ if (isMacho) return LP64 ? 40 : 20; - // For ELF ABI: + // For ELF 32 ABI: // Save it right before the link register - return LP64 ? -8 : -4; + return -4; } /// getLinkageSize - Return the size of the PowerPC ABI linkage area. @@ -57,8 +57,8 @@ if (isMacho) return 6 * (LP64 ? 8 : 4); - // For ELF ABI: - return LP64 ? 16 : 8; + // For ELF 32 ABI: + return 8; } /// getMinCallArgumentsSize - Return the size of the minium PowerPC ABI @@ -73,7 +73,7 @@ if (isMacho) return 8 * (LP64 ? 8 : 4); - // For Linux ABI: + // For ELF 32 ABI: // There is no default stack allocated for the 8 first GPR arguments. return 0; } Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.266 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.267 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.266 Tue Apr 3 05:27:07 2007 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Apr 3 07:35:28 2007 @@ -1132,7 +1132,7 @@ MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; bool isMachoABI = Subtarget.isMachoABI(); - bool isELF_ABI = Subtarget.isELF_ABI(); + bool isELF32_ABI = Subtarget.isELF32_ABI(); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); @@ -1165,7 +1165,7 @@ // 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 + // In the ELF 32 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. @@ -1187,7 +1187,7 @@ default: assert(0 && "Unhandled argument type!"); case MVT::i32: // Double word align in ELF - if (Expand && isELF_ABI && !isPPC64) GPR_idx += (GPR_idx % 2); + if (Expand && isELF32_ABI) GPR_idx += (GPR_idx % 2); if (GPR_idx != Num_GPR_Regs) { unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); MF.addLiveIn(GPR[GPR_idx], VReg); @@ -1198,7 +1198,7 @@ ArgSize = PtrByteSize; } // Stack align in ELF - if (needsLoad && Expand && isELF_ABI && !isPPC64) + if (needsLoad && Expand && isELF32_ABI) ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All int arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += PtrByteSize; @@ -1240,7 +1240,7 @@ } // Stack align in ELF - if (needsLoad && Expand && isELF_ABI && !isPPC64) + if (needsLoad && Expand && isELF32_ABI) ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All FP arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += isPPC64 ? 8 : ObjSize; @@ -1344,7 +1344,7 @@ unsigned NumOps = (Op.getNumOperands() - 5) / 2; bool isMachoABI = Subtarget.isMachoABI(); - bool isELF_ABI = Subtarget.isELF_ABI(); + bool isELF32_ABI = Subtarget.isELF32_ABI(); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; @@ -1432,8 +1432,8 @@ // register cannot be found for it. SDOperand PtrOff; - // Stack align in ELF - if (isELF_ABI && Expand && !isPPC64) + // Stack align in ELF 32 + if (isELF32_ABI && Expand) PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize, StackPtr.getValueType()); else @@ -1453,7 +1453,7 @@ case MVT::i32: case MVT::i64: // Double word align in ELF - if (isELF_ABI && Expand && !isPPC64) GPR_idx += (GPR_idx % 2); + if (isELF32_ABI && Expand) GPR_idx += (GPR_idx % 2); if (GPR_idx != NumGPRs) { RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg)); } else { @@ -1462,7 +1462,7 @@ } if (inMem || isMachoABI) { // Stack align in ELF - if (isELF_ABI && Expand && !isPPC64) + if (isELF32_ABI && Expand) ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; ArgOffset += PtrByteSize; @@ -1516,7 +1516,7 @@ } if (inMem || isMachoABI) { // Stack align in ELF - if (isELF_ABI && Expand && !isPPC64) + if (isELF32_ABI && Expand) ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; if (isPPC64) ArgOffset += 8; @@ -1548,8 +1548,8 @@ InFlag = Chain.getValue(1); } - // With the ELF ABI, set CR6 to true if this is a vararg call. - if (isVarArg && isELF_ABI) { + // With the ELF 32 ABI, set CR6 to true if this is a vararg call. + if (isVarArg && isELF32_ABI) { SDOperand SetCR(DAG.getTargetNode(PPC::SETCR, MVT::i32), 0); Chain = DAG.getCopyToReg(Chain, PPC::CR6, SetCR, InFlag); InFlag = Chain.getValue(1); Index: llvm/lib/Target/PowerPC/PPCInstr64Bit.td diff -u llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.43 llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.44 --- llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.43 Tue Apr 3 05:27:07 2007 +++ llvm/lib/Target/PowerPC/PPCInstr64Bit.td Tue Apr 3 07:35:28 2007 @@ -87,11 +87,12 @@ "bla $func", BrB, [(PPCcall_Macho (i64 imm:$func))]>; } -// ELF ABI Calls. +// ELF 64 ABI Calls = Macho ABI Calls +// Used to define BL8_ELF and BLA8_ELF let isCall = 1, noResults = 1, PPC970_Unit = 7, // All calls clobber the PPC64 non-callee saved registers. Defs = [X0,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12, - F0,F1,F2,F3,F4,F5,F6,F7,F8, + F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13, V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19, LR8,CTR8, CR0,CR1,CR5,CR6,CR7] in { Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.120 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.121 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.120 Tue Apr 3 05:57:49 2007 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Tue Apr 3 07:35:28 2007 @@ -250,7 +250,7 @@ const unsigned* PPCRegisterInfo::getCalleeSavedRegs() const { // 32-bit Darwin calling convention. - static const unsigned Darwin32_CalleeSavedRegs[] = { + static const unsigned Macho32_CalleeSavedRegs[] = { PPC::R13, PPC::R14, PPC::R15, PPC::R16, PPC::R17, PPC::R18, PPC::R19, PPC::R20, PPC::R21, PPC::R22, PPC::R23, @@ -294,7 +294,7 @@ PPC::LR, 0 }; // 64-bit Darwin calling convention. - static const unsigned Darwin64_CalleeSavedRegs[] = { + static const unsigned Macho64_CalleeSavedRegs[] = { PPC::X14, PPC::X15, PPC::X16, PPC::X17, PPC::X18, PPC::X19, PPC::X20, PPC::X21, PPC::X22, PPC::X23, @@ -315,41 +315,18 @@ PPC::LR8, 0 }; - static const unsigned ELF64_CalleeSavedRegs[] = { - PPC::X14, PPC::X15, - PPC::X16, PPC::X17, PPC::X18, PPC::X19, - PPC::X20, PPC::X21, PPC::X22, PPC::X23, - PPC::X24, PPC::X25, PPC::X26, PPC::X27, - PPC::X28, PPC::X29, PPC::X30, PPC::X31, - - PPC::F9, - PPC::F10, PPC::F11, PPC::F12, PPC::F13, - PPC::F14, PPC::F15, PPC::F16, PPC::F17, - PPC::F18, PPC::F19, PPC::F20, PPC::F21, - PPC::F22, PPC::F23, PPC::F24, PPC::F25, - PPC::F26, PPC::F27, PPC::F28, PPC::F29, - PPC::F30, PPC::F31, - - PPC::CR2, PPC::CR3, PPC::CR4, - PPC::V20, PPC::V21, PPC::V22, PPC::V23, - PPC::V24, PPC::V25, PPC::V26, PPC::V27, - PPC::V28, PPC::V29, PPC::V30, PPC::V31, - - PPC::LR8, 0 - }; - if (Subtarget.isMachoABI()) - return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegs : - Darwin32_CalleeSavedRegs; + return Subtarget.isPPC64() ? Macho64_CalleeSavedRegs : + Macho32_CalleeSavedRegs; - // ELF. - return Subtarget.isPPC64() ? ELF64_CalleeSavedRegs : ELF32_CalleeSavedRegs; + // ELF 32. + return ELF32_CalleeSavedRegs; } const TargetRegisterClass* const* PPCRegisterInfo::getCalleeSavedRegClasses() const { - // 32-bit Darwin calling convention. - static const TargetRegisterClass * const Darwin32_CalleeSavedRegClasses[] = { + // 32-bit Macho calling convention. + static const TargetRegisterClass * const Macho32_CalleeSavedRegClasses[] = { &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, @@ -395,8 +372,8 @@ &PPC::GPRCRegClass, 0 }; - // 64-bit Darwin calling convention. - static const TargetRegisterClass * const Darwin64_CalleeSavedRegClasses[] = { + // 64-bit Macho calling convention. + static const TargetRegisterClass * const Macho64_CalleeSavedRegClasses[] = { &PPC::G8RCRegClass,&PPC::G8RCRegClass, &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, @@ -418,37 +395,12 @@ &PPC::G8RCRegClass, 0 }; - static const TargetRegisterClass * const ELF64_CalleeSavedRegClasses[] = { - &PPC::G8RCRegClass,&PPC::G8RCRegClass, - &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, - &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, - &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, - &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, - - &PPC::F8RCRegClass, - &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, - &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, - &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, - &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, - &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, - &PPC::F8RCRegClass,&PPC::F8RCRegClass, - - &PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass, - - &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, - &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, - &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, - - &PPC::G8RCRegClass, 0 - }; - if (Subtarget.isMachoABI()) - return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegClasses : - Darwin32_CalleeSavedRegClasses; + return Subtarget.isPPC64() ? Macho64_CalleeSavedRegClasses : + Macho32_CalleeSavedRegClasses; - // ELF. - return Subtarget.isPPC64() ? ELF64_CalleeSavedRegClasses : - ELF32_CalleeSavedRegClasses; + // ELF 32. + return ELF32_CalleeSavedRegClasses; } // needsFP - Return true if the specified function should have a dedicated frame @@ -900,15 +852,16 @@ // Save R31 if necessary int FPSI = FI->getFramePointerSaveIndex(); bool IsPPC64 = Subtarget.isPPC64(); - bool IsELF_ABI = Subtarget.isELF_ABI(); + bool IsELF32_ABI = Subtarget.isELF32_ABI(); + bool IsMachoABI = Subtarget.isMachoABI(); const MachineFrameInfo *MFI = MF.getFrameInfo(); // If the frame pointer save index hasn't been defined yet. if (!FPSI && (NoFramePointerElim || MFI->hasVarSizedObjects()) - && IsELF_ABI) { + && IsELF32_ABI) { // Find out what the fix offset of the frame pointer save area. - int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, - !IsELF_ABI); + int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, + IsMachoABI); // Allocate the frame index for frame pointer save area. FPSI = MF.getFrameInfo()->CreateFixedObject(IsPPC64? 8 : 4, FPOffset); // Save the result. Index: llvm/lib/Target/PowerPC/PPCSubtarget.h diff -u llvm/lib/Target/PowerPC/PPCSubtarget.h:1.25 llvm/lib/Target/PowerPC/PPCSubtarget.h:1.26 --- llvm/lib/Target/PowerPC/PPCSubtarget.h:1.25 Sat Feb 24 23:04:13 2007 +++ llvm/lib/Target/PowerPC/PPCSubtarget.h Tue Apr 3 07:35:28 2007 @@ -134,8 +134,8 @@ bool isDarwin() const { return IsDarwin; } - bool isMachoABI() const { return IsDarwin; } - bool isELF_ABI() const { return !IsDarwin; } + bool isMachoABI() const { return IsDarwin || IsPPC64; } + bool isELF32_ABI() const { return !IsDarwin && !IsPPC64; } unsigned getAsmFlavor() const { return AsmFlavor != Unset ? unsigned(AsmFlavor) : 0; From lauro.venancio at gmail.com Tue Apr 3 08:49:09 2007 From: lauro.venancio at gmail.com (Lauro Ramos Venancio) Date: Tue, 3 Apr 2007 10:49:09 -0300 Subject: [llvm-commits] eh_arm.cc In-Reply-To: <9c10c9f0704030508t6d037a1fscdbb3cac0aaec544@mail.gmail.com> References: <124DED6F-23CB-4938-93CF-08D897B23F26@apple.com> <9c10c9f0704030508t6d037a1fscdbb3cac0aaec544@mail.gmail.com> Message-ID: <9c10c9f0704030649p607c5084r8d0b2dcb4b142133@mail.gmail.com> Files missed: ? libstdc++-v3/libsupc++/eh_arm.cc ? libstdc++-v3/libsupc++/eh_call.cc ? gcc/config/arm/libunwind.S ? gcc/config/arm/pr-support.c ? gcc/config/arm/unwind-arm.c ? gcc/config/arm/unaligned-funcs.c ? gcc/config/arm/unwind-arm.h Lauro 2007/4/3, Lauro Ramos Venancio : > The file eh_arm.cc wasn't committed. It is in the patch. I can't test > and see if other files are missing because the patch doesn't reach the > public svn yet. > > Lauro > > 2007/4/3, Devang Patel : > > > > On Apr 2, 2007, at 11:34 PM, Bill Wendling wrote: > > > > > I'm getting this error during llvm-gcc compilation: > > > > > > make[3]: *** No rule to make target `eh_arm.cc', needed by > > > `eh_arm.lo'. Stop. > > > make[3]: *** Waiting for unfinished jobs.... > > > > This is related to Lauro Ramos Venancio's patch Dale committed. > > > > - > > Devang > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > From nicolas.geoffray at lip6.fr Tue Apr 3 09:00:09 2007 From: nicolas.geoffray at lip6.fr (Nicolas Geoffray) Date: Tue, 3 Apr 2007 09:00:09 -0500 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h Message-ID: <200704031400.l33E09Ek024682@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.267 -> 1.268 PPCISelLowering.h updated: 1.64 -> 1.65 --- Log message: Starting implementation of the ELF32 ABI specification of varargs handling. LowerVASTART emits the right code if the subtarget is ELF32, the other intrinsics (VAARG, VACOPY and VAEND) are not yet implemented. --- Diffs of the changes: (+177 -9) PPCISelLowering.cpp | 180 +++++++++++++++++++++++++++++++++++++++++++++++++--- PPCISelLowering.h | 6 + 2 files changed, 177 insertions(+), 9 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.267 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.268 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.267 Tue Apr 3 07:35:28 2007 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Apr 3 08:59:52 2007 @@ -169,8 +169,13 @@ // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); + // VAARG is custom lowered with ELF 32 ABI + if (TM.getSubtarget().isELF32_ABI()) + setOperationAction(ISD::VAARG, MVT::Other, Custom); + else + setOperationAction(ISD::VAARG, MVT::Other, Expand); + // Use the default implementation. - setOperationAction(ISD::VAARG , MVT::Other, Expand); setOperationAction(ISD::VACOPY , MVT::Other, Expand); setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); @@ -1086,15 +1091,96 @@ return SDOperand(); } +static SDOperand LowerVAARG(SDOperand Op, SelectionDAG &DAG, + int VarArgsFrameIndex, + int VarArgsStackOffset, + unsigned VarArgsNumGPR, + unsigned VarArgsNumFPR, + const PPCSubtarget &Subtarget) { + + assert(0 && "VAARG in ELF32 ABI not implemented yet!"); +} + static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG, - unsigned VarArgsFrameIndex) { - // vastart just stores the address of the VarArgsFrameIndex slot into the - // memory location argument. + int VarArgsFrameIndex, + int VarArgsStackOffset, + unsigned VarArgsNumGPR, + unsigned VarArgsNumFPR, + const PPCSubtarget &Subtarget) { + + if (Subtarget.isMachoABI()) { + // vastart just stores the address of the VarArgsFrameIndex slot into the + // memory location argument. + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); + SrcValueSDNode *SV = cast(Op.getOperand(2)); + return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV->getValue(), + SV->getOffset()); + } + + // For ELF 32 ABI we follow the layout of the va_list struct. + // We suppose the given va_list is already allocated. + // + // typedef struct { + // char gpr; /* index into the array of 8 GPRs + // * stored in the register save area + // * gpr=0 corresponds to r3, + // * gpr=1 to r4, etc. + // */ + // char fpr; /* index into the array of 8 FPRs + // * stored in the register save area + // * fpr=0 corresponds to f1, + // * fpr=1 to f2, etc. + // */ + // char *overflow_arg_area; + // /* location on stack that holds + // * the next overflow argument + // */ + // char *reg_save_area; + // /* where r3:r10 and f1:f8 (if saved) + // * are stored + // */ + // } va_list[1]; + + + SDOperand ArgGPR = DAG.getConstant(VarArgsNumGPR, MVT::i8); + SDOperand ArgFPR = DAG.getConstant(VarArgsNumFPR, MVT::i8); + + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + + SDOperand StackOffset = DAG.getFrameIndex(VarArgsStackOffset, PtrVT); SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); + + SDOperand ConstFrameOffset = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, + PtrVT); + SDOperand ConstStackOffset = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8 - 1, + PtrVT); + SDOperand ConstFPROffset = DAG.getConstant(1, PtrVT); + SrcValueSDNode *SV = cast(Op.getOperand(2)); - return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV->getValue(), + + // Store first byte : number of int regs + SDOperand firstStore = DAG.getStore(Op.getOperand(0), ArgGPR, + Op.getOperand(1), SV->getValue(), + SV->getOffset()); + SDOperand nextPtr = DAG.getNode(ISD::ADD, PtrVT, Op.getOperand(1), + ConstFPROffset); + + // Store second byte : number of float regs + SDOperand secondStore = DAG.getStore(firstStore, ArgFPR, nextPtr, + SV->getValue(), SV->getOffset()); + nextPtr = DAG.getNode(ISD::ADD, PtrVT, nextPtr, ConstStackOffset); + + // Store second word : arguments given on stack + SDOperand thirdStore = DAG.getStore(secondStore, StackOffset, nextPtr, + SV->getValue(), SV->getOffset()); + nextPtr = DAG.getNode(ISD::ADD, PtrVT, nextPtr, ConstFrameOffset); + + // Store third word : arguments given in registers + return DAG.getStore(thirdStore, FR, nextPtr, SV->getValue(), SV->getOffset()); + } #include "PPCGenCallingConv.inc" @@ -1120,6 +1206,9 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex, + int &VarArgsStackOffset, + unsigned &VarArgsNumGPR, + unsigned &VarArgsNumFPR, const PPCSubtarget &Subtarget) { // TODO: add description of PPC stack frame format, or at least some docs. // @@ -1287,13 +1376,47 @@ // the start of the first vararg value... for expansion of llvm.va_start. bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; if (isVarArg) { + + int depth; + if (isELF32_ABI) { + VarArgsNumGPR = GPR_idx; + VarArgsNumFPR = FPR_idx; + + // Make room for Num_GPR_Regs, Num_FPR_Regs and for a possible frame + // pointer. + depth = -(Num_GPR_Regs * MVT::getSizeInBits(PtrVT)/8 + + Num_FPR_Regs * MVT::getSizeInBits(MVT::f64)/8 + + MVT::getSizeInBits(PtrVT)/8); + + VarArgsStackOffset = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8, + ArgOffset); + + } + else + depth = ArgOffset; + VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8, - ArgOffset); + depth); SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); + + SmallVector MemOps; + + // In ELF 32 ABI, the fixed integer arguments of a variadic function are + // stored to the VarArgsFrameIndex on the stack. + if (isELF32_ABI) { + for (GPR_idx = 0; GPR_idx != VarArgsNumGPR; ++GPR_idx) { + SDOperand Val = DAG.getRegister(GPR[GPR_idx], PtrVT); + SDOperand Store = DAG.getStore(Root, Val, FIN, NULL, 0); + MemOps.push_back(Store); + // Increment the address by four for the next argument to store + SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT); + FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff); + } + } + // If this function is vararg, store any remaining integer argument regs // to their spots on the stack so that they may be loaded by deferencing the // result of va_next. - SmallVector MemOps; for (; GPR_idx != Num_GPR_Regs; ++GPR_idx) { unsigned VReg; if (isPPC64) @@ -1309,6 +1432,35 @@ SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT); FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff); } + + // In ELF 32 ABI, the double arguments are stored to the VarArgsFrameIndex + // on the stack. + if (isELF32_ABI) { + for (FPR_idx = 0; FPR_idx != VarArgsNumFPR; ++FPR_idx) { + SDOperand Val = DAG.getRegister(FPR[FPR_idx], MVT::f64); + SDOperand Store = DAG.getStore(Root, Val, FIN, NULL, 0); + MemOps.push_back(Store); + // Increment the address by eight for the next argument to store + SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(MVT::f64)/8, + PtrVT); + FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff); + } + + for (; FPR_idx != Num_FPR_Regs; ++FPR_idx) { + unsigned VReg; + VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass); + + MF.addLiveIn(FPR[FPR_idx], VReg); + SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::f64); + SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0); + MemOps.push_back(Store); + // Increment the address by eight for the next argument to store + SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(MVT::f64)/8, + PtrVT); + FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff); + } + } + if (!MemOps.empty()) Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size()); } @@ -2709,9 +2861,19 @@ case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); - case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); + case ISD::VASTART: + return LowerVASTART(Op, DAG, VarArgsFrameIndex, VarArgsStackOffset, + VarArgsNumGPR, VarArgsNumFPR, PPCSubTarget); + + case ISD::VAARG: + return LowerVAARG(Op, DAG, VarArgsFrameIndex, VarArgsStackOffset, + VarArgsNumGPR, VarArgsNumFPR, PPCSubTarget); + case ISD::FORMAL_ARGUMENTS: - return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex, PPCSubTarget); + return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex, + VarArgsStackOffset, VarArgsNumGPR, + VarArgsNumFPR, PPCSubTarget); + case ISD::CALL: return LowerCALL(Op, DAG, PPCSubTarget); case ISD::RET: return LowerRET(Op, DAG, getTargetMachine()); case ISD::STACKRESTORE: return LowerSTACKRESTORE(Op, DAG, PPCSubTarget); Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.64 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.65 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.64 Fri Mar 30 18:15:24 2007 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Tue Apr 3 08:59:52 2007 @@ -173,6 +173,12 @@ class PPCTargetLowering : public TargetLowering { int VarArgsFrameIndex; // FrameIndex for start of varargs area. + int VarArgsStackOffset; // StackOffset for start of stack + // arguments. + unsigned VarArgsNumGPR; // Index of the first unused integer + // register for parameter passing. + unsigned VarArgsNumFPR; // Index of the first unused double + // register for parameter passing. int ReturnAddrIndex; // FrameIndex for return slot. const PPCSubtarget &PPCSubTarget; public: From lauro.venancio at gmail.com Tue Apr 3 09:48:04 2007 From: lauro.venancio at gmail.com (Lauro Ramos Venancio) Date: Tue, 3 Apr 2007 11:48:04 -0300 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCallingConv.td PPCFrameInfo.h PPCISelLowering.cpp PPCInstr64Bit.td PPCRegisterInfo.cpp PPCSubtarget.h In-Reply-To: <200704031235.l33CZl4S023016@zion.cs.uiuc.edu> References: <200704031235.l33CZl4S023016@zion.cs.uiuc.edu> Message-ID: <9c10c9f0704030748h19ed9cc5k87c1666d39f2c8f9@mail.gmail.com> > @@ -46,9 +46,9 @@ > if (isMacho) > return LP64 ? 40 : 20; > > - // For ELF ABI: > + // For ELF 32 ABI: > // Save it right before the link register > - return LP64 ? -8 : -4; > + return -4; > } This function is unsigned and it is returning a negative value. Lauro From reid at x10sys.com Tue Apr 3 12:05:36 2007 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Apr 2007 12:05:36 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704031705.l33H5aQF028545@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.34 -> 1.35 --- Log message: Add links into the agenda and fix the table tags there. Mention Oscar's brief talk. --- Diffs of the changes: (+12 -10) DevMtgMay2007.html | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.34 llvm-www/DevMtgMay2007.html:1.35 --- llvm-www/DevMtgMay2007.html:1.34 Tue Apr 3 02:56:27 2007 +++ llvm-www/DevMtgMay2007.html Tue Apr 3 12:05:19 2007 @@ -63,15 +63,15 @@ - - - - - - - - - + + + + + + + + +
        StartStopDescription
        08:0008:45Meet - Greet
        08:4509:00Session 0: LLVM History
        09:0010:30Session 1: Introductions
        10:3011:00Break - Informal Discussions
        11:0012:00Session 2: Learning LLVM
        12:0013:00Lunch Break
        13:0015:00Session 3: Using LLVM
        15:0015:30Break - Informal Discussions
        15:3017:00Session 4: Improving LLVM
        17:0018:00Wrap up - Social Time
        08:4509:00Session 0: LLVM History
        09:0010:30Session 1: Introductions
        10:3011:00Break - Informal Discussions
        11:0012:00Session 2: Learning LLVM
        12:0013:00Lunch Break
        13:0015:00Session 3: Using LLVM
        15:0015:30Break - Informal Discussions
        15:3017:00Session 4: Improving LLVM
        17:0018:00Wrap up - Social Time
        18:0021:00Dinner (Optional)
        @@ -82,6 +82,8 @@ of LLVM) will present a brief and casual history of how LLVM got from an idea in the back of Chris' brain in 2000 to an up-and-coming Open Source project in 2007.

        +

        Also featured in this session will be a brief talk by Oscar describing his + plans for world domination.

        @@ -261,6 +263,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"> Valid HTML 4.01! -
        Last modified: $Date: 2007/04/03 07:56:27 $ +
        Last modified: $Date: 2007/04/03 17:05:19 $ From reid at x10sys.com Tue Apr 3 12:09:03 2007 From: reid at x10sys.com (Reid Spencer) Date: Tue, 3 Apr 2007 12:09:03 -0500 Subject: [llvm-commits] CVS: llvm-www/DevMtgMay2007.html Message-ID: <200704031709.l33H93am028769@zion.cs.uiuc.edu> Changes in directory llvm-www: DevMtgMay2007.html updated: 1.35 -> 1.36 --- Log message: HTML 4.01 compliance. --- Diffs of the changes: (+2 -2) DevMtgMay2007.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/DevMtgMay2007.html diff -u llvm-www/DevMtgMay2007.html:1.35 llvm-www/DevMtgMay2007.html:1.36 --- llvm-www/DevMtgMay2007.html:1.35 Tue Apr 3 12:05:19 2007 +++ llvm-www/DevMtgMay2007.html Tue Apr 3 12:08:45 2007 @@ -158,7 +158,7 @@

        In addition to the planned sessions above, the following discussion topics have been submitted.

        - + @@ -263,6 +263,6 @@ src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!">Valid HTML 4.01! -
        Last modified: $Date: 2007/04/03 17:05:19 $ +
        Last modified: $Date: 2007/04/03 17:08:45 $ From johannes at apple.com Tue Apr 3 12:22:19 2007 From: johannes at apple.com (johannes at apple.com) Date: Tue, 3 Apr 2007 10:22:19 -0700 (PDT) Subject: [llvm-commits] [125690] missed part of ARM EABI patch Message-ID: <20070403172219.4DE2CCD33E60@src> Revision: 125690 Author: johannes Date: 2007-04-03 10:22:18 -0700 (Tue, 03 Apr 2007) Log Message: ----------- missed part of ARM EABI patch Added Paths: ----------- apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_arm.cc apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_call.cc Added: apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_arm.cc =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_arm.cc (rev 0) +++ apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_arm.cc 2007-04-03 17:22:18 UTC (rev 125690) @@ -0,0 +1,153 @@ +// -*- C++ -*- ARM specific Exception handling support routines. +// Copyright (C) 2004, 2005 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include "unwind-cxx.h" + +#ifdef __ARM_EABI_UNWINDER__ + +using namespace __cxxabiv1; + + +// Given the thrown type THROW_TYPE, pointer to a variable containing a +// pointer to the exception object THROWN_PTR_P and a type CATCH_TYPE to +// compare against, return whether or not there is a match and if so, +// update *THROWN_PTR_P. + +extern "C" __cxa_type_match_result +__cxa_type_match(_Unwind_Exception* ue_header, + const std::type_info* catch_type, + bool is_reference __attribute__((__unused__)), + void** thrown_ptr_p) +{ + if (!__is_gxx_exception_class(ue_header->exception_class)) + return ctm_failed; + + __cxa_exception* xh = __get_exception_header_from_ue(ue_header); + const std::type_info* throw_type = xh->exceptionType; + void* thrown_ptr = *thrown_ptr_p; + + // Pointer types need to adjust the actual pointer, not + // the pointer to pointer that is the exception object. + // This also has the effect of passing pointer types + // "by value" through the __cxa_begin_catch return value. + if (throw_type->__is_pointer_p()) + thrown_ptr = *(void**) thrown_ptr; + + if (catch_type->__do_catch(throw_type, &thrown_ptr, 1)) + { + *thrown_ptr_p = thrown_ptr; + + if (typeid(*catch_type) == typeid (typeid(void*))) + { + const __pointer_type_info *catch_pointer_type = + static_cast (catch_type); + const __pointer_type_info *throw_pointer_type = + static_cast (throw_type); + + if (typeid (*catch_pointer_type->__pointee) != typeid (void) + && (*catch_pointer_type->__pointee != + *throw_pointer_type->__pointee)) + return ctm_succeeded_with_ptr_to_base; + } + + return ctm_succeeded; + } + + return ctm_failed; +} + +// ABI defined routine called at the start of a cleanup handler. +extern "C" bool +__cxa_begin_cleanup(_Unwind_Exception* ue_header) +{ + __cxa_eh_globals *globals = __cxa_get_globals(); + __cxa_exception *header = __get_exception_header_from_ue(ue_header); + + if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) + { + // TODO: cleanups with foreign exceptions. + return false; + } + header->propagationCount++; + // Add it to the chain if this is the first time we've seen this exception. + if (header->propagationCount == 1) + { + header->nextPropagatingException = globals->propagatingExceptions; + globals->propagatingExceptions = header; + } + return true; +} + +// Do the work for __cxa_end_cleanup. Returns the currently propagating +// exception object. +extern "C" _Unwind_Exception * +__gnu_end_cleanup(void) +{ + __cxa_exception *header; + __cxa_eh_globals *globals = __cxa_get_globals(); + + header = globals->propagatingExceptions; + + // Check something hasn't gone horribly wrong. + if (!header) + std::terminate(); + + header->propagationCount--; + if (header->propagationCount == 0) + { + // Remove exception from chain. + globals->propagatingExceptions = header->nextPropagatingException; + header->nextPropagatingException = NULL; + } + return &header->unwindHeader; +} + +// Assembly wrapper to call __gnu_end_cleanup without clobbering r1-r3. +// Also push r4 to preserve stack alignment. +#ifdef __thumb__ +asm (".global __cxa_end_cleanup\n" +" .type __cxa_end_cleanup, \"function\"\n" +" .thumb_func\n" +"__cxa_end_cleanup:\n" +" push\t{r1, r2, r3, r4}\n" +" bl\t__gnu_end_cleanup\n" +" pop\t{r1, r2, r3, r4}\n" +" bl\t_Unwind_Resume @ Never returns\n"); +#else +asm (".global __cxa_end_cleanup\n" +" .type __cxa_end_cleanup, \"function\"\n" +"__cxa_end_cleanup:\n" +" stmfd\tsp!, {r1, r2, r3, r4}\n" +" bl\t__gnu_end_cleanup\n" +" ldmfd\tsp!, {r1, r2, r3, r4}\n" +" bl\t_Unwind_Resume @ Never returns\n"); +#endif + +#endif Added: apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_call.cc =================================================================== --- apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_call.cc (rev 0) +++ apple-local/branches/llvm/libstdc++-v3/libsupc++/eh_call.cc 2007-04-03 17:22:18 UTC (rev 125690) @@ -0,0 +1,162 @@ +// -*- C++ -*- Helpers for calling unextected and terminate +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// GCC is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// GCC is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + +#include +#include +#include +#include "unwind-cxx.h" + +using namespace __cxxabiv1; + +#include "unwind-pe.h" + + +// Helper routine for when the exception handling code needs to call +// terminate. + +extern "C" void +__cxa_call_terminate(_Unwind_Exception* ue_header) +{ + + if (ue_header) + { + // terminate is classed as a catch handler. + __cxa_begin_catch(ue_header); + + // Call the terminate handler that was in effect when we threw this + // exception. */ + if (__is_gxx_exception_class(ue_header->exception_class)) + { + __cxa_exception* xh; + + xh = __get_exception_header_from_ue(ue_header); + __terminate(xh->terminateHandler); + } + } + /* Call the global routine if we don't have anything better. */ + std::terminate(); +} + + +#ifdef __ARM_EABI_UNWINDER__ +// The ARM EABI __cxa_call_unexpected has the same semantics as the generic +// routine, but the exception specification has a different format. +extern "C" void +__cxa_call_unexpected(void* exc_obj_in) +{ + _Unwind_Exception* exc_obj + = reinterpret_cast<_Unwind_Exception*>(exc_obj_in); + + int rtti_count = 0; + _Unwind_Word rtti_stride = 0; + _Unwind_Word* rtti_list = NULL; + bool foreign_exception; + std::unexpected_handler unexpectedHandler = NULL; + std::terminate_handler terminateHandler = NULL; + __cxa_exception* xh; + if (__is_gxx_exception_class(exc_obj->exception_class)) + { + // Save data from the EO, which may be clobbered by _cxa_begin_catch. + xh = __get_exception_header_from_ue(exc_obj); + unexpectedHandler = xh->unexpectedHandler; + terminateHandler = xh->terminateHandler; + rtti_count = exc_obj->barrier_cache.bitpattern[1]; + + rtti_stride = exc_obj->barrier_cache.bitpattern[3]; + rtti_list = (_Unwind_Word*) exc_obj->barrier_cache.bitpattern[4]; + foreign_exception = false; + } + else + foreign_exception = true; + + /* This must be called after extracting data from the EO, but before + calling unexpected(). */ + __cxa_begin_catch(exc_obj); + + // This function is a handler for our exception argument. If we exit + // by throwing a different exception, we'll need the original cleaned up. + struct end_catch_protect + { + end_catch_protect() { } + ~end_catch_protect() { __cxa_end_catch(); } + } end_catch_protect_obj; + + + try + { + if (foreign_exception) + std::unexpected(); + else + __unexpected(unexpectedHandler); + } + catch(...) + { + /* See if the new exception matches the rtti list. */ + if (foreign_exception) + std::terminate(); + + // Get the exception thrown from unexpected. + + __cxa_eh_globals* globals = __cxa_get_globals_fast(); + __cxa_exception* new_xh = globals->caughtExceptions; + void* new_ptr = new_xh + 1; + const std::type_info* catch_type; + int n; + bool bad_exception_allowed = false; + const std::type_info& bad_exc = typeid(std::bad_exception); + + // Check the new exception against the rtti list + for (n = 0; n < rtti_count; n++) + { + _Unwind_Word offset; + + offset = (_Unwind_Word) &rtti_list[n * (rtti_stride >> 2)]; + offset = _Unwind_decode_target2(offset); + catch_type = (const std::type_info*) (offset); + + if (__cxa_type_match(&new_xh->unwindHeader, catch_type, false, + &new_ptr) != ctm_failed) + __throw_exception_again; + + if (catch_type->__do_catch(&bad_exc, 0, 1)) + bad_exception_allowed = true; + } + + // If the exception spec allows std::bad_exception, throw that. +#ifdef __EXCEPTIONS + if (bad_exception_allowed) + throw std::bad_exception(); +#endif + + // Otherwise, die. + __terminate(terminateHandler); + } +} +#endif // __ARM_EABI_UNWINDER__ From johannes at apple.com Tue Apr 3 12:23:51 2007 From: johannes at apple.com (johannes at apple.com) Date: Tue, 3 Apr 2007 10:23:51 -0700 (PDT) Subject: [llvm-commits] [125691] missing files from ARM EABI patch Message-ID: <20070403172351.DA83BCD33F3A@src> Revision: 125691 Author: johannes Date: 2007-04-03 10:23:51 -0700 (Tue, 03 Apr 2007) Log Message: ----------- missing files from ARM EABI patch Added Paths: ----------- apple-local/branches/llvm/gcc/config/arm/libunwind.S apple-local/branches/llvm/gcc/config/arm/pr-support.c apple-local/branches/llvm/gcc/config/arm/unaligned-funcs.c apple-local/branches/llvm/gcc/config/arm/unwind-arm.c apple-local/branches/llvm/gcc/config/arm/unwind-arm.h Added: apple-local/branches/llvm/gcc/config/arm/libunwind.S =================================================================== --- apple-local/branches/llvm/gcc/config/arm/libunwind.S (rev 0) +++ apple-local/branches/llvm/gcc/config/arm/libunwind.S 2007-04-03 17:23:51 UTC (rev 125691) @@ -0,0 +1,116 @@ +/* Support functions for the unwinder. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Contributed by Paul Brook + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combine + executable.) + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef L_unwind + +.macro UNPREFIX name + .global SYM (\name) + EQUIV SYM (\name), SYM (__\name) +.endm + +/* r0 points to a 16-word block. Upload these values to the actual core + state. */ +ARM_FUNC_START restore_core_regs + /* We must use sp as the base register when restoring sp. Push the + last 3 registers onto the top of the current stack to achieve + this. */ + add r1, r0, #52 + ldmia r1, {r3, r4, r5} /* {sp, lr, pc}. */ +#ifdef __INTERWORKING__ + /* Restore pc into ip. */ + mov r2, r5 + stmfd sp!, {r2, r3, r4} +#else + stmfd sp!, {r3, r4, r5} +#endif + /* Don't bother restoring ip. */ + ldmia r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp} + /* Pop the three registers we pushed earlier. */ +#ifdef __INTERWORKING__ + ldmfd sp, {ip, sp, lr} + bx ip +#else + ldmfd sp, {sp, lr, pc} +#endif + FUNC_END restore_core_regs + UNPREFIX restore_core_regs + +/* Load VFP registers d0-d15 from the address in r0. */ +ARM_FUNC_START gnu_Unwind_Restore_VFP + /* Use the generic coprocessor form so that gas doesn't complain + on soft-float targets. */ + ldc p11,cr0,[r0],{0x21} /* fldmiax r0, {d0-d15} */ + RET + +/* Store VFR regsters d0-d15 to the address in r0. */ +ARM_FUNC_START gnu_Unwind_Save_VFP + /* Use the generic coprocessor form so that gas doesn't complain + on soft-float targets. */ + stc p11,cr0,[r0],{0x21} /* fstmiax r0, {d0-d15} */ + RET + +/* Wrappers to save core registers, then call the real routine. */ + +.macro UNWIND_WRAPPER name + ARM_FUNC_START \name + /* Create a phase2_vrs structure. */ + /* Split reg push in two to ensure the correct value for sp. */ + stmfd sp!, {sp, lr, pc} + stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip} + + /* Demand-save flags, plus an extra word for alignment. */ + mov r3, #0 + stmfd sp!, {r2, r3} + + /* Point r1 at the block. Pass r0 unchanged. */ + add r1, sp, #4 +#if defined(__thumb__) + /* Switch back to thumb mode to avoid interworking hassle. */ + adr ip, .L1_\name + orr ip, ip, #1 + bx ip + .thumb +.L1_\name: + bl SYM (__gnu\name) __PLT__ + ldr r3, [sp, #64] + add sp, #72 + bx r3 +#else + bl SYM (__gnu\name) __PLT__ + ldr lr, [sp, #64] + add sp, sp, #72 + RET +#endif + FUNC_END \name + UNPREFIX \name +.endm + +UNWIND_WRAPPER _Unwind_RaiseException +UNWIND_WRAPPER _Unwind_Resume + +#endif /* L_unwind */ Added: apple-local/branches/llvm/gcc/config/arm/pr-support.c =================================================================== --- apple-local/branches/llvm/gcc/config/arm/pr-support.c (rev 0) +++ apple-local/branches/llvm/gcc/config/arm/pr-support.c 2007-04-03 17:23:51 UTC (rev 125691) @@ -0,0 +1,377 @@ +/* ARM EABI compliant unwinding routines + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Contributed by Paul Brook + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combine + executable.) + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ +#include "unwind.h" + +typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ + +/* Misc constants. */ +#define R_IP 12 +#define R_SP 13 +#define R_LR 14 +#define R_PC 15 + +#define uint32_highbit (((_uw) 1) << 31) + +void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); + +/* Unwind descriptors. */ + +typedef struct +{ + _uw16 length; + _uw16 offset; +} EHT16; + +typedef struct +{ + _uw length; + _uw offset; +} EHT32; + +/* Calculate the address encoded by a 31-bit self-relative offset at address + P. Copy of routine in unwind-arm.c. */ + +static inline _uw +selfrel_offset31 (const _uw *p) +{ + _uw offset; + + offset = *p; + /* Sign extend to 32 bits. */ + if (offset & (1 << 30)) + offset |= 1u << 31; + + return offset + (_uw) p; +} + + +/* Personality routine helper functions. */ + +#define CODE_FINISH (0xb0) + +/* Return the next byte of unwinding information, or CODE_FINISH if there is + no data remaining. */ +static inline _uw8 +next_unwind_byte (__gnu_unwind_state * uws) +{ + _uw8 b; + + if (uws->bytes_left == 0) + { + /* Load another word */ + if (uws->words_left == 0) + return CODE_FINISH; /* Nothing left. */ + uws->words_left--; + uws->data = *(uws->next++); + uws->bytes_left = 3; + } + else + uws->bytes_left--; + + /* Extract the most significant byte. */ + b = (uws->data >> 24) & 0xff; + uws->data <<= 8; + return b; +} + +/* Execute the unwinding instructions described by UWS. */ +_Unwind_Reason_Code +__gnu_unwind_execute (_Unwind_Context * context, __gnu_unwind_state * uws) +{ + _uw op; + int set_pc; + _uw reg; + + set_pc = 0; + for (;;) + { + op = next_unwind_byte (uws); + if (op == CODE_FINISH) + { + /* If we haven't already set pc then copy it from lr. */ + if (!set_pc) + { + _Unwind_VRS_Get (context, _UVRSC_CORE, R_LR, _UVRSD_UINT32, + ®); + _Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, + ®); + set_pc = 1; + } + /* Drop out of the loop. */ + break; + } + if ((op & 0x80) == 0) + { + /* vsp = vsp +- (imm6 << 2 + 4). */ + _uw offset; + + offset = ((op & 0x3f) << 2) + 4; + _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); + if (op & 0x40) + reg -= offset; + else + reg += offset; + _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); + continue; + } + + if ((op & 0xf0) == 0x80) + { + op = (op << 8) | next_unwind_byte (uws); + if (op == 0x8000) + { + /* Refuse to unwind. */ + return _URC_FAILURE; + } + /* Pop r4-r15 under mask. */ + op = (op << 4) & 0xfff0; + if (_Unwind_VRS_Pop (context, _UVRSC_CORE, op, _UVRSD_UINT32) + != _UVRSR_OK) + return _URC_FAILURE; + if (op & (1 << R_PC)) + set_pc = 1; + continue; + } + if ((op & 0xf0) == 0x90) + { + op &= 0xf; + if (op == 13 || op == 15) + /* Reserved. */ + return _URC_FAILURE; + /* vsp = r[nnnn]. */ + _Unwind_VRS_Get (context, _UVRSC_CORE, op, _UVRSD_UINT32, ®); + _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); + continue; + } + if ((op & 0xf0) == 0xa0) + { + /* Pop r4-r[4+nnn], [lr]. */ + _uw mask; + + mask = (0xff0 >> (7 - (op & 7))) & 0xff0; + if (op & 8) + mask |= (1 << R_LR); + if (_Unwind_VRS_Pop (context, _UVRSC_CORE, mask, _UVRSD_UINT32) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + if ((op & 0xf0) == 0xb0) + { + /* op == 0xb0 already handled. */ + if (op == 0xb1) + { + op = next_unwind_byte (uws); + if (op == 0 || ((op & 0xf0) != 0)) + /* Spare. */ + return _URC_FAILURE; + /* Pop r0-r4 under mask. */ + if (_Unwind_VRS_Pop (context, _UVRSC_CORE, op, _UVRSD_UINT32) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + if (op == 0xb2) + { + /* vsp = vsp + 0x204 + (uleb128 << 2). */ + int shift; + + _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, + ®); + op = next_unwind_byte (uws); + shift = 2; + while (op & 0x80) + { + reg += ((op & 0x7f) << shift); + shift += 7; + op = next_unwind_byte (uws); + } + reg += ((op & 0x7f) << shift) + 0x204; + _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, + ®); + continue; + } + if (op == 0xb3) + { + /* Pop VFP registers with fldmx. */ + op = next_unwind_byte (uws); + op = ((op & 0xf0) << 12) | (op & 0xf); + if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_VFPX) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + if ((op & 0xfc) == 0xb4) + { + /* Pop FPA E[4]-E[4+nn]. */ + op = 0x40000 | ((op & 3) + 1); + if (_Unwind_VRS_Pop (context, _UVRSC_FPA, op, _UVRSD_FPAX) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + /* op & 0xf8 == 0xb8. */ + /* Pop VFP D[8]-D[8+nnn] with fldmx. */ + op = 0x80000 | ((op & 7) + 1); + if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_VFPX) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + if ((op & 0xf0) == 0xc0) + { + if (op == 0xc6) + { + /* Pop iWMMXt D registers. */ + op = next_unwind_byte (uws); + op = ((op & 0xf0) << 12) | (op & 0xf); + if (_Unwind_VRS_Pop (context, _UVRSC_WMMXD, op, _UVRSD_UINT64) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + if (op == 0xc7) + { + op = next_unwind_byte (uws); + if (op == 0 || (op & 0xf0) != 0) + /* Spare. */ + return _URC_FAILURE; + /* Pop iWMMXt wCGR{3,2,1,0} under mask. */ + if (_Unwind_VRS_Pop (context, _UVRSC_WMMXC, op, _UVRSD_UINT32) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + if ((op & 0xf8) == 0xc0) + { + /* Pop iWMMXt wR[10]-wR[10+nnn]. */ + op = 0xa0000 | ((op & 0xf) + 1); + if (_Unwind_VRS_Pop (context, _UVRSC_WMMXD, op, _UVRSD_UINT64) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + if (op == 0xc8) + { + /* Pop FPA registers. */ + op = next_unwind_byte (uws); + op = ((op & 0xf0) << 12) | (op & 0xf); + if (_Unwind_VRS_Pop (context, _UVRSC_FPA, op, _UVRSD_FPAX) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + if (op == 0xc9) + { + /* Pop VFP registers with fldmd. */ + op = next_unwind_byte (uws); + op = ((op & 0xf0) << 12) | (op & 0xf); + if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_DOUBLE) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + /* Spare. */ + return _URC_FAILURE; + } + if ((op & 0xf8) == 0xd0) + { + /* Pop VFP D[8]-D[8+nnn] with fldmd. */ + op = 0x80000 | ((op & 7) + 1); + if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_DOUBLE) + != _UVRSR_OK) + return _URC_FAILURE; + continue; + } + /* Spare. */ + return _URC_FAILURE; + } + return _URC_OK; +} + + +/* Execute the unwinding instructions associated with a frame. UCBP and + CONTEXT are the current exception object and virtual CPU state + respectively. */ + +_Unwind_Reason_Code +__gnu_unwind_frame (_Unwind_Control_Block * ucbp, _Unwind_Context * context) +{ + _uw *ptr; + __gnu_unwind_state uws; + + ptr = (_uw *) ucbp->pr_cache.ehtp; + /* Skip over the personality routine address. */ + ptr++; + /* Setup the unwinder state. */ + uws.data = (*ptr) << 8; + uws.next = ptr + 1; + uws.bytes_left = 3; + uws.words_left = ((*ptr) >> 24) & 0xff; + + return __gnu_unwind_execute (context, &uws); +} + +/* Get the _Unwind_Control_Block from an _Unwind_Context. */ + +static inline _Unwind_Control_Block * +unwind_UCB_from_context (_Unwind_Context * context) +{ + return (_Unwind_Control_Block *) _Unwind_GetGR (context, R_IP); +} + +/* Get the start address of the function being unwound. */ + +_Unwind_Ptr +_Unwind_GetRegionStart (_Unwind_Context * context) +{ + _Unwind_Control_Block *ucbp; + + ucbp = unwind_UCB_from_context (context); + return (_Unwind_Ptr) ucbp->pr_cache.fnstart; +} + +/* Find the Language specific exception data. */ + +void * +_Unwind_GetLanguageSpecificData (_Unwind_Context * context) +{ + _Unwind_Control_Block *ucbp; + _uw *ptr; + + /* Get a pointer to the exception table entry. */ + ucbp = unwind_UCB_from_context (context); + ptr = (_uw *) ucbp->pr_cache.ehtp; + /* Skip the personality routine address. */ + ptr++; + /* Skip the unwind opcodes. */ + ptr += (((*ptr) >> 24) & 0xff) + 1; + + return ptr; +} + Added: apple-local/branches/llvm/gcc/config/arm/unaligned-funcs.c =================================================================== --- apple-local/branches/llvm/gcc/config/arm/unaligned-funcs.c (rev 0) +++ apple-local/branches/llvm/gcc/config/arm/unaligned-funcs.c 2007-04-03 17:23:51 UTC (rev 125691) @@ -0,0 +1,62 @@ +/* EABI unaligned read/write functions. + + Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by CodeSourcery, LLC. + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combine + executable.) + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +int __aeabi_uread4 (void *); +int __aeabi_uwrite4 (int, void *); +long long __aeabi_uread8 (void *); +long long __aeabi_uwrite8 (long long, void *); + +struct __attribute__((packed)) u4 { int data; }; +struct __attribute__((packed)) u8 { long long data; }; + +int +__aeabi_uread4 (void *ptr) +{ + return ((struct u4 *) ptr)->data; +} + +int +__aeabi_uwrite4 (int data, void *ptr) +{ + ((struct u4 *) ptr)->data = data; + return data; +} + +long long +__aeabi_uread8 (void *ptr) +{ + return ((struct u8 *) ptr)->data; +} + +long long +__aeabi_uwrite8 (long long data, void *ptr) +{ + ((struct u8 *) ptr)->data = data; + return data; +} Added: apple-local/branches/llvm/gcc/config/arm/unwind-arm.c =================================================================== --- apple-local/branches/llvm/gcc/config/arm/unwind-arm.c (rev 0) +++ apple-local/branches/llvm/gcc/config/arm/unwind-arm.c 2007-04-03 17:23:51 UTC (rev 125691) @@ -0,0 +1,855 @@ +/* ARM EABI compliant unwinding routines. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Contributed by Paul Brook + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combine + executable.) + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ +#include "unwind.h" + +/* Definitions for C++ runtime support routines. We make these weak + declarations to avoid pulling in libsupc++ unneccesarily. */ +typedef unsigned char bool; + +typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ + +void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); +bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp); +bool __attribute__((weak)) __cxa_type_match(_Unwind_Control_Block *ucbp, + const type_info *rttip, + void **matched_object); + +_Unwind_Ptr __attribute__((weak)) +__gnu_Unwind_Find_exidx (_Unwind_Ptr, int *); + +/* Misc constants. */ +#define R_IP 12 +#define R_SP 13 +#define R_LR 14 +#define R_PC 15 + +#define EXIDX_CANTUNWIND 1 +#define uint32_highbit (((_uw) 1) << 31) + +#define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2) +#define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3) + +struct core_regs +{ + _uw r[16]; +}; + +/* We use normal integer types here to avoid the compiler generating + coprocessor instructions. */ +struct vfp_regs +{ + _uw64 d[16]; + _uw pad; +}; + +struct fpa_reg +{ + _uw w[3]; +}; + +struct fpa_regs +{ + struct fpa_reg f[8]; +}; + +/* Unwind descriptors. */ + +typedef struct +{ + _uw16 length; + _uw16 offset; +} EHT16; + +typedef struct +{ + _uw length; + _uw offset; +} EHT32; + +/* The ABI specifies that the unwind routines may only use core registers, + except when actually manipulating coprocessor state. This allows + us to write one implementation that works on all platforms by + demand-saving coprocessor registers. + + During unwinding we hold the coprocessor state in the actual hardware + registers and allocate demand-save areas for use during phase1 + unwinding. */ + +typedef struct +{ + /* The first fields must be the same as a phase2_vrs. */ + _uw demand_save_flags; + struct core_regs core; + struct vfp_regs vfp; + struct fpa_regs fpa; +} phase1_vrs; + +#define DEMAND_SAVE_VFP 1 + +/* This must match the structure created by the assembly wrappers. */ +typedef struct +{ + _uw demand_save_flags; + struct core_regs core; +} phase2_vrs; + + +/* An exeption index table entry. */ + +typedef struct __EIT_entry +{ + _uw fnoffset; + _uw content; +} __EIT_entry; + +/* Assembly helper functions. */ + +/* Restore core register state. Never returns. */ +void __attribute__((noreturn)) restore_core_regs (struct core_regs *); + + +/* Coprocessor register state manipulation functions. */ + +void __gnu_Unwind_Save_VFP (struct vfp_regs * p); +void __gnu_Unwind_Restore_VFP (struct vfp_regs * p); + +/* Restore coprocessor state after phase1 unwinding. */ +static void +restore_non_core_regs (phase1_vrs * vrs) +{ + if ((vrs->demand_save_flags & DEMAND_SAVE_VFP) == 0) + __gnu_Unwind_Restore_VFP (&vrs->vfp); +} + +/* A better way to do this would probably be to compare the absolute address + with a segment relative relocation of the same symbol. */ + +extern int __text_start; +extern int __data_start; + +/* The exception index table location. */ +extern __EIT_entry __exidx_start; +extern __EIT_entry __exidx_end; + +/* ABI defined personality routines. */ +extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr0 (_Unwind_State, + _Unwind_Control_Block *, _Unwind_Context *);// __attribute__((weak)); +extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr1 (_Unwind_State, + _Unwind_Control_Block *, _Unwind_Context *) __attribute__((weak)); +extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr2 (_Unwind_State, + _Unwind_Control_Block *, _Unwind_Context *) __attribute__((weak)); + +/* ABI defined routine to store a virtual register to memory. */ + +_Unwind_VRS_Result _Unwind_VRS_Get (_Unwind_Context *context, + _Unwind_VRS_RegClass regclass, + _uw regno, + _Unwind_VRS_DataRepresentation representation, + void *valuep) +{ + phase1_vrs *vrs = (phase1_vrs *) context; + + switch (regclass) + { + case _UVRSC_CORE: + if (representation != _UVRSD_UINT32 + || regno > 15) + return _UVRSR_FAILED; + *(_uw *) valuep = vrs->core.r[regno]; + return _UVRSR_OK; + + case _UVRSC_VFP: + case _UVRSC_FPA: + case _UVRSC_WMMXD: + case _UVRSC_WMMXC: + return _UVRSR_NOT_IMPLEMENTED; + + default: + return _UVRSR_FAILED; + } +} + + +/* ABI defined function to load a virtual register from memory. */ + +_Unwind_VRS_Result _Unwind_VRS_Set (_Unwind_Context *context, + _Unwind_VRS_RegClass regclass, + _uw regno, + _Unwind_VRS_DataRepresentation representation, + void *valuep) +{ + phase1_vrs *vrs = (phase1_vrs *) context; + + switch (regclass) + { + case _UVRSC_CORE: + if (representation != _UVRSD_UINT32 + || regno > 15) + return _UVRSR_FAILED; + + vrs->core.r[regno] = *(_uw *) valuep; + return _UVRSR_OK; + + case _UVRSC_VFP: + case _UVRSC_FPA: + case _UVRSC_WMMXD: + case _UVRSC_WMMXC: + return _UVRSR_NOT_IMPLEMENTED; + + default: + return _UVRSR_FAILED; + } +} + + +/* ABI defined function to pop registers off the stack. */ + +_Unwind_VRS_Result _Unwind_VRS_Pop (_Unwind_Context *context, + _Unwind_VRS_RegClass regclass, + _uw discriminator, + _Unwind_VRS_DataRepresentation representation) +{ + phase1_vrs *vrs = (phase1_vrs *) context; + + switch (regclass) + { + case _UVRSC_CORE: + { + _uw *ptr; + _uw mask; + int i; + + if (representation != _UVRSD_UINT32) + return _UVRSR_FAILED; + + mask = discriminator & 0xffff; + ptr = (_uw *) vrs->core.r[R_SP]; + /* Pop the requested registers. */ + for (i = 0; i < 16; i++) + { + if (mask & (1 << i)) + vrs->core.r[i] = *(ptr++); + } + /* Writeback the stack pointer value if it wasn't restored. */ + if ((mask & (1 << R_SP)) == 0) + vrs->core.r[R_SP] = (_uw) ptr; + } + return _UVRSR_OK; + + case _UVRSC_VFP: + { + _uw start = discriminator >> 16; + _uw count = discriminator & 0xffff; + struct vfp_regs tmp; + _uw *sp; + _uw *dest; + + if ((representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE) + || start + count > 16) + return _UVRSR_FAILED; + + if (vrs->demand_save_flags & DEMAND_SAVE_VFP) + { + /* Demand-save resisters for stage1. */ + vrs->demand_save_flags &= ~DEMAND_SAVE_VFP; + __gnu_Unwind_Save_VFP (&vrs->vfp); + } + + /* Restore the registers from the stack. Do this by saving the + current VFP registers to a memory area, moving the in-memory + values into that area, and restoring from the whole area. + For _UVRSD_VFPX we assume FSTMX standard format 1. */ + __gnu_Unwind_Save_VFP (&tmp); + + /* The stack address is only guaranteed to be word aligned, so + we can't use doubleword copies. */ + sp = (_uw *) vrs->core.r[R_SP]; + dest = (_uw *) &tmp.d[start]; + count *= 2; + while (count--) + *(dest++) = *(sp++); + + /* Skip the pad word */ + if (representation == _UVRSD_VFPX) + sp++; + + /* Set the new stack pointer. */ + vrs->core.r[R_SP] = (_uw) sp; + + /* Reload the registers. */ + __gnu_Unwind_Restore_VFP (&tmp); + } + return _UVRSR_OK; + + case _UVRSC_FPA: + case _UVRSC_WMMXD: + case _UVRSC_WMMXC: + return _UVRSR_NOT_IMPLEMENTED; + + default: + return _UVRSR_FAILED; + } +} + + +/* Core unwinding functions. */ + +/* Calculate the address encoded by a 31-bit self-relative offset at address + P. */ +static inline _uw +selfrel_offset31 (const _uw *p) +{ + _uw offset; + + offset = *p; + /* Sign extend to 32 bits. */ + if (offset & (1 << 30)) + offset |= 1u << 31; + + return offset + (_uw) p; +} + + +/* Perform a binary search for RETURN_ADDRESS in TABLE. The table contains + NREC entries. */ + +static const __EIT_entry * +search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address) +{ + _uw next_fn; + _uw this_fn; + int n, left, right; + + if (nrec == 0) + return (__EIT_entry *) 0; + + left = 0; + right = nrec - 1; + + while (1) + { + n = (left + right) / 2; + this_fn = selfrel_offset31 (&table[n].fnoffset); + if (n != nrec - 1) + next_fn = selfrel_offset31 (&table[n + 1].fnoffset); + else + next_fn = ~(_uw) 0; + + if (return_address < this_fn) + { + if (n == left) + return (__EIT_entry *) 0; + right = n - 1; + } + else if (return_address < next_fn) + return &table[n]; + else + left = n + 1; + } +} + +/* Find the exception index table eintry for the given address. + Fill in the relevant fields of the UCB. + Returns _URC_FAILURE if an error occured, _URC_OK on success*/ + +static _Unwind_Reason_Code +get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) +{ + const __EIT_entry * eitp; + int nrec; + + /* The return address is the address of the instruction following the + call instruction (plus one in thumb mode). If this was the last + instruction in the function the address will lie in the following + function. Subtract 2 from the address so that it points within the call + instruction itself. */ + return_address -= 2; + + if (__gnu_Unwind_Find_exidx) + { + eitp = (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_address, + &nrec); + if (!eitp) + { + UCB_PR_ADDR (ucbp) = 0; + return _URC_FAILURE; + } + } + else + { + eitp = &__exidx_start; + nrec = &__exidx_end - &__exidx_start; + } + + eitp = search_EIT_table (eitp, nrec, return_address); + + if (!eitp) + { + UCB_PR_ADDR (ucbp) = 0; + return _URC_FAILURE; + } + ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset); + + /* Can this frame be unwound at all? */ + if (eitp->content == EXIDX_CANTUNWIND) + { + UCB_PR_ADDR (ucbp) = 0; + return _URC_FAILURE; + } + + /* Obtain the address of the "real" __EHT_Header word. */ + + if (eitp->content & uint32_highbit) + { + /* It is immediate data. */ + ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content; + ucbp->pr_cache.additional = 1; + } + else + { + /* The low 31 bits of the content field are a self-relative + offset to an _Unwind_EHT_Entry structure. */ + ucbp->pr_cache.ehtp = + (_Unwind_EHT_Header *) selfrel_offset31 (&eitp->content); + ucbp->pr_cache.additional = 0; + } + + /* Discover the personality routine address. */ + if (*ucbp->pr_cache.ehtp & (1u << 31)) + { + /* One of the predefined standard routines. */ + _uw idx = (*(_uw *) ucbp->pr_cache.ehtp >> 24) & 0xf; + if (idx == 0) + UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr0; + else if (idx == 1) + UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr1; + else if (idx == 2) + UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr2; + else + { /* Failed */ + UCB_PR_ADDR (ucbp) = 0; + return _URC_FAILURE; + } + } + else + { + /* Execute region offset to PR */ + UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp); + } + return _URC_OK; +} + + +/* Perform phase2 unwinding. VRS is the initial virtual register state. */ + +static void __attribute__((noreturn)) +unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs) +{ + _Unwind_Reason_Code pr_result; + + for(;;) + { + /* Find the entry for this routine. */ + if (get_eit_entry (ucbp, vrs->core.r[R_PC]) != _URC_OK) + abort (); + + UCB_SAVED_CALLSITE_ADDR (ucbp) = vrs->core.r[R_PC]; + + /* Call the pr to decide what to do. */ + pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) + (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs); + + if (pr_result != _URC_CONTINUE_UNWIND) + break; + } + + if (pr_result != _URC_INSTALL_CONTEXT) + abort(); + + restore_core_regs (&vrs->core); +} + +/* Perform phase1 unwinding. UCBP is the exception being thrown, and + entry_VRS is the register state on entry to _Unwind_RaiseException. */ + +_Unwind_Reason_Code +__gnu_Unwind_RaiseException (_Unwind_Control_Block *, phase2_vrs *); + +_Unwind_Reason_Code +__gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp, + phase2_vrs * entry_vrs) +{ + phase1_vrs saved_vrs; + _Unwind_Reason_Code pr_result; + + /* Set the pc to the call site. */ + entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR]; + + /* Save the core registers. */ + saved_vrs.core = entry_vrs->core; + /* Set demand-save flags. */ + saved_vrs.demand_save_flags = ~(_uw) 0; + + /* Unwind until we reach a propagation barrier. */ + for (;;) + { + /* Find the entry for this routine. */ + if (get_eit_entry (ucbp, saved_vrs.core.r[R_PC]) != _URC_OK) + return _URC_FAILURE; + + /* Call the pr to decide what to do. */ + pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) + (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs); + + if (pr_result != _URC_CONTINUE_UNWIND) + break; + } + + /* We've unwound as far as we want to go, so restore the original + register state. */ + restore_non_core_regs (&saved_vrs); + if (pr_result != _URC_HANDLER_FOUND) + { + /* Some sort of failure has occurred in the pr and probably the + pr returned _URC_FAILURE. */ + return _URC_FAILURE; + } + + unwind_phase2 (ucbp, entry_vrs); +} + +/* Resume unwinding after a cleanup has been run. UCBP is the exception + being thrown and ENTRY_VRS is the register state on entry to + _Unwind_Resume. */ +_Unwind_Reason_Code +__gnu_Unwind_Resume (_Unwind_Control_Block *, phase2_vrs *); + +_Unwind_Reason_Code +__gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs) +{ + _Unwind_Reason_Code pr_result; + + /* Recover the saved address. */ + entry_vrs->core.r[R_PC] = UCB_SAVED_CALLSITE_ADDR (ucbp); + + /* Call the cached PR. */ + pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) + (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs); + + switch (pr_result) + { + case _URC_INSTALL_CONTEXT: + /* Upload the registers to enter the landing pad. */ + restore_core_regs (&entry_vrs->core); + + case _URC_CONTINUE_UNWIND: + /* Continue unwinding the next frame. */ + unwind_phase2 (ucbp, entry_vrs); + + default: + abort (); + } +} + +/* Clean up an exception object when unwinding is complete. */ +void +_Unwind_Complete (_Unwind_Control_Block * ucbp __attribute__((unused))) +{ +} + + +/* Get the _Unwind_Control_Block from an _Unwind_Context. */ + +static inline _Unwind_Control_Block * +unwind_UCB_from_context (_Unwind_Context * context) +{ + return (_Unwind_Control_Block *) _Unwind_GetGR (context, R_IP); +} + + +/* Free an exception. */ + +void +_Unwind_DeleteException (_Unwind_Exception * exc) +{ + if (exc->exception_cleanup) + (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc); +} + + +/* Common implementation for ARM ABI defined personality routines. + ID is the index of the personality routine, other arguments are as defined + by __aeabi_unwind_cpp_pr{0,1,2}. */ + +static _Unwind_Reason_Code +__gnu_unwind_pr_common (_Unwind_State state, + _Unwind_Control_Block *ucbp, + _Unwind_Context *context, + int id) +{ + __gnu_unwind_state uws; + _uw *data; + _uw offset; + _uw len; + _uw rtti_count; + int phase2_call_unexpected_after_unwind = 0; + int in_range = 0; + + data = (_uw *) ucbp->pr_cache.ehtp; + uws.data = *(data++); + uws.next = data; + if (id == 0) + { + uws.data <<= 8; + uws.words_left = 0; + uws.bytes_left = 3; + } + else + { + uws.words_left = (uws.data >> 16) & 0xff; + uws.data <<= 16; + uws.bytes_left = 2; + data += uws.words_left; + } + + /* Restore the saved pointer. */ + if (state == _US_UNWIND_FRAME_RESUME) + data = (_uw *) ucbp->cleanup_cache.bitpattern[0]; + + if ((ucbp->pr_cache.additional & 1) == 0) + { + /* Process descriptors. */ + while (*data) + { + _uw addr; + _uw fnstart; + + if (id == 2) + { + len = ((EHT32 *) data)->length; + offset = ((EHT32 *) data)->offset; + data += 2; + } + else + { + len = ((EHT16 *) data)->length; + offset = ((EHT16 *) data)->offset; + data++; + } + + fnstart = ucbp->pr_cache.fnstart + (offset & ~1); + addr = _Unwind_GetGR (context, R_PC); + in_range = (fnstart <= addr && addr < fnstart + (len & ~1)); + + switch (((offset & 1) << 1) | (len & 1)) + { + case 0: + /* Cleanup. */ + if (state != _US_VIRTUAL_UNWIND_FRAME + && in_range) + { + /* Cleanup in range, and we are running cleanups. */ + _uw lp; + + /* Landing pad address is 31-bit pc-relatvie offset. */ + lp = selfrel_offset31 (data); + data++; + /* Save the exception data pointer. */ + ucbp->cleanup_cache.bitpattern[0] = (_uw) data; + if (!__cxa_begin_cleanup (ucbp)) + return _URC_FAILURE; + /* Setup the VRS to enter the landing pad. */ + _Unwind_SetGR (context, R_PC, lp); + return _URC_INSTALL_CONTEXT; + } + /* Cleanup not in range, or we are in stage 1. */ + data++; + break; + + case 1: + /* Catch handler. */ + if (state == _US_VIRTUAL_UNWIND_FRAME) + { + if (in_range) + { + /* Check for a barrier. */ + _uw rtti; + void *matched; + + /* Check for no-throw areas. */ + if (data[1] == (_uw) -2) + return _URC_FAILURE; + + /* The thrown object immediately folows the ECB. */ + matched = (void *)(ucbp + 1); + if (data[1] != (_uw) -1) + { + /* Match a catch specification. */ + rtti = _Unwind_decode_target2 ((_uw) &data[1]); + if (!__cxa_type_match (ucbp, (type_info *) rtti, + &matched)) + matched = (void *)0; + } + + if (matched) + { + ucbp->barrier_cache.sp = + _Unwind_GetGR (context, R_SP); + ucbp->barrier_cache.bitpattern[0] = (_uw) matched; + ucbp->barrier_cache.bitpattern[1] = (_uw) data; + return _URC_HANDLER_FOUND; + } + } + /* Handler out of range, or not matched. */ + } + else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP) + && ucbp->barrier_cache.bitpattern[1] == (_uw) data) + { + /* Matched a previous propagation barrier. */ + _uw lp; + + /* Setup for entry to the handler. */ + lp = selfrel_offset31 (data); + _Unwind_SetGR (context, R_PC, lp); + _Unwind_SetGR (context, 0, (_uw) ucbp); + return _URC_INSTALL_CONTEXT; + } + /* Catch handler not mached. Advance to the next descriptor. */ + data += 2; + break; + + case 2: + rtti_count = data[0] & 0x7fffffff; + /* Exception specification. */ + if (state == _US_VIRTUAL_UNWIND_FRAME) + { + if (in_range) + { + /* Match against teh exception specification. */ + _uw i; + _uw rtti; + void *matched; + + for (i = 0; i < rtti_count; i++) + { + matched = (void *)(ucbp + 1); + rtti = _Unwind_decode_target2 ((_uw) &data[i + 1]); + if (__cxa_type_match (ucbp, (type_info *) rtti, + &matched)) + break; + } + + if (i == rtti_count) + { + /* Exception does not match the spec. */ + ucbp->barrier_cache.sp = + _Unwind_GetGR (context, R_SP); + ucbp->barrier_cache.bitpattern[0] = (_uw) matched; + ucbp->barrier_cache.bitpattern[1] = (_uw) data; + return _URC_HANDLER_FOUND; + } + } + /* Handler out of range, or exception is permitted. */ + } + else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP) + && ucbp->barrier_cache.bitpattern[1] == (_uw) data) + { + /* Matched a previous propagation barrier. */ + _uw lp; + /* Record the RTTI list for __cxa_call_unexpected. */ + ucbp->barrier_cache.bitpattern[1] = rtti_count; + ucbp->barrier_cache.bitpattern[2] = 0; + ucbp->barrier_cache.bitpattern[3] = 4; + ucbp->barrier_cache.bitpattern[4] = (_uw) &data[1]; + + if (data[0] & uint32_highbit) + phase2_call_unexpected_after_unwind = 1; + else + { + data += rtti_count + 1; + /* Setup for entry to the handler. */ + lp = selfrel_offset31 (data); + data++; + _Unwind_SetGR (context, R_PC, lp); + _Unwind_SetGR (context, 0, (_uw) ucbp); + return _URC_INSTALL_CONTEXT; + } + } + if (data[0] & uint32_highbit) + data++; + data += rtti_count + 1; + break; + + default: + /* Should never happen. */ + return _URC_FAILURE; + } + /* Finished processing this descriptor. */ + } + } + + if (__gnu_unwind_execute (context, &uws) != _URC_OK) + return _URC_FAILURE; + + if (phase2_call_unexpected_after_unwind) + { + /* Enter __cxa_unexpected as if called from the callsite. */ + _Unwind_SetGR (context, R_LR, _Unwind_GetGR (context, R_PC)); + _Unwind_SetGR (context, R_PC, (_uw) &__cxa_call_unexpected); + return _URC_INSTALL_CONTEXT; + } + + return _URC_CONTINUE_UNWIND; +} + + +/* ABI defined personality routine entry points. */ + +_Unwind_Reason_Code +__aeabi_unwind_cpp_pr0 (_Unwind_State state, + _Unwind_Control_Block *ucbp, + _Unwind_Context *context) +{ + return __gnu_unwind_pr_common (state, ucbp, context, 0); +} + +_Unwind_Reason_Code +__aeabi_unwind_cpp_pr1 (_Unwind_State state, + _Unwind_Control_Block *ucbp, + _Unwind_Context *context) +{ + return __gnu_unwind_pr_common (state, ucbp, context, 1); +} + +_Unwind_Reason_Code +__aeabi_unwind_cpp_pr2 (_Unwind_State state, + _Unwind_Control_Block *ucbp, + _Unwind_Context *context) +{ + return __gnu_unwind_pr_common (state, ucbp, context, 2); +} Added: apple-local/branches/llvm/gcc/config/arm/unwind-arm.h =================================================================== --- apple-local/branches/llvm/gcc/config/arm/unwind-arm.h (rev 0) +++ apple-local/branches/llvm/gcc/config/arm/unwind-arm.h 2007-04-03 17:23:51 UTC (rev 125691) @@ -0,0 +1,271 @@ +/* Header file for the ARM EABI unwinder + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Contributed by Paul Brook + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file into combinations with other programs, + and to distribute those combinations without any restriction coming + from the use of this file. (The General Public License restrictions + do apply in other respects; for example, they cover modification of + the file, and distribution when not linked into a combine + executable.) + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Language-independent unwinder header public defines. This contins both + ABI defined objects, and GNU support routines.*/ + +#ifndef UNWIND_ARM_H +#define UNWIND_ARM_H + +#define __ARM_EABI_UNWINDER__ 1 + +#ifdef __cplusplus +extern "C" { +#endif + /* We add a prototype for abort here to avoid creating a dependency on + target headers. */ + extern void abort(); + + typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); + typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); + typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); + typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); + typedef _Unwind_Word _uw; + typedef unsigned _uw64 __attribute__((mode(__DI__))); + typedef unsigned _uw16 __attribute__((mode(__HI__))); + typedef unsigned _uw8 __attribute__((mode(__QI__))); + + typedef enum + { + _URC_OK = 0, /* operation completed successfully */ + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8, + _URC_FAILURE = 9 /* unspecified failure of some kind */ + } + _Unwind_Reason_Code; + + typedef enum + { + _US_VIRTUAL_UNWIND_FRAME = 0, + _US_UNWIND_FRAME_STARTING = 1, + _US_UNWIND_FRAME_RESUME = 2 + } + _Unwind_State; + + typedef struct _Unwind_Control_Block _Unwind_Control_Block; + typedef struct _Unwind_Context _Unwind_Context; + typedef _uw _Unwind_EHT_Header; + + + /* UCB: */ + + struct _Unwind_Control_Block + { + char exception_class[8]; + void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *); + /* Unwinder cache, private fields for the unwinder's use */ + struct + { + _uw reserved1; /* init reserved1 to 0, then don't touch */ + _uw reserved2; + _uw reserved3; + _uw reserved4; + _uw reserved5; + } + unwinder_cache; + /* Propagation barrier cache (valid after phase 1): */ + struct + { + _uw sp; + _uw bitpattern[5]; + } + barrier_cache; + /* Cleanup cache (preserved over cleanup): */ + struct + { + _uw bitpattern[4]; + } + cleanup_cache; + /* Pr cache (for pr's benefit): */ + struct + { + _uw fnstart; /* function start address */ + _Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */ + _uw additional; /* additional data */ + _uw reserved1; + } + pr_cache; + long long int :0; /* Force alignment to 8-byte boundary */ + }; + + /* Interface functions: */ + _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp); + void __attribute__((noreturn)) _Unwind_Resume(_Unwind_Control_Block *ucbp); + void _Unwind_Complete(_Unwind_Control_Block *ucbp); + + /* Virtual Register Set*/ + + typedef enum + { + _UVRSC_CORE = 0, /* integer register */ + _UVRSC_VFP = 1, /* vfp */ + _UVRSC_FPA = 2, /* fpa */ + _UVRSC_WMMXD = 3, /* Intel WMMX data register */ + _UVRSC_WMMXC = 4 /* Intel WMMX control register */ + } + _Unwind_VRS_RegClass; + + typedef enum + { + _UVRSD_UINT32 = 0, + _UVRSD_VFPX = 1, + _UVRSD_FPAX = 2, + _UVRSD_UINT64 = 3, + _UVRSD_FLOAT = 4, + _UVRSD_DOUBLE = 5 + } + _Unwind_VRS_DataRepresentation; + + typedef enum + { + _UVRSR_OK = 0, + _UVRSR_NOT_IMPLEMENTED = 1, + _UVRSR_FAILED = 2 + } + _Unwind_VRS_Result; + + /* Frame unwinding state. */ + typedef struct + { + /* The current word (bytes packed msb first). */ + _uw data; + /* Pointer to the next word of data. */ + _uw *next; + /* The number of bytes left in this word. */ + _uw8 bytes_left; + /* The number of words pointed to by ptr. */ + _uw8 words_left; + } + __gnu_unwind_state; + + typedef _Unwind_Reason_Code (*personality_routine) (_Unwind_State, + _Unwind_Control_Block *, _Unwind_Context *); + + _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *, _Unwind_VRS_RegClass, + _uw, _Unwind_VRS_DataRepresentation, + void *); + + _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *, _Unwind_VRS_RegClass, + _uw, _Unwind_VRS_DataRepresentation, + void *); + + _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *, _Unwind_VRS_RegClass, + _uw, _Unwind_VRS_DataRepresentation); + + + /* Support functions for the PR. */ +#define _Unwind_Exception _Unwind_Control_Block + typedef char _Unwind_Exception_Class[8]; + + void * _Unwind_GetLanguageSpecificData (_Unwind_Context *); + _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *); + + /* These two should never be used */ + static inline _Unwind_Ptr + _Unwind_GetDataRelBase (_Unwind_Context * context __attribute__ ((unused))) + { + abort (); + } + + static inline _Unwind_Ptr + _Unwind_GetTextRelBase (_Unwind_Context * context __attribute__ ((unused))) + { + abort (); + } + + void _Unwind_DeleteException (_Unwind_Exception *); + + _Unwind_Reason_Code __gnu_unwind_frame (_Unwind_Control_Block *, + _Unwind_Context *); + _Unwind_Reason_Code __gnu_unwind_execute (_Unwind_Context *, + __gnu_unwind_state *); + + /* Decode an R_ARM_TARGET2 relocation. */ + static inline _Unwind_Word + _Unwind_decode_target2 (_Unwind_Word ptr) + { + _Unwind_Word tmp; + + tmp = *(_Unwind_Word *) ptr; + /* Zero values are always NULL. */ + if (!tmp) + return 0; + +#if defined(linux) || defined(__NetBSD__) + /* Pc-relative indirect. */ + tmp += ptr; + tmp = *(_Unwind_Word *) tmp; +#elif defined(__symbian__) + /* Absoute pointer. Nothing more to do. */ +#else + /* Pc-relative pointer. */ + tmp += ptr; +#endif + return tmp; + } + + static inline _Unwind_Word + _Unwind_GetGR (_Unwind_Context *context, int regno) + { + _uw val; + _Unwind_VRS_Get (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); + return val; + } + + /* Return the address of the instruction, not the actual IP value. */ +#define _Unwind_GetIP(context) \ + (_Unwind_GetGR (context, 15) &
        Suggested ByIssue or Discussion Topic
        Suggested ByIssue or Discussion Topic
        Owen AndersonFuture development practices: with a burgeoning number of clients and wider adoption, do we want more organized development practices? i.e. release focuses or something?