From ashukla at cs.uiuc.edu Mon Feb 17 13:46:01 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Feb 17 13:46:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Trigger/GetTraceTime.cpp Message-ID: <200302171945.NAA25341@tank.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Trigger: GetTraceTime.cpp updated: 1.1 -> 1.2 --- Log message: Fixed compilation with linux --- Diffs of the changes: Index: llvm/lib/Reoptimizer/Trigger/GetTraceTime.cpp diff -u llvm/lib/Reoptimizer/Trigger/GetTraceTime.cpp:1.1 llvm/lib/Reoptimizer/Trigger/GetTraceTime.cpp:1.2 --- llvm/lib/Reoptimizer/Trigger/GetTraceTime.cpp:1.1 Fri Feb 14 14:48:18 2003 +++ llvm/lib/Reoptimizer/Trigger/GetTraceTime.cpp Mon Feb 17 13:45:22 2003 @@ -7,8 +7,11 @@ // //===----------------------------------------------------------------------===// +#ifdef __sparc__ #include "llvm/Reoptimizer/GetTraceTime.h" +#include + #ifdef GET_TRACE_TIME extern "C" void llvm_time_start(){ @@ -29,5 +32,7 @@ void llvm_trigger_time_end(){ cpc_count_usr_events(0); } + +#endif #endif From ashukla at cs.uiuc.edu Mon Feb 17 13:46:03 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Feb 17 13:46:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp Message-ID: <200302171945.NAA25356@tank.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Trigger: TriggerAuxillary.cpp updated: 1.1 -> 1.2 --- Log message: Fixed compilation with linux --- Diffs of the changes: Index: llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp diff -u llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp:1.1 llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp:1.2 --- llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp:1.1 Fri Feb 14 14:47:28 2003 +++ llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp Mon Feb 17 13:45:34 2003 @@ -132,6 +132,7 @@ //get a path vector from a BB* +/* unsigned int getPathVector(vector &vBB){ int i = 0, path = 0; for(vector::iterator BI = vBB.begin(), BE = vBB.end(); BI != BE; @@ -152,3 +153,4 @@ } } +*/ From ashukla at cs.uiuc.edu Mon Feb 17 13:47:02 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Feb 17 13:47:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Reoptimizer/GetTraceTime.h Message-ID: <200302171946.NAA25376@tank.cs.uiuc.edu> Changes in directory llvm/include/llvm/Reoptimizer: GetTraceTime.h updated: 1.2 -> 1.3 --- Log message: Fixed compilation with linux --- Diffs of the changes: Index: llvm/include/llvm/Reoptimizer/GetTraceTime.h diff -u llvm/include/llvm/Reoptimizer/GetTraceTime.h:1.2 llvm/include/llvm/Reoptimizer/GetTraceTime.h:1.3 --- llvm/include/llvm/Reoptimizer/GetTraceTime.h:1.2 Fri Feb 14 14:42:59 2003 +++ llvm/include/llvm/Reoptimizer/GetTraceTime.h Mon Feb 17 13:46:01 2003 @@ -9,7 +9,8 @@ #ifndef LLVM_REOPTIMIZER_TRACECACHE_GETTRACETIME_H #define LLVM_REOPTIMIZER_TRACECACHE_GETTRACETIME_H -#include + +#ifdef __sparc //#define GET_TRACE_TIME //#define MAP_TIME @@ -28,5 +29,6 @@ void llvm_trigger_time_end(); #endif +#endif #endif From ashukla at cs.uiuc.edu Mon Feb 17 13:51:01 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Feb 17 13:51:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/TraceCache2.cpp Message-ID: <200302171950.NAA14012@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: TraceCache2.cpp added (r1.1) --- Log message: Alternate tracecache and memory manager --- Diffs of the changes: From ashukla at cs.uiuc.edu Mon Feb 17 13:53:01 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Feb 17 13:53:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/MemoryManager2.cpp Message-ID: <200302171952.NAA14026@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: MemoryManager2.cpp added (r1.1) --- Log message: Alternate tracecache and memory manager --- Diffs of the changes: From ashukla at cs.uiuc.edu Mon Feb 17 13:53:02 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Feb 17 13:53:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/MemoryManager2.h Message-ID: <200302171952.NAA14038@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: MemoryManager2.h added (r1.1) --- Log message: Alternate tracecache and memory manager --- Diffs of the changes: From ashukla at cs.uiuc.edu Mon Feb 17 13:54:00 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Feb 17 13:54:00 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Reoptimizer/TraceCache2.h Message-ID: <200302171953.NAA14053@trinity.cs.uiuc.edu> Changes in directory llvm/include/llvm/Reoptimizer: TraceCache2.h added (r1.1) --- Log message: Alternate tracecache and memory manager --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Feb 18 12:06:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 12:06:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/or.ll Message-ID: <200302181805.MAA01142@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: or.ll updated: 1.6 -> 1.7 --- Log message: Modernize testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/or.ll diff -u llvm/test/Regression/Transforms/InstCombine/or.ll:1.6 llvm/test/Regression/Transforms/InstCombine/or.ll:1.7 --- llvm/test/Regression/Transforms/InstCombine/or.ll:1.6 Tue Oct 8 11:09:47 2002 +++ llvm/test/Regression/Transforms/InstCombine/or.ll Tue Feb 18 12:05:19 2003 @@ -8,52 +8,52 @@ implementation -int "test1"(int %A) { +int %test1(int %A) { %B = or int %A, 0 ret int %B } -int "test2"(int %A) { +int %test2(int %A) { %B = or int %A, -1 ret int %B } -bool "test3"(bool %A) { +bool %test3(bool %A) { %B = or bool %A, false ret bool %B } -bool "test4"(bool %A) { +bool %test4(bool %A) { %B = or bool %A, true ret bool %B } -bool "test5"(bool %A) { +bool %test5(bool %A) { %B = xor bool %A, false ret bool %B } -int "test6"(int %A) { +int %test6(int %A) { %B = xor int %A, 0 ret int %B } -bool "test7"(bool %A) { +bool %test7(bool %A) { %B = xor bool %A, %A ret bool %B } -int "test8"(int %A) { +int %test8(int %A) { %B = xor int %A, %A ret int %B } -bool "test9"(bool %A) { +bool %test9(bool %A) { %B = or bool %A, %A ret bool %B } -int "test10"(int %A) { +int %test10(int %A) { %B = or int %A, %A ret int %B } From lattner at cs.uiuc.edu Tue Feb 18 12:07:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 12:07:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/and.ll Message-ID: <200302181806.MAA01197@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: and.ll updated: 1.3 -> 1.4 --- Log message: Modernize testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/and.ll diff -u llvm/test/Regression/Transforms/InstCombine/and.ll:1.3 llvm/test/Regression/Transforms/InstCombine/and.ll:1.4 --- llvm/test/Regression/Transforms/InstCombine/and.ll:1.3 Fri Aug 2 14:27:57 2002 +++ llvm/test/Regression/Transforms/InstCombine/and.ll Tue Feb 18 12:06:44 2003 @@ -8,32 +8,32 @@ implementation -int "test1"(int %A) { +int %test1(int %A) { %B = and int %A, 0 ; zero result ret int %B } -int "test2"(int %A) { +int %test2(int %A) { %B = and int %A, -1 ; noop ret int %B } -bool "test3"(bool %A) { +bool %test3(bool %A) { %B = and bool %A, false ; always = false ret bool %B } -bool "test4"(bool %A) { +bool %test4(bool %A) { %B = and bool %A, true ; noop ret bool %B } -int "test5"(int %A) { +int %test5(int %A) { %B = and int %A, %A ret int %B } -bool "test6"(bool %A) { +bool %test6(bool %A) { %B = and bool %A, %A ret bool %B } From lattner at cs.uiuc.edu Tue Feb 18 13:17:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 13:17:02 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/div.ll Message-ID: <200302181916.NAA02270@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: div.ll updated: 1.2 -> 1.3 --- Log message: modernize testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/div.ll diff -u llvm/test/Regression/Transforms/InstCombine/div.ll:1.2 llvm/test/Regression/Transforms/InstCombine/div.ll:1.3 --- llvm/test/Regression/Transforms/InstCombine/div.ll:1.2 Fri Aug 2 14:27:57 2002 +++ llvm/test/Regression/Transforms/InstCombine/div.ll Tue Feb 18 13:16:45 2003 @@ -8,9 +8,7 @@ implementation -int "test1"(int %A) -begin +int %test1(int %A) { %B = div int %A, 1 ret int %B -end - +} From lattner at cs.uiuc.edu Tue Feb 18 13:29:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 13:29:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200302181928.NAA02712@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.67 -> 1.68 --- Log message: Add a variety of new transformations: * A & ~A == 0 * A / (2^c) == A >> c if unsigned * 0 / A == 0 * 1.0 * A == A * A * (2^c) == A << c * A ^ ~A == -1 * A | ~A == -1 * 0 % X = 0 * A % (2^c) == A & (c-1) if unsigned * A - (A & B) == A & ~B * -1 - A == ~A --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.67 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.68 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.67 Thu Dec 5 16:41:53 2002 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Feb 18 13:28:33 2003 @@ -123,22 +123,27 @@ // instruction if the LHS is a constant zero (which is the 'negate' form). // static inline Value *dyn_castNegInst(Value *V) { - Instruction *I = dyn_cast(V); - if (!I || I->getOpcode() != Instruction::Sub) return 0; - - if (I->getOperand(0) == Constant::getNullValue(I->getType())) - return I->getOperand(1); - return 0; + return BinaryOperator::isNeg(V) ? + BinaryOperator::getNegArgument(cast(V)) : 0; } static inline Value *dyn_castNotInst(Value *V) { - Instruction *I = dyn_cast(V); - if (!I || I->getOpcode() != Instruction::Xor) return 0; + return BinaryOperator::isNot(V) ? + BinaryOperator::getNotArgument(cast(V)) : 0; +} - if (ConstantIntegral *CI = dyn_cast(I->getOperand(1))) - if (CI->isAllOnesValue()) - return I->getOperand(0); - return 0; + +// Log2 - Calculate the log base 2 for the specified value if it is exactly a +// power of 2. +static unsigned Log2(uint64_t Val) { + assert(Val > 1 && "Values 0 and 1 should be handled elsewhere!"); + unsigned Count = 0; + while (Val != 1) { + if (Val & 1) return 0; // Multiple bits set? + Val >>= 1; + ++Count; + } + return Count; } Instruction *InstCombiner::visitAdd(BinaryOperator &I) { @@ -197,56 +202,119 @@ if (Value *V = dyn_castNegInst(Op1)) return BinaryOperator::create(Instruction::Add, Op0, V); - // Replace (x - (y - z)) with (x + (z - y)) if the (y - z) subexpression is - // not used by anyone else... - // + // Replace (-1 - A) with (~A)... + if (ConstantInt *C = dyn_cast(Op0)) + if (C->isAllOnesValue()) + return BinaryOperator::createNot(Op1); + if (BinaryOperator *Op1I = dyn_cast(Op1)) - if (Op1I->use_size() == 1 && Op1I->getOpcode() == Instruction::Sub) { - // Swap the two operands of the subexpr... - Value *IIOp0 = Op1I->getOperand(0), *IIOp1 = Op1I->getOperand(1); - Op1I->setOperand(0, IIOp1); - Op1I->setOperand(1, IIOp0); + if (Op1I->use_size() == 1) { + // Replace (x - (y - z)) with (x + (z - y)) if the (y - z) subexpression + // is not used by anyone else... + // + if (Op1I->getOpcode() == Instruction::Sub) { + // Swap the two operands of the subexpr... + Value *IIOp0 = Op1I->getOperand(0), *IIOp1 = Op1I->getOperand(1); + Op1I->setOperand(0, IIOp1); + Op1I->setOperand(1, IIOp0); + + // Create the new top level add instruction... + return BinaryOperator::create(Instruction::Add, Op0, Op1); + } + + // Replace (A - (A & B)) with (A & ~B) if this is the only use of (A&B)... + // + if (Op1I->getOpcode() == Instruction::And && + (Op1I->getOperand(0) == Op0 || Op1I->getOperand(1) == Op0)) { + Value *OtherOp = Op1I->getOperand(Op1I->getOperand(0) == Op0); - // Create the new top level add instruction... - return BinaryOperator::create(Instruction::Add, Op0, Op1); + Instruction *NewNot = BinaryOperator::createNot(OtherOp, "B.not", &I); + return BinaryOperator::create(Instruction::And, Op0, NewNot); + } } + return 0; } Instruction *InstCombiner::visitMul(BinaryOperator &I) { bool Changed = SimplifyBinOp(I); - Value *Op1 = I.getOperand(0); + Value *Op0 = I.getOperand(0); // Simplify mul instructions with a constant RHS... - if (Constant *Op2 = dyn_cast(I.getOperand(1))) { - if (I.getType()->isInteger() && cast(Op2)->equalsInt(1)) - return ReplaceInstUsesWith(I, Op1); // Eliminate 'mul int %X, 1' - - if (I.getType()->isInteger() && cast(Op2)->equalsInt(2)) - // Convert 'mul int %X, 2' to 'add int %X, %X' - return BinaryOperator::create(Instruction::Add, Op1, Op1, I.getName()); + if (Constant *Op1 = dyn_cast(I.getOperand(1))) { + if (ConstantInt *CI = dyn_cast(Op1)) { + const Type *Ty = CI->getType(); + uint64_t Val = Ty->isSigned() ? + (uint64_t)cast(CI)->getValue() : + cast(CI)->getValue(); + switch (Val) { + case 0: + return ReplaceInstUsesWith(I, Op1); // Eliminate 'mul double %X, 0' + case 1: + return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul int %X, 1' + case 2: // Convert 'mul int %X, 2' to 'add int %X, %X' + return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName()); + } - if (Op2->isNullValue()) - return ReplaceInstUsesWith(I, Op2); // Eliminate 'mul int %X, 0' + if (uint64_t C = Log2(Val)) // Replace X*(2^C) with X << C + return new ShiftInst(Instruction::Shl, Op0, + ConstantUInt::get(Type::UByteTy, C)); + } else { + ConstantFP *Op1F = cast(Op1); + if (Op1F->isNullValue()) + return ReplaceInstUsesWith(I, Op1); + + // "In IEEE floating point, x*1 is not equivalent to x for nans. However, + // ANSI says we can drop signals, so we can do this anyway." (from GCC) + if (Op1F->getValue() == 1.0) + return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0' + } } return Changed ? &I : 0; } - Instruction *InstCombiner::visitDiv(BinaryOperator &I) { // div X, 1 == X - if (ConstantInt *RHS = dyn_cast(I.getOperand(1))) + if (ConstantInt *RHS = dyn_cast(I.getOperand(1))) { if (RHS->equalsInt(1)) return ReplaceInstUsesWith(I, I.getOperand(0)); + + // Check to see if this is an unsigned division with an exact power of 2, + // if so, convert to a right shift. + if (ConstantUInt *C = dyn_cast(RHS)) + if (uint64_t Val = C->getValue()) // Don't break X / 0 + if (uint64_t C = Log2(Val)) + return new ShiftInst(Instruction::Shr, I.getOperand(0), + ConstantUInt::get(Type::UByteTy, C)); + } + + // 0 / X == 0, we don't need to preserve faults! + if (ConstantInt *LHS = dyn_cast(I.getOperand(0))) + if (LHS->equalsInt(0)) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + return 0; } Instruction *InstCombiner::visitRem(BinaryOperator &I) { - // rem X, 1 == 0 - if (ConstantInt *RHS = dyn_cast(I.getOperand(1))) - if (RHS->equalsInt(1)) + if (ConstantInt *RHS = dyn_cast(I.getOperand(1))) { + if (RHS->equalsInt(1)) // X % 1 == 0 + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + + // Check to see if this is an unsigned remainder with an exact power of 2, + // if so, convert to a bitwise and. + if (ConstantUInt *C = dyn_cast(RHS)) + if (uint64_t Val = C->getValue()) // Don't break X % 0 (divide by zero) + if (Log2(Val)) + return BinaryOperator::create(Instruction::And, I.getOperand(0), + ConstantUInt::get(I.getType(), Val-1)); + } + + // 0 % X == 0, we don't need to preserve faults! + if (ConstantInt *LHS = dyn_cast(I.getOperand(0))) + if (LHS->equalsInt(0)) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); return 0; @@ -299,15 +367,19 @@ if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op0); - // and (not A), (not B) == not (or A, B) - if (Op0->use_size() == 1 && Op1->use_size() == 1) - if (Value *A = dyn_castNotInst(Op0)) - if (Value *B = dyn_castNotInst(Op1)) { - Instruction *Or = BinaryOperator::create(Instruction::Or, A, B, - I.getName()+".demorgan"); - InsertNewInstBefore(Or, I); - return BinaryOperator::createNot(Or, I.getName()); - } + Value *Op0NotVal = dyn_castNotInst(Op0); + Value *Op1NotVal = dyn_castNotInst(Op1); + + // (~A & ~B) == (~(A | B)) - Demorgan's Law + if (Op0->use_size() == 1 && Op1->use_size() == 1 && Op0NotVal && Op1NotVal) { + Instruction *Or = BinaryOperator::create(Instruction::Or, Op0NotVal, + Op1NotVal,I.getName()+".demorgan", + &I); + return BinaryOperator::createNot(Or); + } + + if (Op0NotVal == Op1 || Op1NotVal == Op0) // A & ~A == ~A & A == 0 + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); return Changed ? &I : 0; } @@ -327,6 +399,16 @@ if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op1); + if (Value *X = dyn_castNotInst(Op0)) // ~A | A == -1 + if (X == Op1) + return ReplaceInstUsesWith(I, + ConstantIntegral::getAllOnesValue(I.getType())); + + if (Value *X = dyn_castNotInst(Op1)) // A | ~A == -1 + if (X == Op0) + return ReplaceInstUsesWith(I, + ConstantIntegral::getAllOnesValue(I.getType())); + return Changed ? &I : 0; } @@ -359,6 +441,16 @@ } } + if (Value *X = dyn_castNotInst(Op0)) // ~A ^ A == -1 + if (X == Op1) + return ReplaceInstUsesWith(I, + ConstantIntegral::getAllOnesValue(I.getType())); + + if (Value *X = dyn_castNotInst(Op1)) // A ^ ~A == -1 + if (X == Op0) + return ReplaceInstUsesWith(I, + ConstantIntegral::getAllOnesValue(I.getType())); + return Changed ? &I : 0; } @@ -501,7 +593,7 @@ // Check to see if we are shifting left by 1. If so, turn it into an add // instruction. if (I.getOpcode() == Instruction::Shl && CUI->equalsInt(1)) - // Convert 'shl int %X, 2' to 'add int %X, %X' + // Convert 'shl int %X, 1' to 'add int %X, %X' return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName()); } From lattner at cs.uiuc.edu Tue Feb 18 13:29:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 13:29:02 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/and.ll div.ll mul.ll or.ll rem.ll sub.ll Message-ID: <200302181928.NAA02731@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: and.ll updated: 1.4 -> 1.5 div.ll updated: 1.3 -> 1.4 mul.ll updated: 1.2 -> 1.3 or.ll updated: 1.7 -> 1.8 rem.ll updated: 1.2 -> 1.3 sub.ll updated: 1.5 -> 1.6 --- Log message: test for a variety of new transformations: * A & ~A == 0 * A / (2^c) == A >> c if unsigned * 0 / A == 0 * 1.0 * A == A * A * (2^c) == A << c * A ^ ~A == -1 * A | ~A == -1 * 0 % X = 0 * A % (2^c) == A & (c-1) if unsigned * A - (A & B) == A & ~B * -1 - A == ~A --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/and.ll diff -u llvm/test/Regression/Transforms/InstCombine/and.ll:1.4 llvm/test/Regression/Transforms/InstCombine/and.ll:1.5 --- llvm/test/Regression/Transforms/InstCombine/and.ll:1.4 Tue Feb 18 12:06:44 2003 +++ llvm/test/Regression/Transforms/InstCombine/and.ll Tue Feb 18 13:28:47 2003 @@ -38,3 +38,8 @@ ret bool %B } +int %test7(int %A) { ; A & ~A == 0 + %NotA = xor int %A, -1 + %B = and int %A, %NotA + ret int %B +} \ No newline at end of file Index: llvm/test/Regression/Transforms/InstCombine/div.ll diff -u llvm/test/Regression/Transforms/InstCombine/div.ll:1.3 llvm/test/Regression/Transforms/InstCombine/div.ll:1.4 --- llvm/test/Regression/Transforms/InstCombine/div.ll:1.3 Tue Feb 18 13:16:45 2003 +++ llvm/test/Regression/Transforms/InstCombine/div.ll Tue Feb 18 13:28:47 2003 @@ -12,3 +12,13 @@ %B = div int %A, 1 ret int %B } + +uint %test2(uint %A) { + %B = div uint %A, 8 ; => Shift + ret int %B +} + +int %test3(int %A) { + %B = div int 0, %A ; => 0, don't need to keep traps + ret int %B +} Index: llvm/test/Regression/Transforms/InstCombine/mul.ll diff -u llvm/test/Regression/Transforms/InstCombine/mul.ll:1.2 llvm/test/Regression/Transforms/InstCombine/mul.ll:1.3 --- llvm/test/Regression/Transforms/InstCombine/mul.ll:1.2 Fri Aug 2 14:27:57 2002 +++ llvm/test/Regression/Transforms/InstCombine/mul.ll Tue Feb 18 13:28:47 2003 @@ -26,3 +26,12 @@ ret int %B end +double %test4(double %A) { + %B = mul double 1.0, %A ; This is safe for FP + ret double %B +} + +int %test5(int %A) { + %B = mul int %A, 8 + ret int %B +} Index: llvm/test/Regression/Transforms/InstCombine/or.ll diff -u llvm/test/Regression/Transforms/InstCombine/or.ll:1.7 llvm/test/Regression/Transforms/InstCombine/or.ll:1.8 --- llvm/test/Regression/Transforms/InstCombine/or.ll:1.7 Tue Feb 18 12:05:19 2003 +++ llvm/test/Regression/Transforms/InstCombine/or.ll Tue Feb 18 13:28:47 2003 @@ -58,3 +58,14 @@ ret int %B } +int %test11(int %A) { ; A ^ ~A == -1 + %NotA = xor int -1, %A + %B = xor int %A, %NotA + ret int %B +} + +int %test12(int %A) { ; A | ~A == -1 + %NotA = xor int -1, %A + %B = or int %A, %NotA + ret int %B +} Index: llvm/test/Regression/Transforms/InstCombine/rem.ll diff -u llvm/test/Regression/Transforms/InstCombine/rem.ll:1.2 llvm/test/Regression/Transforms/InstCombine/rem.ll:1.3 --- llvm/test/Regression/Transforms/InstCombine/rem.ll:1.2 Fri Aug 2 14:27:58 2002 +++ llvm/test/Regression/Transforms/InstCombine/rem.ll Tue Feb 18 13:28:47 2003 @@ -8,8 +8,17 @@ implementation -int "test1"(int %A) { +int %test1(int %A) { %B = rem int %A, 1 ; ISA constant 0 ret int %B } +int %test2(int %A) { ; 0 % X = 0, we don't need ot preserve traps + %B = rem int 0, %A + ret int %B +} + +uint %test3(uint %A) { + %B = rem uint %A, 8 ; & 7 + ret uint %B +} Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.5 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.6 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.5 Fri Aug 2 14:27:58 2002 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Tue Feb 18 13:28:47 2003 @@ -35,3 +35,15 @@ %E = sub int %A, %D ret int %E } + +int %test6(int %A, int %B) { + %C = and int %A, %B ; A - (A & B) => A & ~B + %D = sub int %A, %C + ret int %D +} + +int %test7(int %A) { + %B = sub int -1, %A ; B = ~A + ret int %B +} + From lattner at cs.uiuc.edu Tue Feb 18 13:44:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 13:44:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll sub.ll Message-ID: <200302181943.NAA02790@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.3 -> 1.4 sub.ll updated: 1.6 -> 1.7 --- Log message: Modernize testcases --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.3 llvm/test/Regression/Transforms/InstCombine/add.ll:1.4 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.3 Fri Aug 2 14:27:57 2002 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Tue Feb 18 13:43:21 2003 @@ -10,33 +10,33 @@ implementation -int "test1"(int %A) +int %test1(int %A) begin %B = add int %A, 0 ret int %B end -int "test2"(int %A) +int %test2(int %A) begin %B = add int %A, 5 %C = add int %B, -5 ret int %C end -int "test3"(int %A) +int %test3(int %A) begin %B = add int %A, 5 %C = sub int %B, 5 ;; This should get converted to an add ret int %C end -int "test4"(int %A, int %B) { +int %test4(int %A, int %B) { %C = sub int 0, %A %D = add int %B, %C ; D = B + -A = B - A ret int %D } -int "test5"(int %A, int %B) { +int %test5(int %A, int %B) { %C = sub int 0, %A %D = add int %C, %B ; D = -A + B = B - A ret int %D Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.6 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.7 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.6 Tue Feb 18 13:28:47 2003 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Tue Feb 18 13:43:21 2003 @@ -8,29 +8,29 @@ implementation -int "test1"(int %A) { +int %test1(int %A) { %B = sub int %A, %A ; ISA constant 0 ret int %B } -int "test2"(int %A) { +int %test2(int %A) { %B = sub int %A, 0 ret int %B } -int "test3"(int %A) { +int %test3(int %A) { %B = sub int 0, %A ; B = -A %C = sub int 0, %B ; C = -B = A ret int %C } -int "test4"(int %A, int %x) { +int %test4(int %A, int %x) { %B = sub int 0, %A %C = sub int %x, %B ret int %C } -int "test5"(int %A, int %Bok, int %Cok) { +int %test5(int %A, int %Bok, int %Cok) { %D = sub int %Bok, %Cok %E = sub int %A, %D ret int %E From lattner at cs.uiuc.edu Tue Feb 18 13:45:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 13:45:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll Message-ID: <200302181944.NAA02801@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.4 -> 1.5 --- Log message: Modernize testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.4 llvm/test/Regression/Transforms/InstCombine/add.ll:1.5 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.4 Tue Feb 18 13:43:21 2003 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Tue Feb 18 13:43:53 2003 @@ -10,25 +10,22 @@ implementation -int %test1(int %A) -begin +int %test1(int %A) { %B = add int %A, 0 ret int %B -end +} -int %test2(int %A) -begin +int %test2(int %A) { %B = add int %A, 5 %C = add int %B, -5 ret int %C -end +} -int %test3(int %A) -begin +int %test3(int %A) { %B = add int %A, 5 %C = sub int %B, 5 ;; This should get converted to an add ret int %C -end +} int %test4(int %A, int %B) { %C = sub int 0, %A From lattner at cs.uiuc.edu Tue Feb 18 13:56:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 13:56:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll sub.ll Message-ID: <200302181955.NAA03352@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.5 -> 1.6 sub.ll updated: 1.7 -> 1.8 --- Log message: Add new testcases --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.5 llvm/test/Regression/Transforms/InstCombine/add.ll:1.6 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.5 Tue Feb 18 13:43:53 2003 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Tue Feb 18 13:55:31 2003 @@ -39,3 +39,15 @@ ret int %D } +int %test6(int %A) { + %B = mul int 7, %A + %C = add int %B, %A ; C = 7*A+A == 8*A == A << 3 + ret int %C +} + +int %test7(int %A) { + %B = mul int 7, %A + %C = add int %A, %B ; C = A+7*A == 8*A == A << 3 + ret int %C +} + Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.7 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.8 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.7 Tue Feb 18 13:43:21 2003 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Tue Feb 18 13:55:31 2003 @@ -47,3 +47,15 @@ ret int %B } +int %test8(int %A) { + %B = mul int 9, %A + %C = sub int %B, %A ; C = 9*A-A == A*8 == A << 3 + ret int %C +} + +int %test9(int %A) { + %B = mul int 3, %A + %C = sub int %A, %B ; C = A-3*A == A*-2 + ret int %C +} + From lattner at cs.uiuc.edu Tue Feb 18 13:58:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 13:58:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200302181957.NAA03364@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.68 -> 1.69 --- Log message: 4 new transformations: * X*C + X --> X * (C+1) * X + X*C --> X * (C+1) * X - X*C --> X * (1-C) * X*C - X --> X * (C-1) --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.68 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.69 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.68 Tue Feb 18 13:28:33 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Feb 18 13:57:07 2003 @@ -146,6 +146,16 @@ return Count; } +static inline Value *dyn_castFoldableMul(Value *V) { + if (V->use_size() == 1 && V->getType()->isInteger()) + if (Instruction *I = dyn_cast(V)) + if (I->getOpcode() == Instruction::Mul) + if (isa(I->getOperand(1))) + return I->getOperand(0); + return 0; +} + + Instruction *InstCombiner::visitAdd(BinaryOperator &I) { bool Changed = SimplifyBinOp(I); Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); @@ -182,6 +192,22 @@ } } + // X*C + X --> X * (C+1) + if (dyn_castFoldableMul(LHS) == RHS) { + Constant *CP1 = *cast(cast(LHS)->getOperand(1)) + + *ConstantInt::get(I.getType(), 1); + assert(CP1 && "Couldn't constant fold C + 1?"); + return BinaryOperator::create(Instruction::Mul, RHS, CP1); + } + + // X + X*C --> X * (C+1) + if (dyn_castFoldableMul(RHS) == LHS) { + Constant *CP1 = *cast(cast(RHS)->getOperand(1)) + + *ConstantInt::get(I.getType(), 1); + assert(CP1 && "Couldn't constant fold C + 1?"); + return BinaryOperator::create(Instruction::Mul, LHS, CP1); + } + return Changed ? &I : 0; } @@ -231,7 +257,23 @@ Instruction *NewNot = BinaryOperator::createNot(OtherOp, "B.not", &I); return BinaryOperator::create(Instruction::And, Op0, NewNot); } + + // X - X*C --> X * (1-C) + if (dyn_castFoldableMul(Op1I) == Op0) { + Constant *CP1 = *ConstantInt::get(I.getType(), 1) - + *cast(cast(Op1)->getOperand(1)); + assert(CP1 && "Couldn't constant fold 1-C?"); + return BinaryOperator::create(Instruction::Mul, Op0, CP1); + } } + + // X*C - X --> X * (C-1) + if (dyn_castFoldableMul(Op0) == Op1) { + Constant *CP1 = *cast(cast(Op0)->getOperand(1)) - + *ConstantInt::get(I.getType(), 1); + assert(CP1 && "Couldn't constant fold C - 1?"); + return BinaryOperator::create(Instruction::Mul, Op1, CP1); + } return 0; } From lattner at cs.uiuc.edu Tue Feb 18 14:41:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 14:41:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/TEST.dsgraph.report Message-ID: <200302182040.OAA03515@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs: TEST.dsgraph.report updated: 1.4 -> 1.5 --- Log message: many changes --- Diffs of the changes: Index: llvm/test/Programs/TEST.dsgraph.report diff -u llvm/test/Programs/TEST.dsgraph.report:1.4 llvm/test/Programs/TEST.dsgraph.report:1.5 --- llvm/test/Programs/TEST.dsgraph.report:1.4 Fri Feb 14 18:50:40 2003 +++ llvm/test/Programs/TEST.dsgraph.report Tue Feb 18 14:40:04 2003 @@ -15,36 +15,84 @@ } } +sub FormatSize { + my $Size = shift; + if ($Size > 10*1024*1024) { + return (int $Size*10 / (1024*1024))/10 . "MB"; + } elsif ($Size > 10*1024) { + return (int $Size / 1024); + } else { + return $Size . "B"; + } +} + +sub NoStar { + return "0" if ($_[0] eq '*'); + return $_[0]; +} + +sub NoCallNodes { + $_[0] =~ m/([0-9]+)\+/; + return $1; +} + # Sort by total analyze time $SortCol = 7; # Sort in descending order $SortReverse = 1; -%NameMap = ( - treeadd => 'Olden-treeadd', - bisort => 'Olden-bisort', - mst => 'Olden-mst', - perimeter => 'Olden-perimeter', - health => 'Olden-health', - tsp => 'Olden-tsp', - power => 'Olden-power', - em3d => 'Olden-em3d', - voronoi => 'Olden-voronoi', - bh => 'Olden-bh', - - ks => 'ptrdist-ks', - anagram => 'ptrdist-anagram', - yacr2 => 'ptrdist-yacr2', - ft => 'ptrdist-ft', - bc => 'ptrdist-bc'); +# For latex output, limit benchmarks and rename as appropriate + at LatexRowMapOrder = ( + 'treeadd' => 'Olden-treeadd', + 'bisort' => 'Olden-bisort', + 'mst' => 'Olden-mst', + 'perimeter' => 'Olden-perimeter', + 'health' => 'Olden-health', + 'tsp' => 'Olden-tsp', + 'power' => 'Olden-power', + 'em3d' => 'Olden-em3d', + 'voronoi' => 'Olden-voronoi', + 'bh' => 'Olden-bh', + '-' => '-', + 'anagram' => 'ptrdist-anagram', + 'ks' => 'ptrdist-ks', + 'ft' => 'ptrdist-ft', + 'yacr2' => 'ptrdist-yacr2', + 'bc' => 'ptrdist-bc', + '-' => '-', + '181.mcf' => '181.mcf', + '256.bzip2' => '256.bzip2', + '164.gzip' => '164.gzip', + '197.parser' => '197.parser', + '300.twolf' => '300.twolf', + '255.vortex' => '255.vortex', + '-' => '-', + 'sgefa' => 'sgefa', + 'sim' => 'sim', + 'burg' => 'burg', + 'gnuchess' => 'gnuchess', + 'larn' => 'larn', + 'flex' => 'flex', + 'moria' => 'moria', + 'povray31' => 'povray31' + ); - at LatexColumns = (0, 1, 26, 19, # Program, LOC, #Instrs, MaxSCC + at LatexColumns = (1, 27, 19, # LOC, #Instrs, MaxSCC 4, 5, 6, 7, # Execution times - 13, # Memory BU+TD + 11, # Memory BU + 12, # Memory TD 16, 17, # Total, Max Nodes 15); # NumFolded +# Specify how to format columns nicely for printing... +%LatexColumnFormat = ( + 11 => \&FormatSize, + 12 => \&FormatSize, + 15 => \&NoStar, + 16 => \&NoCallNodes + ); + # These are the columns for the report. The first entry is the header for the # column, the second is the regex to use to match the value. Empty list create # seperators, and closures may be put in for custom processing. @@ -65,7 +113,7 @@ ["LcSize:" , '([0-9]+) Local'], ["BUSize:" , '([0-9]+) Bottom-up'], ["TDSize:" , '([0-9]+) Top-down'], - ["BUTDSz:" , sub { return SumCols(@_, 3); }], + ["BUTDSz:" , sub { return SumCols(@_, 2); }], [], # Misc stuff ["NumFold" , '([0-9]+).*Number of folded nodes '], @@ -79,7 +127,8 @@ ["Calls" , '([0-9]+).*Number of Call insts'], ["Allca" , '([0-9]+).*Number of Alloca insts'], ["Mallc" , '([0-9]+).*Number of Malloc insts'], - ["Sum" , sub { return SumCols(@_, 5); }], + ["GEP" , '([0-9]+).*Number of GetElementPtr insts'], + ["Sum" , sub { return SumCols(@_, 6); }], [], ["num/ind" , '([0-9]+).*number of indirect call sites'], ["indcallee",'([0-9]+).*number of callee functions at'], From lattner at cs.uiuc.edu Tue Feb 18 14:41:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 14:41:02 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/TEST.dsgraph.Makefile Message-ID: <200302182040.OAA03528@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs: TEST.dsgraph.Makefile updated: 1.9 -> 1.10 --- Log message: Track memory usage --- Diffs of the changes: Index: llvm/test/Programs/TEST.dsgraph.Makefile diff -u llvm/test/Programs/TEST.dsgraph.Makefile:1.9 llvm/test/Programs/TEST.dsgraph.Makefile:1.10 --- llvm/test/Programs/TEST.dsgraph.Makefile:1.9 Fri Feb 14 18:31:28 2003 +++ llvm/test/Programs/TEST.dsgraph.Makefile Tue Feb 18 14:40:20 2003 @@ -13,12 +13,14 @@ ANALYZE_OPTS := -stats -time-passes -only-print-main-ds -dsstats -instcount +MEM := -track-memory + $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.lib.bc Output/%.LOC.txt $(LANALYZE) $(LOPT) @echo -n "LOC: " > $@ @cat Output/$*.LOC.txt >> $@ - -(time -p $(LANALYZE) -$(PASS)datastructure $(ANALYZE_OPTS) $<)>> $@ 2>&1 - -($(LOPT) -steens-aa -time-passes > /dev/null < $<) >> $@ 2>&1 + -(time -p $(LANALYZE) $(MEM) -$(PASS)datastructure $(ANALYZE_OPTS) $<)>> $@ 2>&1 + -($(LOPT) -steens-aa $(MEM) -time-passes > /dev/null < $<) >> $@ 2>&1 $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt From lattner at cs.uiuc.edu Tue Feb 18 14:41:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 14:41:03 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/GenerateReport.pl Message-ID: <200302182040.OAA03541@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs: GenerateReport.pl updated: 1.8 -> 1.9 --- Log message: Add support for LatexColumnFormat --- Diffs of the changes: Index: llvm/test/Programs/GenerateReport.pl diff -u llvm/test/Programs/GenerateReport.pl:1.8 llvm/test/Programs/GenerateReport.pl:1.9 --- llvm/test/Programs/GenerateReport.pl:1.8 Fri Feb 14 18:31:49 2003 +++ llvm/test/Programs/GenerateReport.pl Tue Feb 18 14:40:45 2003 @@ -73,6 +73,7 @@ die "Couldn't open report description '$ReportFN'!"; my @LatexColumns; # Filled in by report if it supports Latex mode +my %LatexColumnFormat; # Filled in by report if supports latex mode my @Fields = eval ; @@ -184,16 +185,41 @@ # Print out the latexified table... # shift @Values; # Don't print the header... - foreach $Row (@Values) { - my $First = 1; - - for $ColNum (@LatexColumns) { - # Print a seperator... - print " & " if ($First == 0); - $First = 0; - printf "%-$FieldWidths[$ColNum]s", $Row->[$ColNum]; + + # Make sure the benchmark name field is wide enough for any aliases. + foreach $Name (@LatexRowMapOrder) { + $FieldWidths[0] = length $Name if (length($Name) > $FieldWidths[0]); + } + + # Print out benchmarks listed in the LatexRowMapOrder + for ($i = 0; $i < @LatexRowMapOrder; $i += 2) { + my $Name = $LatexRowMapOrder[$i]; + if ($Name eq '-') { + print "\\hline\n"; + } else { + # Output benchmark name... + printf "%-$FieldWidths[0]s", $LatexRowMapOrder[$i+1]; + + # Find the row that this benchmark name corresponds to... + foreach $Row (@Values) { + if ($Row->[0] eq $Name) { + for $ColNum (@LatexColumns) { + # Print a seperator... + my $Val = $Row->[$ColNum]; + if (exists $LatexColumnFormat{$ColNum}) { + # If a column format routine has been specified, run it now... + $Val = &{$LatexColumnFormat{$ColNum}}($Val); + } + + printf " & %-$FieldWidths[$ColNum]s", $Val; + } + goto Done; + } + } + print "UNKNOWN Benchmark name: " . $Name; + Done: + print "\\\\\n"; } - print "\\\\\n"; } } else { # From lattner at cs.uiuc.edu Tue Feb 18 14:42:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 14:42:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile Message-ID: <200302182041.OAA03552@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile updated: 1.12 -> 1.13 --- Log message: Add support for report.tex pseudo target --- Diffs of the changes: Index: llvm/test/Programs/Makefile diff -u llvm/test/Programs/Makefile:1.12 llvm/test/Programs/Makefile:1.13 --- llvm/test/Programs/Makefile:1.12 Fri Feb 14 17:25:44 2003 +++ llvm/test/Programs/Makefile Tue Feb 18 14:41:10 2003 @@ -35,8 +35,14 @@ report.$(TEST).html: report.$(TEST).raw.out $(TestReport) ./GenerateReport.pl -html TEST.$(TEST).report < $< > $@ +report.$(TEST).tex: report.$(TEST).raw.out $(TestReport) + ./GenerateReport.pl -latex TEST.$(TEST).report < $< > $@ + report: report.$(TEST).txt - @cat report.$(TEST).txt + @cat $< + +report.tex: report.$(TEST).tex + @cat $< clean:: rm -f report.*.raw.out report.*.txt From lattner at cs.uiuc.edu Tue Feb 18 14:42:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 14:42:02 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/TEST.aa.report Message-ID: <200302182041.OAA03566@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs: TEST.aa.report updated: 1.1 -> 1.2 --- Log message: Add latex output support --- Diffs of the changes: Index: llvm/test/Programs/TEST.aa.report diff -u llvm/test/Programs/TEST.aa.report:1.1 llvm/test/Programs/TEST.aa.report:1.2 --- llvm/test/Programs/TEST.aa.report:1.1 Wed Feb 12 13:34:23 2003 +++ llvm/test/Programs/TEST.aa.report Tue Feb 18 14:41:27 2003 @@ -16,11 +16,63 @@ } } -# Sort by program name... -$SortCol = 1; +sub OnlyMayInfo { + $_[0] =~ m|/([0-9]+)%/|; + return $1."\\%"; +} + +# Sort by ds time... +$SortCol = 15; # Sort in ascending order $SortReverse = 0; + +# For latex output, limit benchmarks and rename as appropriate + at LatexRowMapOrder = ( + 'treeadd' => 'Olden-treeadd', + 'bisort' => 'Olden-bisort', + 'mst' => 'Olden-mst', + 'perimeter' => 'Olden-perimeter', + 'health' => 'Olden-health', + 'tsp' => 'Olden-tsp', + 'power' => 'Olden-power', + 'em3d' => 'Olden-em3d', + 'voronoi' => 'Olden-voronoi', + 'bh' => 'Olden-bh', + '-' => '-', + 'anagram' => 'ptrdist-anagram', + 'ks' => 'ptrdist-ks', + 'ft' => 'ptrdist-ft', + 'yacr2' => 'ptrdist-yacr2', + 'bc' => 'ptrdist-bc', + '-' => '-', + '181.mcf' => '181.mcf', + '256.bzip2' => '256.bzip2', + '164.gzip' => '164.gzip', + '197.parser' => '197.parser', + '300.twolf' => '300.twolf', + '255.vortex' => '255.vortex', + '-' => '-', + 'sgefa' => 'sgefa', + 'sim' => 'sim', + 'burg' => 'burg', + 'gnuchess' => 'gnuchess', + 'larn' => 'larn', + 'flex' => 'flex', + 'moria' => 'moria', + 'povray31' => 'povray31' + ); + + at LatexColumns = (2, 3, 4, 6, 7, 5); + +# Specify how to reformat columns to be presentable... +%LatexColumnFormat = ( + 2 => \&OnlyMayInfo, + 3 => \&OnlyMayInfo, + 4 => \&OnlyMayInfo, + 5 => \&OnlyMayInfo, + 6 => \&OnlyMayInfo, + 7 => \&OnlyMayInfo); # These are the columns for the report. The first entry is the header for the # column, the second is the regex to use to match the value. Empty list create From lattner at cs.uiuc.edu Tue Feb 18 14:43:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 14:43:01 2003 Subject: [llvm-commits] CVS: llvm/test/Libraries/libdummy/dummylib.c Message-ID: <200302182042.OAA03581@apoc.cs.uiuc.edu> Changes in directory llvm/test/Libraries/libdummy: dummylib.c updated: 1.4 -> 1.5 --- Log message: Add lots of functions --- Diffs of the changes: Index: llvm/test/Libraries/libdummy/dummylib.c diff -u llvm/test/Libraries/libdummy/dummylib.c:1.4 llvm/test/Libraries/libdummy/dummylib.c:1.5 --- llvm/test/Libraries/libdummy/dummylib.c:1.4 Tue Feb 11 17:12:23 2003 +++ llvm/test/Libraries/libdummy/dummylib.c Tue Feb 18 14:42:07 2003 @@ -3,10 +3,19 @@ #include #include #include +#include +#include +#include + +int stat(const char *file_name, struct stat *buf) { return 0; } +int fstat(int filedes, struct stat *buf) { return 0; } +int lstat(const char *file_name, struct stat *buf) { return 0; } // Varargs function definitions -int ioctl(int d, int request) {return 0; } +int ioctl(int d, int request, ...) {return 0; } int printf(const char *X) {return 0; } +int sscanf(const char *X, const char *Y, ...) { return 0; } +int fprintf(FILE *stream, const char *format, ...) { return 0; } int gettimeofday(struct timeval *tv, void *tz) { return 0; } @@ -21,6 +30,7 @@ void __main() {} int atoi(const char*x) { return 1; } char *fgets(char*Ptr, int x, FILE*F) { return Ptr; } +char *gets(char *C) { return C; } int fclose(FILE*F) { return 0; } FILE *fopen(const char *n, const char*x) { return malloc(sizeof(FILE)); } FILE *freopen(const char *path, const char *mode, FILE *stream) { return 0; } @@ -45,6 +55,9 @@ int fputs(const char *s, char *stream) { return 0; } int ferror(FILE *F) { return 0; } FILE *fdopen(int fildes, const char *mode) { return 0;} +FILE *popen(const char *command, const char *type) { return 0; } +int pclose(FILE *stream) { return 0; } + int ungetc(int c, FILE *stream) { return 0; } int setvbuf(FILE *stream, char *buf, int mode , size_t size) { return 0; } void rewind(FILE*F) { } From lattner at cs.uiuc.edu Tue Feb 18 14:43:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 18 14:43:02 2003 Subject: [llvm-commits] CVS: llvm/test/Libraries/libc/string.c Message-ID: <200302182042.OAA03588@apoc.cs.uiuc.edu> Changes in directory llvm/test/Libraries/libc: string.c updated: 1.3 -> 1.4 --- Log message: Remove support for memset --- Diffs of the changes: Index: llvm/test/Libraries/libc/string.c diff -u llvm/test/Libraries/libc/string.c:1.3 llvm/test/Libraries/libc/string.c:1.4 --- llvm/test/Libraries/libc/string.c:1.3 Wed Jul 17 19:15:29 2002 +++ llvm/test/Libraries/libc/string.c Tue Feb 18 14:42:15 2003 @@ -53,7 +53,7 @@ } // http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/generic/?cvsroot=glibc - +#if 0 typedef unsigned int op_t; #define OPSIZ 4 @@ -119,6 +119,7 @@ return dstpp; } +#endif void *memcpy(void *dstpp, const void *srcpp, size_t len) { char *dstp = (char*)dstpp; From ashukla at cs.uiuc.edu Wed Feb 19 13:20:01 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Wed Feb 19 13:20:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/MemoryManager2.cpp Message-ID: <200302191919.NAA18784@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: MemoryManager2.cpp updated: 1.1 -> 1.2 --- Log message: corrected for compilation warnings --- Diffs of the changes: Index: llvm/lib/Reoptimizer/TraceCache/MemoryManager2.cpp diff -u llvm/lib/Reoptimizer/TraceCache/MemoryManager2.cpp:1.1 llvm/lib/Reoptimizer/TraceCache/MemoryManager2.cpp:1.2 --- llvm/lib/Reoptimizer/TraceCache/MemoryManager2.cpp:1.1 Mon Feb 17 13:51:00 2003 +++ llvm/lib/Reoptimizer/TraceCache/MemoryManager2.cpp Wed Feb 19 13:19:17 2003 @@ -32,8 +32,8 @@ int dummyFunction2(int i); //the function that provides memory! MemoryManager2::MemoryManager2(){ - memStart = (uint64_t)&dummyFunction2; - memEnd = (uint64_t)&dummyFunction2+globalMemSize2*4; + memStart = (uint64_t)(intptr_t)&dummyFunction2; + memEnd = (uint64_t)(intptr_t)&dummyFunction2+globalMemSize2*4; //std::cerr<<"Dummy address :"<<(void *)memStart<<"\n"; freeMemList.push_back(std::make_pair(memStart, memEnd)); } @@ -49,11 +49,11 @@ for(std::list >::iterator LI = freeMemList.begin(), LE = freeMemList.end(); LI!=LE; ++LI){ - if(LI->second - LI->first >= sz-1){ + if(LI->second - LI->first >= (uint64_t)(sz-1)){ uint64_t temp = LI->first; //reassign the pair - if(LI->second - LI->first == sz-1) + if(LI->second - LI->first == (uint64_t)(sz-1)) freeMemList.erase(LI); else LI->first += sz; From ashukla at cs.uiuc.edu Wed Feb 19 13:20:03 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Wed Feb 19 13:20:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp Message-ID: <200302191919.NAA18792@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: MemoryManager.cpp updated: 1.3 -> 1.4 --- Log message: corrected for compilation warnings --- Diffs of the changes: Index: llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp diff -u llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp:1.3 llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp:1.4 --- llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp:1.3 Fri Feb 14 14:45:53 2003 +++ llvm/lib/Reoptimizer/TraceCache/MemoryManager.cpp Wed Feb 19 13:19:11 2003 @@ -32,8 +32,8 @@ int dummyFunction(int i); //the function that provides memory! MemoryManager::MemoryManager(){ - memStart = (uint64_t)&dummyFunction; - memEnd = (uint64_t)&dummyFunction+globalMemSize*4; + memStart = (uint64_t)(intptr_t)&dummyFunction; + memEnd = (uint64_t)(intptr_t)&dummyFunction+globalMemSize*4; //std::cerr<<"Dummy address :"<<(void *)memStart<<"\n"; freeMemList.push_back(std::make_pair(memStart, memEnd)); } @@ -49,11 +49,11 @@ for(std::list >::iterator LI = freeMemList.begin(), LE = freeMemList.end(); LI!=LE; ++LI){ - if(int64_t(LI->second - LI->first) >= sz-1){ + if(LI->second - LI->first >= (uint64_t)(sz-1)){ uint64_t temp = LI->first; //reassign the pair - if(int64_t(LI->second - LI->first) == sz-1) + if(LI->second - LI->first == (uint64_t)(sz-1)) freeMemList.erase(LI); else LI->first += sz; From ashukla at cs.uiuc.edu Wed Feb 19 13:27:01 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Wed Feb 19 13:27:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Trigger/Trigger.cpp Message-ID: <200302191926.NAA18805@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Trigger: Trigger.cpp updated: 1.15 -> 1.16 --- Log message: corrected for compilation warnings --- Diffs of the changes: Index: llvm/lib/Reoptimizer/Trigger/Trigger.cpp diff -u llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.15 llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.16 --- llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.15 Fri Feb 14 14:46:29 2003 +++ llvm/lib/Reoptimizer/Trigger/Trigger.cpp Wed Feb 19 13:26:38 2003 @@ -271,8 +271,10 @@ && "Incorrect trace"); //insert a BA going to the top - trace.push_back(getBranchInst(0x10800000, (uint64_t)(&trace[0]), - (uint64_t)(&trace[instIndex]))); + trace.push_back(getBranchInst + (0x10800000, + (uint64_t)(intptr_t)&trace[0], + (uint64_t)(intptr_t)&trace[instIndex])); //insert delay slot if(addrToRm.find(addr+4) == addrToRm.end()) trace.push_back(vm->readInstrFrmVm(addr+4, tr)); @@ -351,8 +353,10 @@ && "Incorrect trace"); //insert a BA going to the top - trace.push_back(getBranchInst(0x10800000, (uint64_t)(&trace[0]), - (uint64_t)(&trace[instIndex]))); + trace.push_back(getBranchInst + (0x10800000, + (uint64_t)(intptr_t)&trace[0], + (uint64_t)(intptr_t)&trace[instIndex])); @@ -506,7 +510,9 @@ instVec.push_back(jmpl); instVec.push_back(load1); //delay slot! - uint64_t newInst = getBranchInst(instr, (uint64_t)(&instVec[instIndex]), (uint64_t)(&instVec[MI->first])); + uint64_t newInst = getBranchInst(instr, + (uint64_t)(intptr_t)&instVec[instIndex], + (uint64_t)(intptr_t)&instVec[MI->first]); instVec[MI->first] = newInst; //change original call map to point to new PC From lattner at cs.uiuc.edu Wed Feb 19 16:13:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 19 16:13:01 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200302192212.QAA15915@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.78 -> 1.79 --- Log message: Fix warnings compiling C files --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.78 llvm/Makefile.common:1.79 --- llvm/Makefile.common:1.78 Thu Feb 13 10:56:30 2003 +++ llvm/Makefile.common Wed Feb 19 16:12:20 2003 @@ -164,8 +164,8 @@ # Compile a c file, don't link... CompileC := $(CC) -c $(CPPFLAGS) $(CCFLAGS) $(CompileCommonOpts) CompileCG := $(CompileC) -g -D_DEBUG -CompileCO := $(CompileC) $(CompileOptimizeOpts) -felide-constructors -fomit-frame-pointer -CompileCP := $(CompileC) $(CompileOptimizeOpts) -felide-constructors $(PROFILE) +CompileCO := $(CompileC) $(CompileOptimizeOpts) -fomit-frame-pointer +CompileCP := $(CompileC) $(CompileOptimizeOpts) $(PROFILE) # Link final executable From lattner at cs.uiuc.edu Wed Feb 19 18:10:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 19 18:10:02 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Other/Makefile Message-ID: <200302200009.SAA19313@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Other: Makefile updated: 1.1 -> 1.2 --- Log message: Make tests rerun if analyze is rebuilt --- Diffs of the changes: Index: llvm/test/Regression/Other/Makefile diff -u llvm/test/Regression/Other/Makefile:1.1 llvm/test/Regression/Other/Makefile:1.2 --- llvm/test/Regression/Other/Makefile:1.1 Thu Jan 31 22:24:20 2002 +++ llvm/test/Regression/Other/Makefile Wed Feb 19 18:09:19 2003 @@ -6,5 +6,5 @@ all:: $(addprefix Output/, $(TESTS:%.ll=%.ll.out)) -Output/%.ll.out: %.ll Output/.dir +Output/%.ll.out: %.ll Output/.dir $(LANALYZE) -$(TESTRUNR) $< From lattner at cs.uiuc.edu Wed Feb 19 18:10:06 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 19 18:10:06 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Other/2003-02-19-LoopInfoNestingBug.ll Message-ID: <200302200009.SAA19345@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Other: 2003-02-19-LoopInfoNestingBug.ll added (r1.1) --- Log message: Add a testcase for broken loopinfo --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Feb 19 18:18:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 19 18:18:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200302200017.SAA19709@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.26 -> 1.27 --- Log message: Fix bug: 2003-02-19-LoopInfoNestingBug.ll --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.26 llvm/lib/Analysis/LoopInfo.cpp:1.27 --- llvm/lib/Analysis/LoopInfo.cpp:1.26 Fri Oct 11 00:30:13 2002 +++ llvm/lib/Analysis/LoopInfo.cpp Wed Feb 19 18:17:17 2003 @@ -37,13 +37,12 @@ unsigned numBackEdges = 0; BasicBlock *header = Blocks.front(); - for (std::vector::const_iterator i = Blocks.begin(), e = Blocks.end(); - i != e; ++i) { - for (BasicBlock::succ_iterator Successor = succ_begin(*i), SEnd = succ_end(*i); - Successor != SEnd; ++Successor) { - if (header == *Successor) + for (std::vector::const_iterator I = Blocks.begin(), + E = Blocks.end(); I != E; ++I) { + for (BasicBlock::succ_iterator SI = succ_begin(*I), SE = succ_end(*I); + SI != SE; ++SI) + if (header == *SI) ++numBackEdges; - } } return numBackEdges; } @@ -138,17 +137,38 @@ // they start subloops of their own. // for (std::vector::reverse_iterator I = L->Blocks.rbegin(), - E = L->Blocks.rend(); I != E; ++I) { + E = L->Blocks.rend(); I != E; ++I) // Check to see if this block starts a new loop - if (Loop *NewLoop = ConsiderForLoop(*I, DS)) { - L->SubLoops.push_back(NewLoop); - NewLoop->ParentLoop = L; - } - - if (BBMap.find(*I) == BBMap.end()) - BBMap.insert(std::make_pair(*I, L)); - } + if (*I != BB) + if (Loop *NewLoop = ConsiderForLoop(*I, DS)) { + L->SubLoops.push_back(NewLoop); + NewLoop->ParentLoop = L; + } else { + std::map::iterator BBMI = BBMap.lower_bound(*I); + if (BBMI == BBMap.end() || BBMI->first != *I) { // Not in map yet... + BBMap.insert(BBMI, std::make_pair(*I, L)); + } else { + // If this is already in the BBMap then this means that we already added + // a loop for it, but incorrectly added the loop to a higher level loop + // instead of the current loop we are creating. Fix this now by moving + // the loop into the correct subloop. + // + Loop *SubLoop = BBMI->second; + Loop *OldSubLoopParent = SubLoop->getParentLoop(); + if (OldSubLoopParent != L) { + // Remove SubLoop from OldSubLoopParent's list of subloops... + std::vector::iterator I = + std::find(OldSubLoopParent->SubLoops.begin(), + OldSubLoopParent->SubLoops.end(), SubLoop); + assert(I != OldSubLoopParent->SubLoops.end() + && "Loop parent doesn't contain loop?"); + OldSubLoopParent->SubLoops.erase(I); + SubLoop->ParentLoop = L; + L->SubLoops.push_back(SubLoop); + } + } + } return L; } From lattner at cs.uiuc.edu Wed Feb 19 18:19:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 19 18:19:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200302200018.SAA19753@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.27 -> 1.28 --- Log message: Fix 80 character formatting --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.27 llvm/lib/Analysis/LoopInfo.cpp:1.28 --- llvm/lib/Analysis/LoopInfo.cpp:1.27 Wed Feb 19 18:17:17 2003 +++ llvm/lib/Analysis/LoopInfo.cpp Wed Feb 19 18:18:07 2003 @@ -149,10 +149,10 @@ if (BBMI == BBMap.end() || BBMI->first != *I) { // Not in map yet... BBMap.insert(BBMI, std::make_pair(*I, L)); } else { - // If this is already in the BBMap then this means that we already added - // a loop for it, but incorrectly added the loop to a higher level loop - // instead of the current loop we are creating. Fix this now by moving - // the loop into the correct subloop. + // If this is already in the BBMap then this means that we already + // added a loop for it, but incorrectly added the loop to a higher + // level loop instead of the current loop we are creating. Fix this + // now by moving the loop into the correct subloop. // Loop *SubLoop = BBMI->second; Loop *OldSubLoopParent = SubLoop->getParentLoop(); From lattner at cs.uiuc.edu Wed Feb 19 18:29:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 19 18:29:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200302200028.SAA19952@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.28 -> 1.29 --- Log message: Fix the requisite bug that I introduced --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.28 llvm/lib/Analysis/LoopInfo.cpp:1.29 --- llvm/lib/Analysis/LoopInfo.cpp:1.28 Wed Feb 19 18:18:07 2003 +++ llvm/lib/Analysis/LoopInfo.cpp Wed Feb 19 18:28:00 2003 @@ -155,17 +155,19 @@ // now by moving the loop into the correct subloop. // Loop *SubLoop = BBMI->second; - Loop *OldSubLoopParent = SubLoop->getParentLoop(); - if (OldSubLoopParent != L) { - // Remove SubLoop from OldSubLoopParent's list of subloops... - std::vector::iterator I = - std::find(OldSubLoopParent->SubLoops.begin(), - OldSubLoopParent->SubLoops.end(), SubLoop); - assert(I != OldSubLoopParent->SubLoops.end() - && "Loop parent doesn't contain loop?"); - OldSubLoopParent->SubLoops.erase(I); - SubLoop->ParentLoop = L; - L->SubLoops.push_back(SubLoop); + if (SubLoop->getHeader() == *I) { // Only do this once for the loop... + Loop *OldSubLoopParent = SubLoop->getParentLoop(); + if (OldSubLoopParent != L) { + // Remove SubLoop from OldSubLoopParent's list of subloops... + std::vector::iterator I = + std::find(OldSubLoopParent->SubLoops.begin(), + OldSubLoopParent->SubLoops.end(), SubLoop); + assert(I != OldSubLoopParent->SubLoops.end() + && "Loop parent doesn't contain loop?"); + OldSubLoopParent->SubLoops.erase(I); + SubLoop->ParentLoop = L; + L->SubLoops.push_back(SubLoop); + } } } } From lattner at cs.uiuc.edu Sat Feb 22 15:34:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 22 15:34:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200302222133.PAA28190@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.29 -> 1.30 --- Log message: Dramatically simplify building of natural loops and fix a bug where the BBMap was not correctly computed. --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.29 llvm/lib/Analysis/LoopInfo.cpp:1.30 --- llvm/lib/Analysis/LoopInfo.cpp:1.29 Wed Feb 19 18:28:00 2003 +++ llvm/lib/Analysis/LoopInfo.cpp Sat Feb 22 15:33:11 2003 @@ -60,6 +60,7 @@ getSubLoops()[i]->print(OS); } + //===----------------------------------------------------------------------===// // LoopInfo implementation // @@ -101,6 +102,12 @@ void LoopInfo::print(std::ostream &OS) const { for (unsigned i = 0; i < TopLevelLoops.size(); ++i) TopLevelLoops[i]->print(OS); +#if 0 + for (std::map::const_iterator I = BBMap.begin(), + E = BBMap.end(); I != E; ++I) + OS << "BB '" << I->first->getName() << "' level = " + << I->second->LoopDepth << "\n"; +#endif } Loop *LoopInfo::ConsiderForLoop(BasicBlock *BB, const DominatorSet &DS) { @@ -132,45 +139,24 @@ } } + // If there are any loops nested within this loop, create them now! + for (std::vector::iterator I = L->Blocks.begin(), + E = L->Blocks.end(); I != E; ++I) + if (Loop *NewLoop = ConsiderForLoop(*I, DS)) { + L->SubLoops.push_back(NewLoop); + NewLoop->ParentLoop = L; + } + + // Add the basic blocks that comprise this loop to the BBMap so that this - // loop can be found for them. Also check subsidary basic blocks to see if - // they start subloops of their own. + // loop can be found for them. // - for (std::vector::reverse_iterator I = L->Blocks.rbegin(), - E = L->Blocks.rend(); I != E; ++I) - - // Check to see if this block starts a new loop - if (*I != BB) - if (Loop *NewLoop = ConsiderForLoop(*I, DS)) { - L->SubLoops.push_back(NewLoop); - NewLoop->ParentLoop = L; - } else { - std::map::iterator BBMI = BBMap.lower_bound(*I); - if (BBMI == BBMap.end() || BBMI->first != *I) { // Not in map yet... - BBMap.insert(BBMI, std::make_pair(*I, L)); - } else { - // If this is already in the BBMap then this means that we already - // added a loop for it, but incorrectly added the loop to a higher - // level loop instead of the current loop we are creating. Fix this - // now by moving the loop into the correct subloop. - // - Loop *SubLoop = BBMI->second; - if (SubLoop->getHeader() == *I) { // Only do this once for the loop... - Loop *OldSubLoopParent = SubLoop->getParentLoop(); - if (OldSubLoopParent != L) { - // Remove SubLoop from OldSubLoopParent's list of subloops... - std::vector::iterator I = - std::find(OldSubLoopParent->SubLoops.begin(), - OldSubLoopParent->SubLoops.end(), SubLoop); - assert(I != OldSubLoopParent->SubLoops.end() - && "Loop parent doesn't contain loop?"); - OldSubLoopParent->SubLoops.erase(I); - SubLoop->ParentLoop = L; - L->SubLoops.push_back(SubLoop); - } - } - } - } + for (std::vector::iterator I = L->Blocks.begin(), + E = L->Blocks.end(); I != E; ++I) { + std::map::iterator BBMI = BBMap.lower_bound(*I); + if (BBMI == BBMap.end() || BBMI->first != *I) // Not in map yet... + BBMap.insert(BBMI, std::make_pair(*I, L)); // Must be at this level + } return L; } From lattner at cs.uiuc.edu Sat Feb 22 16:21:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 22 16:21:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LICM/scalar_promote.ll Message-ID: <200302222220.QAA29061@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LICM: scalar_promote.ll added (r1.1) --- Log message: New testcase to check to see if LICM is performing scalar promotion --- Diffs of the changes: From lattner at cs.uiuc.edu Sat Feb 22 16:26:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 22 16:26:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <200302222225.QAA29124@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: PromoteMemoryToRegister.cpp updated: 1.33 -> 1.34 --- Log message: Clean up std namespace references --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp diff -u llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.33 llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.34 --- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.33 Mon Oct 21 15:00:26 2002 +++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Sat Feb 22 16:25:17 2003 @@ -13,7 +13,9 @@ // Currently this just loops over all alloca instructions, looking for // instructions that are only used in simple load and stores. // -// After this, the code is transformed by...something magical :) +// After this, the code is transformed by looping over all of the alloca +// instruction, calculating dominator frontiers, then inserting phi-nodes +// following the usual SSA construction algorithm. // //===----------------------------------------------------------------------===// @@ -27,23 +29,20 @@ #include "llvm/Type.h" #include "Support/Statistic.h" -using std::vector; -using std::map; -using std::set; - namespace { Statistic<> NumPromoted("mem2reg", "Number of alloca's promoted"); struct PromotePass : public FunctionPass { - vector Allocas; // the alloca instruction.. - map AllocaLookup; // reverse mapping of above + std::vector Allocas; // the alloca instruction.. + std::map AllocaLookup; // reverse mapping of above - vector > PhiNodes; // index corresponds to Allocas + std::vector > PhiNodes;// Idx corresponds 2 Allocas // List of instructions to remove at end of pass - vector KillList; + std::vector KillList; - map > NewPhiNodes; // the PhiNodes we're adding + std::map > NewPhiNodes; // the PhiNodes we're adding public: // runOnFunction - To run this pass, first we calculate the alloca @@ -59,8 +58,9 @@ } private: - void Traverse(BasicBlock *BB, BasicBlock *Pred, vector &IncVals, - set &Visited); + void RenamePass(BasicBlock *BB, BasicBlock *Pred, + std::vector &IncVals, + std::set &Visited); bool QueuePhiNode(BasicBlock *BB, unsigned AllocaIdx); void FindSafeAllocas(Function &F); }; @@ -95,7 +95,7 @@ BasicBlock &BB = F.getEntryNode(); // Get the entry node for the function // Look at all instructions in the entry node - for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) + for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) if (AllocaInst *AI = dyn_cast(&*I)) // Is it an alloca? if (isSafeAlloca(AI)) { // If safe alloca, add alloca to safe list AllocaLookup[AI] = Allocas.size(); // Keep reverse mapping @@ -118,7 +118,7 @@ // Calculate the set of write-locations for each alloca. This is analogous to // counting the number of 'redefinitions' of each variable. - vector > WriteSets; // index corresponds to Allocas + std::vector > WriteSets;// Idx corresponds to Allocas WriteSets.resize(Allocas.size()); for (unsigned i = 0; i != Allocas.size(); ++i) { AllocaInst *AI = Allocas[i]; @@ -159,15 +159,15 @@ // the alloca's. We do this in case there is a load of a value that has not // been stored yet. In this case, it will get this null value. // - vector Values(Allocas.size()); + std::vector Values(Allocas.size()); for (unsigned i = 0, e = Allocas.size(); i != e; ++i) Values[i] = Constant::getNullValue(Allocas[i]->getAllocatedType()); // Walks all basic blocks in the function performing the SSA rename algorithm // and inserting the phi nodes we marked as necessary // - set Visited; // The basic blocks we've already visited - Traverse(F.begin(), 0, Values, Visited); + std::set Visited; // The basic blocks we've already visited + RenamePass(F.begin(), 0, Values, Visited); // Remove all instructions marked by being placed in the KillList... // @@ -194,7 +194,7 @@ // bool PromotePass::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo) { // Look up the basic-block in question - vector &BBPNs = NewPhiNodes[BB]; + std::vector &BBPNs = NewPhiNodes[BB]; if (BBPNs.empty()) BBPNs.resize(Allocas.size()); // If the BB already has a phi node added for the i'th alloca then we're done! @@ -210,12 +210,12 @@ return true; } -void PromotePass::Traverse(BasicBlock *BB, BasicBlock *Pred, - vector &IncomingVals, - set &Visited) { +void PromotePass::RenamePass(BasicBlock *BB, BasicBlock *Pred, + std::vector &IncomingVals, + std::set &Visited) { // If this is a BB needing a phi node, lookup/create the phinode for each // variable we need phinodes for. - vector &BBPNs = NewPhiNodes[BB]; + std::vector &BBPNs = NewPhiNodes[BB]; for (unsigned k = 0; k != BBPNs.size(); ++k) if (PHINode *PN = BBPNs[k]) { // at this point we can assume that the array has phi nodes.. let's add @@ -237,10 +237,8 @@ Instruction *I = II; // get the instruction if (LoadInst *LI = dyn_cast(I)) { - Value *Ptr = LI->getPointerOperand(); - - if (AllocaInst *Src = dyn_cast(Ptr)) { - map::iterator AI = AllocaLookup.find(Src); + if (AllocaInst *Src = dyn_cast(LI->getPointerOperand())) { + std::map::iterator AI = AllocaLookup.find(Src); if (AI != AllocaLookup.end()) { Value *V = IncomingVals[AI->second]; @@ -250,11 +248,10 @@ } } } else if (StoreInst *SI = dyn_cast(I)) { - // delete this instruction and mark the name as the current holder of the + // Delete this instruction and mark the name as the current holder of the // value - Value *Ptr = SI->getPointerOperand(); - if (AllocaInst *Dest = dyn_cast(Ptr)) { - map::iterator ai = AllocaLookup.find(Dest); + if (AllocaInst *Dest = dyn_cast(SI->getPointerOperand())) { + std::map::iterator ai =AllocaLookup.find(Dest); if (ai != AllocaLookup.end()) { // what value were we writing? IncomingVals[ai->second] = SI->getOperand(0); @@ -265,8 +262,8 @@ } else if (TerminatorInst *TI = dyn_cast(I)) { // Recurse across our successors for (unsigned i = 0; i != TI->getNumSuccessors(); i++) { - vector OutgoingVals(IncomingVals); - Traverse(TI->getSuccessor(i), BB, OutgoingVals, Visited); + std::vector OutgoingVals(IncomingVals); + RenamePass(TI->getSuccessor(i), BB, OutgoingVals, Visited); } } } From lattner at cs.uiuc.edu Sat Feb 22 17:06:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 22 17:06:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h Message-ID: <200302222305.RAA29381@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: PromoteMemToReg.h added (r1.1) --- Log message: Add a new interface file for the PromoteMemToReg interface in the Utils library --- Diffs of the changes: From lattner at cs.uiuc.edu Sat Feb 22 17:58:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 22 17:58:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/Mem2Reg.cpp Message-ID: <200302222357.RAA30650@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: Mem2Reg.cpp added (r1.1) --- Log message: Split mem2reg promotion into two parts: a function which does the work, and a pass which wraps the function. This allows other passes to use the functionality --- Diffs of the changes: From lattner at cs.uiuc.edu Sat Feb 22 17:58:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 22 17:58:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <200302222357.RAA30659@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: PromoteMemoryToRegister.cpp updated: 1.34 -> 1.35 --- Log message: Split mem2reg promotion into two parts: a function which does the work, and a pass which wraps the function. This allows other passes to use the functionality --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp diff -u llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.34 llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.35 --- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.34 Sat Feb 22 16:25:17 2003 +++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Sat Feb 22 17:57:48 2003 @@ -1,7 +1,7 @@ //===- PromoteMemoryToRegister.cpp - Convert memory refs to regs ----------===// // -// This pass is used to promote memory references to be register references. A -// simple example of the transformation performed by this pass is: +// This file is used to promote memory references to be register references. A +// simple example of the transformation performed by this function is: // // FROM CODE TO CODE // %X = alloca int, uint 1 ret int 42 @@ -9,17 +9,14 @@ // %Y = load int* %X // ret int %Y // -// To do this transformation, a simple analysis is done to ensure it is safe. -// Currently this just loops over all alloca instructions, looking for -// instructions that are only used in simple load and stores. -// -// After this, the code is transformed by looping over all of the alloca -// instruction, calculating dominator frontiers, then inserting phi-nodes -// following the usual SSA construction algorithm. +// The code is transformed by looping over all of the alloca instruction, +// calculating dominator frontiers, then inserting phi-nodes following the usual +// SSA construction algorithm. This code does not modify the CFG of the +// function. // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/PromoteMemToReg.h" #include "llvm/Analysis/Dominators.h" #include "llvm/iMemory.h" #include "llvm/iPHINode.h" @@ -27,13 +24,31 @@ #include "llvm/Function.h" #include "llvm/Constant.h" #include "llvm/Type.h" -#include "Support/Statistic.h" + +/// isAllocaPromotable - Return true if this alloca is legal for promotion. +/// This is true if there are only loads and stores to the alloca... +/// +bool isAllocaPromotable(const AllocaInst *AI) { + // Only allow direct loads and stores... + for (Value::use_const_iterator UI = AI->use_begin(), UE = AI->use_end(); + UI != UE; ++UI) // Loop over all of the uses of the alloca + if (!isa(*UI)) + if (const StoreInst *SI = dyn_cast(*UI)) { + if (SI->getOperand(0) == AI) + return false; // Don't allow a store of the AI, only INTO the AI. + } else { + return false; // Not a load or store? + } + + return true; +} + namespace { - Statistic<> NumPromoted("mem2reg", "Number of alloca's promoted"); + struct PromoteMem2Reg { + const std::vector &Allocas; // the alloca instructions.. + DominanceFrontier &DF; - struct PromotePass : public FunctionPass { - std::vector Allocas; // the alloca instruction.. std::map AllocaLookup; // reverse mapping of above std::vector > PhiNodes;// Idx corresponds 2 Allocas @@ -45,72 +60,34 @@ std::vector > NewPhiNodes; // the PhiNodes we're adding public: - // runOnFunction - To run this pass, first we calculate the alloca - // instructions that are safe for promotion, then we promote each one. - // - virtual bool runOnFunction(Function &F); - - // getAnalysisUsage - We need dominance frontiers - // - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.setPreservesCFG(); - } + PromoteMem2Reg(const std::vector &A, DominanceFrontier &df) + :Allocas(A), DF(df) {} + + void run(); private: void RenamePass(BasicBlock *BB, BasicBlock *Pred, std::vector &IncVals, std::set &Visited); bool QueuePhiNode(BasicBlock *BB, unsigned AllocaIdx); - void FindSafeAllocas(Function &F); }; - - RegisterOpt X("mem2reg", "Promote Memory to Register"); } // end of anonymous namespace -// isSafeAlloca - This predicate controls what types of alloca instructions are -// allowed to be promoted... -// -static inline bool isSafeAlloca(const AllocaInst *AI) { - if (AI->isArrayAllocation()) return false; - - // Only allow direct loads and stores... - for (Value::use_const_iterator UI = AI->use_begin(), UE = AI->use_end(); - UI != UE; ++UI) // Loop over all of the uses of the alloca - if (!isa(*UI)) - if (const StoreInst *SI = dyn_cast(*UI)) { - if (SI->getOperand(0) == AI) - return false; // Don't allow a store of the AI, only INTO the AI. - } else { - return false; // Not a load or store? - } - - return true; -} - -// FindSafeAllocas - Find allocas that are safe to promote -// -void PromotePass::FindSafeAllocas(Function &F) { - BasicBlock &BB = F.getEntryNode(); // Get the entry node for the function - - // Look at all instructions in the entry node - for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) - if (AllocaInst *AI = dyn_cast(&*I)) // Is it an alloca? - if (isSafeAlloca(AI)) { // If safe alloca, add alloca to safe list - AllocaLookup[AI] = Allocas.size(); // Keep reverse mapping - Allocas.push_back(AI); - } -} - +void PromoteMem2Reg::run() { + // If there is nothing to do, bail out... + if (Allocas.empty()) return; + Function &F = *DF.getRoot()->getParent(); -bool PromotePass::runOnFunction(Function &F) { - // Calculate the set of safe allocas - FindSafeAllocas(F); + for (unsigned i = 0, e = Allocas.size(); i != e; ++i) { + assert(isAllocaPromotable(Allocas[i]) && + "Cannot promote non-promotable alloca!"); + assert(Allocas[i]->getParent()->getParent() == &F && + "All allocas should be in the same function, which is same as DF!"); + AllocaLookup[Allocas[i]] = i; + } - // If there is nothing to do, bail out... - if (Allocas.empty()) return false; // Add each alloca to the KillList. Note: KillList is destroyed MOST recently // added to least recently. @@ -128,9 +105,6 @@ WriteSets[i].push_back(SI->getParent()); } - // Get dominance frontier information... - DominanceFrontier &DF = getAnalysis(); - // Compute the locations where PhiNodes need to be inserted. Look at the // dominance frontier of EACH basic-block we have a write in // @@ -177,22 +151,13 @@ I->getParent()->getInstList().erase(I); } - - NumPromoted += Allocas.size(); - - // Purge data structurse so they are available the next iteration... - Allocas.clear(); - AllocaLookup.clear(); - PhiNodes.clear(); - NewPhiNodes.clear(); - return true; } // QueuePhiNode - queues a phi-node to be added to a basic-block for a specific // Alloca returns true if there wasn't already a phi-node for that variable // -bool PromotePass::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo) { +bool PromoteMem2Reg::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo) { // Look up the basic-block in question std::vector &BBPNs = NewPhiNodes[BB]; if (BBPNs.empty()) BBPNs.resize(Allocas.size()); @@ -210,7 +175,7 @@ return true; } -void PromotePass::RenamePass(BasicBlock *BB, BasicBlock *Pred, +void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred, std::vector &IncomingVals, std::set &Visited) { // If this is a BB needing a phi node, lookup/create the phinode for each @@ -269,9 +234,12 @@ } } - -// createPromoteMemoryToRegister - Provide an entry point to create this pass. -// -Pass *createPromoteMemoryToRegister() { - return new PromotePass(); +/// PromoteMemToReg - Promote the specified list of alloca instructions into +/// scalar registers, inserting PHI nodes as appropriate. This function makes +/// use of DominanceFrontier information. This function does not modify the CFG +/// of the function at all. All allocas must be from the same function. +/// +void PromoteMemToReg(const std::vector &Allocas, + DominanceFrontier &DF) { + PromoteMem2Reg(Allocas, DF).run(); } From lattner at cs.uiuc.edu Sun Feb 23 21:53:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 23 21:53:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LICM/scalar_promote.ll Message-ID: <200302240352.VAA02643@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LICM: scalar_promote.ll updated: 1.1 -> 1.2 --- Log message: New testcase for scalar promotion --- Diffs of the changes: Index: llvm/test/Regression/Transforms/LICM/scalar_promote.ll diff -u llvm/test/Regression/Transforms/LICM/scalar_promote.ll:1.1 llvm/test/Regression/Transforms/LICM/scalar_promote.ll:1.2 --- llvm/test/Regression/Transforms/LICM/scalar_promote.ll:1.1 Sat Feb 22 16:20:19 2003 +++ llvm/test/Regression/Transforms/LICM/scalar_promote.ll Sun Feb 23 21:52:04 2003 @@ -19,3 +19,18 @@ Out: ret void } + +void %testhard(int %i) { + br label %Loop +Loop: + %X1 = getelementptr int* %X, long 0 + %A = load int* %X1 ; Aliases X, needs to be rewritten + %V = add int %A, 1 + %X2 = getelementptr int* %X, long 0 + store int %V, int* %X2 + br bool false, label %Loop, label %Exit + +Exit: + ret void + +} From lattner at cs.uiuc.edu Sun Feb 23 21:53:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 23 21:53:03 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/BasicAA/licmtest.ll Message-ID: <200302240352.VAA02654@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/BasicAA: licmtest.ll updated: 1.2 -> 1.3 --- Log message: Tweak testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/BasicAA/licmtest.ll diff -u llvm/test/Regression/Transforms/BasicAA/licmtest.ll:1.2 llvm/test/Regression/Transforms/BasicAA/licmtest.ll:1.3 --- llvm/test/Regression/Transforms/BasicAA/licmtest.ll:1.2 Sat Sep 7 17:48:30 2002 +++ llvm/test/Regression/Transforms/BasicAA/licmtest.ll Sun Feb 23 21:52:13 2003 @@ -22,7 +22,8 @@ br bool %c, label %Out, label %Loop Out: - ret int 7 + %X = sub int %ToRemove, %Atmp + ret int %X Dummy: store int 7, int* %A From lattner at cs.uiuc.edu Sun Feb 23 21:53:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 23 21:53:04 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200302240352.VAA02663@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.20 -> 1.21 --- Log message: Initial implementation of Loop invariant memory->scalar promotion --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.20 llvm/lib/Transforms/Scalar/LICM.cpp:1.21 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.20 Mon Oct 21 15:00:26 2002 +++ llvm/lib/Transforms/Scalar/LICM.cpp Sun Feb 23 21:52:32 2003 @@ -1,27 +1,147 @@ //===-- LICM.cpp - Loop Invariant Code Motion Pass ------------------------===// // -// This pass is a simple loop invariant code motion pass. +// This pass is a simple loop invariant code motion pass. An interesting aspect +// of this pass is that it uses alias analysis for two purposes: +// +// 1. Moving loop invariant loads out of loops. If we can determine that a +// load inside of a loop never aliases anything stored to, we can hoist it +// like any other instruction. +// 2. Scalar Promotion of Memory - If there is a store instruction inside of +// the loop, we try to move the store to happen AFTER the loop instead of +// inside of the loop. This can only happen if a few conditions are true: +// A. The pointer stored through is loop invariant +// B. There are no stores or loads in the loop which _may_ alias the +// pointer. There are no calls in the loop which mod/ref the pointer. +// If these conditions are true, we can promote the loads and stores in the +// loop of the pointer to use a temporary alloca'd variable. We then use +// the mem2reg functionality to construct the appropriate SSA form for the +// variable. // //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/PromoteMemToReg.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/Dominators.h" -#include "llvm/iOperators.h" -#include "llvm/iMemory.h" +#include "llvm/Instructions.h" +#include "llvm/DerivedTypes.h" #include "llvm/Support/InstVisitor.h" -#include "Support/STLExtras.h" +#include "llvm/Support/CFG.h" #include "Support/Statistic.h" +#include "Support/CommandLine.h" #include "llvm/Assembly/Writer.h" #include -using std::string; namespace { + cl::opt DisablePromotion("disable-licm-promotion", cl::Hidden, + cl::desc("Disable memory promotion in LICM pass")); + Statistic<> NumHoisted("licm", "Number of instructions hoisted out of loop"); Statistic<> NumHoistedLoads("licm", "Number of load insts hoisted"); + Statistic<> NumPromoted("licm", "Number of memory locations promoted to registers"); + + /// LoopBodyInfo - We recursively traverse loops from most-deeply-nested to + /// least-deeply-nested. For all of the loops nested within the current one, + /// we keep track of information so that we don't have to repeat queries. + /// + struct LoopBodyInfo { + std::vector Calls; // Call instructions in loop + std::vector Invokes; // Invoke instructions in loop + + // StoredPointers - Targets of store instructions... + std::set StoredPointers; + + // LoadedPointers - Source pointers for load instructions... + std::set LoadedPointers; + + enum PointerClass { + PointerUnknown = 0, // Nothing is known about this pointer yet + PointerMustStore, // Memory is stored to ONLY through this pointer + PointerMayStore, // Memory is stored to through this or other pointers + PointerNoStore // Memory is not modified in this loop + }; + + // PointerIsModified - Keep track of information as we find out about it in + // the loop body... + // + std::map PointerIsModified; + + /// CantModifyAnyPointers - Return true if no memory modifying instructions + /// occur in this loop. This is just a conservative approximation, because + /// a call may not actually store anything. + bool CantModifyAnyPointers() const { + return Calls.empty() && Invokes.empty() && StoredPointers.empty(); + } + /// incorporate - Incorporate information about a subloop into the current + /// loop. + void incorporate(const LoopBodyInfo &OtherLBI); + void incorporate(BasicBlock &BB); // do the same for a basic block + + PointerClass getPointerInfo(Value *V, AliasAnalysis &AA) { + PointerClass &VInfo = PointerIsModified[V]; + if (VInfo == PointerUnknown) + VInfo = calculatePointerInfo(V, AA); + return VInfo; + } + private: + /// calculatePointerInfo - Calculate information about the specified + /// pointer. + PointerClass calculatePointerInfo(Value *V, AliasAnalysis &AA) const; + }; +} + +/// incorporate - Incorporate information about a subloop into the current loop. +void LoopBodyInfo::incorporate(const LoopBodyInfo &OtherLBI) { + // Do not incorporate NonModifiedPointers (which is just a cache) because it + // is too much trouble to make sure it's still valid. + Calls.insert (Calls.end(), OtherLBI.Calls.begin(), OtherLBI.Calls.end()); + Invokes.insert(Invokes.end(),OtherLBI.Invokes.begin(),OtherLBI.Invokes.end()); + StoredPointers.insert(OtherLBI.StoredPointers.begin(), + OtherLBI.StoredPointers.end()); + LoadedPointers.insert(OtherLBI.LoadedPointers.begin(), + OtherLBI.LoadedPointers.end()); +} + +void LoopBodyInfo::incorporate(BasicBlock &BB) { + for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) + if (CallInst *CI = dyn_cast(&*I)) + Calls.push_back(CI); + else if (StoreInst *SI = dyn_cast(&*I)) + StoredPointers.insert(SI->getOperand(1)); + else if (LoadInst *LI = dyn_cast(&*I)) + LoadedPointers.insert(LI->getOperand(0)); + + if (InvokeInst *II = dyn_cast(BB.getTerminator())) + Invokes.push_back(II); +} + + +// calculatePointerInfo - Calculate information about the specified pointer. +LoopBodyInfo::PointerClass LoopBodyInfo::calculatePointerInfo(Value *V, + AliasAnalysis &AA) const { + for (unsigned i = 0, e = Calls.size(); i != e; ++i) + if (AA.canCallModify(*Calls[i], V)) + return PointerMayStore; + + for (unsigned i = 0, e = Invokes.size(); i != e; ++i) + if (AA.canInvokeModify(*Invokes[i], V)) + return PointerMayStore; + + PointerClass Result = PointerNoStore; + for (std::set::const_iterator I = StoredPointers.begin(), + E = StoredPointers.end(); I != E; ++I) + if (AA.alias(V, *I)) + if (V == *I) + Result = PointerMustStore; // If this is the only alias, return must + else + return PointerMayStore; // We have to return may + return Result; +} + +namespace { struct LICM : public FunctionPass, public InstVisitor { virtual bool runOnFunction(Function &F); @@ -33,18 +153,21 @@ AU.addRequiredID(LoopPreheadersID); AU.addRequired(); AU.addRequired(); + AU.addRequired(); AU.addRequired(); } private: - Loop *CurLoop; // The current loop we are working on... - BasicBlock *Preheader; // The preheader block of the current loop... - bool Changed; // Set to true when we change anything. - AliasAnalysis *AA; // Currently AliasAnalysis information + LoopInfo *LI; // Current LoopInfo + AliasAnalysis *AA; // Current AliasAnalysis information + bool Changed; // Set to true when we change anything. + BasicBlock *Preheader; // The preheader block of the current loop... + Loop *CurLoop; // The current loop we are working on... + LoopBodyInfo *CurLBI; // Information about the current loop... /// visitLoop - Hoist expressions out of the specified loop... /// - void visitLoop(Loop *L); + void visitLoop(Loop *L, LoopBodyInfo &LBI); /// HoistRegion - Walk the specified region of the CFG (defined by all /// blocks dominated by the specified block, and that are in the current @@ -73,7 +196,10 @@ /// pointerInvalidatedByLoop - Return true if the body of this loop may /// store into the memory location pointed to by V. /// - bool pointerInvalidatedByLoop(Value *V); + bool pointerInvalidatedByLoop(Value *V) { + // Check to see if any of the basic blocks in CurLoop invalidate V. + return CurLBI->getPointerInfo(V, *AA) != LoopBodyInfo::PointerNoStore; + } /// isLoopInvariant - Return true if the specified value is loop invariant /// @@ -83,6 +209,22 @@ return true; // All non-instructions are loop invariant } + /// PromoteValuesInLoop - Look at the stores in the loop and promote as many + /// to scalars as we can. + /// + void PromoteValuesInLoop(); + + /// findPromotableValuesInLoop - Check the current loop for stores to + /// definate pointers, which are not loaded and stored through may aliases. + /// If these are found, create an alloca for the value, add it to the + /// PromotedValues list, and keep track of the mapping from value to + /// alloca... + /// + void findPromotableValuesInLoop( + std::vector > &PromotedValues, + std::map &Val2AlMap); + + /// Instruction visitation handlers... these basically control whether or /// not the specified instruction types are hoisted. /// @@ -116,35 +258,52 @@ /// function, hoisting expressions out of loops if possible. /// bool LICM::runOnFunction(Function &) { - // Get information about the top level loops in the function... - const std::vector &TopLevelLoops = - getAnalysis().getTopLevelLoops(); + Changed = false; - // Get our alias analysis information... + // Get our Loop and Alias Analysis information... + LI = &getAnalysis(); AA = &getAnalysis(); - // Traverse loops in postorder, hoisting expressions out of the deepest loops - // first. - // - Changed = false; - std::for_each(TopLevelLoops.begin(), TopLevelLoops.end(), - bind_obj(this, &LICM::visitLoop)); + // Hoist expressions out of all of the top-level loops. + const std::vector &TopLevelLoops = LI->getTopLevelLoops(); + for (std::vector::const_iterator I = TopLevelLoops.begin(), + E = TopLevelLoops.end(); I != E; ++I) { + LoopBodyInfo LBI; + LICM::visitLoop(*I, LBI); + } return Changed; } /// visitLoop - Hoist expressions out of the specified loop... /// -void LICM::visitLoop(Loop *L) { +void LICM::visitLoop(Loop *L, LoopBodyInfo &LBI) { // Recurse through all subloops before we process this loop... - std::for_each(L->getSubLoops().begin(), L->getSubLoops().end(), - bind_obj(this, &LICM::visitLoop)); + for (std::vector::const_iterator I = L->getSubLoops().begin(), + E = L->getSubLoops().end(); I != E; ++I) { + LoopBodyInfo SubLBI; + LICM::visitLoop(*I, SubLBI); + + // Incorporate information about the subloops into this loop... + LBI.incorporate(SubLBI); + } CurLoop = L; + CurLBI = &LBI; // Get the preheader block to move instructions into... Preheader = L->getLoopPreheader(); assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!"); + // Loop over the body of this loop, looking for calls, invokes, and stores. + // Because subloops have already been incorporated into LBI, we skip blocks in + // subloops. + // + const std::vector &LoopBBs = L->getBlocks(); + for (std::vector::const_iterator I = LoopBBs.begin(), + E = LoopBBs.end(); I != E; ++I) + if (LI->getLoopFor(*I) == L) // Ignore blocks in subloops... + LBI.incorporate(**I); // Incorporate the specified basic block + // We want to visit all of the instructions in this loop... that are not parts // of our subloops (they have already had their invariants hoisted out of // their loop, into this loop, so there is no need to process the BODIES of @@ -156,6 +315,11 @@ // HoistRegion(getAnalysis()[L->getHeader()]); + // Now that all loop invariants have been removed from the loop, promote any + // memory references to scalars that we can... + if (!DisablePromotion) + PromoteValuesInLoop(); + // Clear out loops state information for the next iteration CurLoop = 0; Preheader = 0; @@ -211,13 +375,144 @@ } } -/// pointerInvalidatedByLoop - Return true if the body of this loop may store -/// into the memory location pointed to by V. -/// -bool LICM::pointerInvalidatedByLoop(Value *V) { - // Check to see if any of the basic blocks in CurLoop invalidate V. - for (unsigned i = 0, e = CurLoop->getBlocks().size(); i != e; ++i) - if (AA->canBasicBlockModify(*CurLoop->getBlocks()[i], V)) - return true; - return false; +/// PromoteValuesInLoop - Try to promote memory values to scalars by sinking +/// stores out of the loop and moving loads to before the loop. We do this by +/// looping over the stores in the loop, looking for stores to Must pointers +/// which are loop invariant. We promote these memory locations to use allocas +/// instead. These allocas can easily be raised to register values by the +/// PromoteMem2Reg functionality. +/// +void LICM::PromoteValuesInLoop() { + // PromotedValues - List of values that are promoted out of the loop. Each + // value has an alloca instruction for it, and a cannonical version of the + // pointer. + std::vector > PromotedValues; + std::map ValueToAllocaMap; // Map of ptr to alloca + + findPromotableValuesInLoop(PromotedValues, ValueToAllocaMap); + if (ValueToAllocaMap.empty()) return; // If there are values to promote... + + Changed = true; + NumPromoted += PromotedValues.size(); + + // Emit a copy from the value into the alloca'd value in the loop preheader + TerminatorInst *LoopPredInst = Preheader->getTerminator(); + for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) { + // Load from the memory we are promoting... + LoadInst *LI = new LoadInst(PromotedValues[i].second, + PromotedValues[i].second->getName()+".promoted", + LoopPredInst); + // Store into the temporary alloca... + new StoreInst(LI, PromotedValues[i].first, LoopPredInst); + } + + // Scan the basic blocks in the loop, replacing uses of our pointers with + // uses of the allocas in question. If we find a branch that exits the + // loop, make sure to put reload code into all of the successors of the + // loop. + // + const std::vector &LoopBBs = CurLoop->getBlocks(); + for (std::vector::const_iterator I = LoopBBs.begin(), + E = LoopBBs.end(); I != E; ++I) { + // Rewrite all loads and stores in the block of the pointer... + for (BasicBlock::iterator II = (*I)->begin(), E = (*I)->end(); + II != E; ++II) { + if (LoadInst *L = dyn_cast(&*II)) { + std::map::iterator + I = ValueToAllocaMap.find(L->getOperand(0)); + if (I != ValueToAllocaMap.end()) + L->setOperand(0, I->second); // Rewrite load instruction... + } else if (StoreInst *S = dyn_cast(&*II)) { + std::map::iterator + I = ValueToAllocaMap.find(S->getOperand(1)); + if (I != ValueToAllocaMap.end()) + S->setOperand(1, I->second); // Rewrite store instruction... + } + } + + // Check to see if any successors of this block are outside of the loop. + // If so, we need to copy the value from the alloca back into the memory + // location... + // + for (succ_iterator SI = succ_begin(*I), SE = succ_end(*I); SI != SE; ++SI) + if (!CurLoop->contains(*SI)) { + // Copy all of the allocas into their memory locations... + Instruction *InsertPos = (*SI)->begin(); + for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) { + // Load from the alloca... + LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos); + // Store into the memory we promoted... + new StoreInst(LI, PromotedValues[i].second, InsertPos); + } + } + } + + // Now that we have done the deed, use the mem2reg functionality to promote + // all of the new allocas we just created into real SSA registers... + // + std::vector PromotedAllocas; + PromotedAllocas.reserve(PromotedValues.size()); + for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) + PromotedAllocas.push_back(PromotedValues[i].first); + PromoteMemToReg(PromotedAllocas, getAnalysis()); +} + +/// findPromotableValuesInLoop - Check the current loop for stores to definate +/// pointers, which are not loaded and stored through may aliases. If these are +/// found, create an alloca for the value, add it to the PromotedValues list, +/// and keep track of the mapping from value to alloca... +/// +void LICM::findPromotableValuesInLoop( + std::vector > &PromotedValues, + std::map &ValueToAllocaMap) { + Instruction *FnStart = CurLoop->getHeader()->getParent()->begin()->begin(); + + for (std::set::iterator I = CurLBI->StoredPointers.begin(), + E = CurLBI->StoredPointers.end(); I != E; ++I) { + Value *V = *I; + if (isLoopInvariant(V) && + CurLBI->getPointerInfo(V, *AA) == LoopBodyInfo::PointerMustStore) { + + // Don't add a new entry for this stored pointer if it aliases something + // we have already processed. + std::map::iterator V2AMI = + ValueToAllocaMap.lower_bound(V); + if (V2AMI == ValueToAllocaMap.end() || V2AMI->first != V) { + // Check to make sure that any loads in the loop are either NO or MUST + // aliases. We cannot rewrite loads that _might_ come from this memory + // location. + + bool PointerOk = true; + for (std::set::const_iterator I =CurLBI->LoadedPointers.begin(), + E = CurLBI->LoadedPointers.end(); I != E; ++I) + if (AA->alias(V, *I) == AliasAnalysis::MayAlias) { + PointerOk = false; + break; + } + + if (PointerOk) { + const Type *Ty = cast(V->getType())->getElementType(); + AllocaInst *AI = new AllocaInst(Ty, 0, V->getName()+".tmp", FnStart); + PromotedValues.push_back(std::make_pair(AI, V)); + ValueToAllocaMap.insert(V2AMI, std::make_pair(V, AI)); + + DEBUG(std::cerr << "LICM: Promoting value: " << *V << "\n"); + + // Loop over all of the loads and stores that alias this pointer, + // adding them to the Value2AllocaMap as well... + for (std::set::const_iterator + I = CurLBI->LoadedPointers.begin(), + E = CurLBI->LoadedPointers.end(); I != E; ++I) + if (AA->alias(V, *I) == AliasAnalysis::MustAlias) + ValueToAllocaMap[*I] = AI; + + for (std::set::const_iterator + I = CurLBI->StoredPointers.begin(), + E = CurLBI->StoredPointers.end(); I != E; ++I) + if (AA->alias(V, *I) == AliasAnalysis::MustAlias) + ValueToAllocaMap[*I] = AI; + } + } + } + } } From lattner at cs.uiuc.edu Sun Feb 23 22:32:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 23 22:32:01 2003 Subject: [llvm-commits] CVS: llvm/include/Support/slist Message-ID: <200302240431.WAA02833@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: slist added (r1.1) --- Log message: Add support for the slist extension --- Diffs of the changes: From lattner at cs.uiuc.edu Sun Feb 23 22:41:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 23 22:41:01 2003 Subject: [llvm-commits] CVS: llvm/include/Support/slist Message-ID: <200302240440.WAA02965@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: slist updated: 1.1 -> 1.2 --- Log message: Fix #endif --- Diffs of the changes: Index: llvm/include/Support/slist diff -u llvm/include/Support/slist:1.1 llvm/include/Support/slist:1.2 --- llvm/include/Support/slist:1.1 Sun Feb 23 22:31:49 2003 +++ llvm/include/Support/slist Sun Feb 23 22:40:35 2003 @@ -30,3 +30,5 @@ // GCC 2.x #include #endif + +#endif