From ashukla at cs.uiuc.edu Mon Oct 7 03:22:01 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Oct 7 03:22:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Trigger/Trigger.cpp Message-ID: <200210070821.DAA27029@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Trigger: Trigger.cpp updated: 1.11 -> 1.12 --- Log message: Corrected a delay slot problem --- Diffs of the changes: Index: llvm/lib/Reoptimizer/Trigger/Trigger.cpp diff -u llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.11 llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.12 --- llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.11 Sat Sep 21 00:04:26 2002 +++ llvm/lib/Reoptimizer/Trigger/Trigger.cpp Mon Oct 7 03:21:07 2002 @@ -274,17 +274,22 @@ //take the target of br2 and inverted condition of br1 unsigned int invertedBranch = vm->getInvertedBranch(br1); - //insert ds1, br2, ds2 in the trace (in that order) + //only handling the case when ds2 == nop! + + //insert br2, ds1 in the trace (in that order) //store branches and PCs for later correction in branchMap - trace.push_back(ds1); - instIndex++; + assert(ds2 == 0x01000000 && + "Can't handle the case when the unconditional branch doesn't have nop in delay slot!"); + + //trace.push_back(ds1); + //instIndex++; trace.push_back(invertedBranch); //branchMap[instIndex] = addrbr2; targetMap[instIndex] = getBranchTarget(br2, addrbr2); - trace.push_back(ds2); + trace.push_back(ds1); instIndex += 2; } else{ @@ -315,6 +320,12 @@ assert(tar2 == bbDest.first && "Last BB must point to first BB"); //remove br1: it ALWAYS goes to target! + //br1 + // trace.push_back(br1); + //targetMap[instIndex] = getBranchTarget(br1, addrbr1); + //instIndex++; + //br1 --end + trace.push_back(ds1); instIndex++; @@ -409,7 +420,7 @@ //save %io, ad1 unsigned int stx1 = 0xf077a000|0x7f7; //stx %i0, %fp+offset-8 - unsigned int stx2 = 0xf277a000|0x7ef; //stx %i1, offset-16 + unsigned int stx2 = 0xf277a000|0x7ef; //stx %i1, offset-16 //sethi uint64_t target = targetMap[MI->first]; From ashukla at cs.uiuc.edu Mon Oct 7 03:23:00 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Mon Oct 7 03:23:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Mapping/getLLVMinfo.cpp Message-ID: <200210070822.DAA27330@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Mapping: getLLVMinfo.cpp updated: 1.7 -> 1.8 --- Log message: Commented out debug info --- Diffs of the changes: Index: llvm/lib/Reoptimizer/Mapping/getLLVMinfo.cpp diff -u llvm/lib/Reoptimizer/Mapping/getLLVMinfo.cpp:1.7 llvm/lib/Reoptimizer/Mapping/getLLVMinfo.cpp:1.8 --- llvm/lib/Reoptimizer/Mapping/getLLVMinfo.cpp:1.7 Fri Sep 13 21:08:26 2002 +++ llvm/lib/Reoptimizer/Mapping/getLLVMinfo.cpp Mon Oct 7 03:22:36 2002 @@ -132,7 +132,7 @@ //std::cerr<<"got BBnoVec\n"; //unsigned *Fadd = (unsigned *)llvmFunctionTable[Fno]; uint64_t Fadd = (uint64_t)llvmFunctionTable[Fno]; - std::cerr<<"########### Function add:"<<(void *)Fadd<<"\n"; + //std::cerr<<"########### Function add:"<<(void *)Fadd<<"\n"; uint64_t BBstartAdd = Fadd + BBnoVec.first*4;//anand-- added *4 //std::cerr<<"added BBstartAdd: "< &MIList = MImapF[BasicBlockNo][LLVMInstrNo];//MImapF[FunctionNo][BasicBlockNo]; - std::cerr<<"************* BB#"<::iterator MI = MIList.begin(), ME = MIList.end(); - MI!=ME; ++MI) - std::cerr<<*MI<<"\n"; + //std::cerr<<"************* BB#"<::iterator MI = MIList.begin(), ME = MIList.end(); + // MI!=ME; ++MI) + //std::cerr<<*MI<<"\n"; return MIList; } @@ -232,22 +232,22 @@ assert(LIi < LIend && "Trying to read off the end of list of LMIMap"); unsigned BasicBlockNumber = readNumber(LIi); - std::cerr<<"BasicBlockNumber= "< > LImap; for(unsigned j=0; j oneLI; for(unsigned k=0; k Changes in directory llvm/include/llvm/Support: CFG.h updated: 1.5 -> 1.6 --- Log message: Implement operator= for SuccIterators --- Diffs of the changes: Index: llvm/include/llvm/Support/CFG.h diff -u llvm/include/llvm/Support/CFG.h:1.5 llvm/include/llvm/Support/CFG.h:1.6 --- llvm/include/llvm/Support/CFG.h:1.5 Wed Jul 24 17:08:45 2002 +++ llvm/include/llvm/Support/CFG.h Mon Oct 7 11:53:22 2002 @@ -100,6 +100,11 @@ : Term(T), idx(Term->getNumSuccessors()) { assert(T && "getTerminator returned null!"); } + + inline const _Self &operator=(const _Self &I) { + assert(Term == I.Term &&"Cannot assign iterators to two different blocks!"); + idx = I.idx; + } inline bool operator==(const _Self& x) const { return idx == x.idx; } inline bool operator!=(const _Self& x) const { return !operator==(x); } From lattner at cs.uiuc.edu Mon Oct 7 12:01:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 12:01:02 2002 Subject: [llvm-commits] CVS: llvm/test/combinations.ll Message-ID: <200210071700.MAA17155@apoc.cs.uiuc.edu> Changes in directory llvm/test: combinations.ll (r1.1) removed --- Log message: Remove really old testcase --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Oct 7 12:02:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 12:02:00 2002 Subject: [llvm-commits] CVS: llvm/test/sched.ll Message-ID: <200210071701.MAA17173@apoc.cs.uiuc.edu> Changes in directory llvm/test: sched.ll updated: 1.2 -> 1.3 --- Log message: Update testcase to be legal llvm --- Diffs of the changes: Index: llvm/test/sched.ll diff -u llvm/test/sched.ll:1.2 llvm/test/sched.ll:1.3 --- llvm/test/sched.ll:1.2 Wed Oct 3 09:50:12 2001 +++ llvm/test/sched.ll Mon Oct 7 12:00:53 2002 @@ -1,9 +1,8 @@ implementation declare int "printf"(sbyte*, int, float) - -int "testissue"(int %i, float %x, float %y) -begin +int %testissue(int %i, float %x, float %y) { + br label %bb1 bb1: %x1 = mul float %x, %y ;; x1 %y1 = mul float %y, 0.75 ;; y1 @@ -24,7 +23,6 @@ br bool %b, label %bb1, label %bb2 bb2: - %Msg = cast ulong 0 to sbyte * - call int %printf(sbyte* %Msg, int %m1, float %z3) + call int %printf(sbyte* null, int %m1, float %z3) ret int 0 end From lattner at cs.uiuc.edu Mon Oct 7 12:14:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 12:14:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/CFG.h Message-ID: <200210071713.MAA17541@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: CFG.h updated: 1.6 -> 1.7 --- Log message: Fix bug in last checkin --- Diffs of the changes: Index: llvm/include/llvm/Support/CFG.h diff -u llvm/include/llvm/Support/CFG.h:1.6 llvm/include/llvm/Support/CFG.h:1.7 --- llvm/include/llvm/Support/CFG.h:1.6 Mon Oct 7 11:53:22 2002 +++ llvm/include/llvm/Support/CFG.h Mon Oct 7 12:13:22 2002 @@ -104,6 +104,7 @@ inline const _Self &operator=(const _Self &I) { assert(Term == I.Term &&"Cannot assign iterators to two different blocks!"); idx = I.idx; + return *this; } inline bool operator==(const _Self& x) const { return idx == x.idx; } From lattner at cs.uiuc.edu Mon Oct 7 13:35:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 13:35:01 2002 Subject: [llvm-commits] CVS: llvm/tools/extract/extract.cpp Message-ID: <200210071834.NAA19272@apoc.cs.uiuc.edu> Changes in directory llvm/tools/extract: extract.cpp updated: 1.10 -> 1.11 --- Log message: Avoid making external global variables internal --- Diffs of the changes: Index: llvm/tools/extract/extract.cpp diff -u llvm/tools/extract/extract.cpp:1.10 llvm/tools/extract/extract.cpp:1.11 --- llvm/tools/extract/extract.cpp:1.10 Sun Oct 6 16:30:04 2002 +++ llvm/tools/extract/extract.cpp Mon Oct 7 13:33:53 2002 @@ -30,7 +30,8 @@ bool run(Module &M) { // Mark all global variables to be internal for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - I->setInternalLinkage(true); + if (!I->isExternal()) + I->setInternalLinkage(true); Function *Named = 0; From lattner at cs.uiuc.edu Mon Oct 7 13:35:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 13:35:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Internalize.cpp Message-ID: <200210071834.NAA19292@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: Internalize.cpp updated: 1.10 -> 1.11 --- Log message: Non-functionality change just to make it more clear what is going on --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/Internalize.cpp diff -u llvm/lib/Transforms/IPO/Internalize.cpp:1.10 llvm/lib/Transforms/IPO/Internalize.cpp:1.11 --- llvm/lib/Transforms/IPO/Internalize.cpp:1.10 Tue Oct 1 17:38:36 2002 +++ llvm/lib/Transforms/IPO/Internalize.cpp Mon Oct 7 13:34:32 2002 @@ -42,7 +42,7 @@ // Mark all global variables with initializers as internal as well... for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - if (I->hasInitializer() && I->hasExternalLinkage()) { + if (!I->isExternal() && I->hasExternalLinkage()) { I->setInternalLinkage(true); Changed = true; ++NumGlobals; From lattner at cs.uiuc.edu Mon Oct 7 13:38:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 13:38:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/DOTGraphTraits.h GraphWriter.h Message-ID: <200210071837.NAA19317@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: DOTGraphTraits.h added (r1.1) GraphWriter.h added (r1.1) --- Log message: - Allow printing generic LLVM graphs to 'dot' files, so they can be visualized easily. --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Oct 7 13:39:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 13:39:01 2002 Subject: [llvm-commits] CVS: llvm/tools/analyze/GraphPrinters.cpp Message-ID: <200210071838.NAA19330@apoc.cs.uiuc.edu> Changes in directory llvm/tools/analyze: GraphPrinters.cpp added (r1.1) --- Log message: - Implement a new -print-cfg option for analyze, that causes it to print the CFG of each function in the module to 'dot' files. --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Oct 7 15:06:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 15:06:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll Message-ID: <200210072005.PAA21262@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CorrelatedExprs: 2002-10-07-DominatorProblem.ll added (r1.1) --- Log message: Finally I'm able to distill a testcase for a problem I'm seeing! --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Oct 7 15:26:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 15:26:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll Message-ID: <200210072025.PAA21602@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CorrelatedExprs: 2002-10-07-DominatorProblem.ll updated: 1.1 -> 1.2 --- Log message: Fix testcase to run correctly, add description --- Diffs of the changes: Index: llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll diff -u llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll:1.1 llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll:1.2 --- llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll:1.1 Mon Oct 7 15:05:27 2002 +++ llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll Mon Oct 7 15:25:45 2002 @@ -1,4 +1,7 @@ - +; RUN: as < %s | opt -cee +; +; The 'cee' pass is breaking SSA form when it blindly forwards the branch from +; Eq to branch to "Forwarded" instead. implementation From lattner at cs.uiuc.edu Mon Oct 7 15:33:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 15:33:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-NoImmediateDominator.ll Message-ID: <200210072032.PAA21750@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CorrelatedExprs: 2002-10-07-NoImmediateDominator.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Oct 7 17:38:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Oct 7 17:38:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/GraphWriter.h Message-ID: <200210072237.RAA23246@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: GraphWriter.h updated: 1.1 -> 1.2 --- Log message: Don't rotate paper. --- Diffs of the changes: Index: llvm/include/Support/GraphWriter.h diff -u llvm/include/Support/GraphWriter.h:1.1 llvm/include/Support/GraphWriter.h:1.2 --- llvm/include/Support/GraphWriter.h:1.1 Mon Oct 7 13:37:10 2002 +++ llvm/include/Support/GraphWriter.h Mon Oct 7 17:37:03 2002 @@ -55,8 +55,7 @@ typedef typename GTraits::NodeType NodeType; O << "digraph foo {\n" // Graph name doesn't matter - << "\tsize=\"10,7.5\";\n" // Size to fit on a page - << "\trotate=\"90\";\n"; // Orient correctly + << "\tsize=\"7.5,10\";\n"; // Size to fit on a page std::string GraphName = DOTTraits::getGraphName(G); if (!GraphName.empty()) From hldnbrnd at cs.uiuc.edu Mon Oct 7 17:54:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Mon Oct 7 17:54:01 2002 Subject: [llvm-commits] CVS: llvm/utils/vim/ Message-ID: <200210072253.RAA12335@trinity.cs.uiuc.edu> Changes in directory llvm/utils/vim: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/utils/vim added to the repository --- Diffs of the changes: From hldnbrnd at cs.uiuc.edu Mon Oct 7 17:55:00 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Mon Oct 7 17:55:00 2002 Subject: [llvm-commits] CVS: llvm/utils/vim/llvm.vim Message-ID: <200210072254.RAA12349@trinity.cs.uiuc.edu> Changes in directory llvm/utils/vim: llvm.vim added (r1.1) --- Log message: LLVM syntax highlighting for VIM. --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Oct 8 11:10:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 11:10:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/or.ll Message-ID: <200210081609.LAA04142@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: or.ll updated: 1.5 -> 1.6 --- Log message: This test was mistakenly matching 'predecessors' that the new asmwriter spits out --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/or.ll diff -u llvm/test/Regression/Transforms/InstCombine/or.ll:1.5 llvm/test/Regression/Transforms/InstCombine/or.ll:1.6 --- llvm/test/Regression/Transforms/InstCombine/or.ll:1.5 Wed Aug 14 12:44:00 2002 +++ llvm/test/Regression/Transforms/InstCombine/or.ll Tue Oct 8 11:09:47 2002 @@ -1,7 +1,7 @@ ; This test makes sure that these instructions are properly eliminated. ; -; RUN: if as < %s | opt -instcombine | dis | grep or +; RUN: if as < %s | opt -instcombine | dis | grep or\ ; RUN: then exit 1 ; RUN: else exit 0 ; RUN: fi From lattner at cs.uiuc.edu Tue Oct 8 11:11:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 11:11:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/shift.ll Message-ID: <200210081610.LAA04186@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: shift.ll updated: 1.4 -> 1.5 --- Log message: Add new testcase for arithmetic shr of -1 --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/shift.ll diff -u llvm/test/Regression/Transforms/InstCombine/shift.ll:1.4 llvm/test/Regression/Transforms/InstCombine/shift.ll:1.5 --- llvm/test/Regression/Transforms/InstCombine/shift.ll:1.4 Tue Sep 10 18:03:10 2002 +++ llvm/test/Regression/Transforms/InstCombine/shift.ll Tue Oct 8 11:10:35 2002 @@ -37,3 +37,8 @@ %B = shl uint %A, ubyte 1 ;; convert to an add instruction ret uint %B } + +int %test7(ubyte %A) { + %B = shr int -1, ubyte %A ;; Always equal to -1 + ret int %B +} From lattner at cs.uiuc.edu Tue Oct 8 11:17:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 11:17:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200210081616.LAA04814@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.59 -> 1.60 --- Log message: Fold ashr -1, X into -1 --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.59 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.60 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.59 Tue Oct 1 17:38:41 2002 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Oct 8 11:16:40 2002 @@ -503,6 +503,12 @@ return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName()); } + + // shr int -1, X = -1 (for any arithmetic shift rights of ~0) + if (ConstantSInt *CSI = dyn_cast(Op0)) + if (I.getOpcode() == Instruction::Shr && CSI->isAllOnesValue()) + return ReplaceInstUsesWith(I, CSI); + return 0; } From ashukla at cs.uiuc.edu Tue Oct 8 11:30:01 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Tue Oct 8 11:30:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/Trigger/Trigger.cpp Message-ID: <200210081629.LAA15076@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/Trigger: Trigger.cpp updated: 1.12 -> 1.13 --- Log message: Added functions to time execution inside trace cache --- Diffs of the changes: Index: llvm/lib/Reoptimizer/Trigger/Trigger.cpp diff -u llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.12 llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.13 --- llvm/lib/Reoptimizer/Trigger/Trigger.cpp:1.12 Mon Oct 7 03:21:07 2002 +++ llvm/lib/Reoptimizer/Trigger/Trigger.cpp Tue Oct 8 11:29:48 2002 @@ -10,6 +10,7 @@ #include "llvm/Reoptimizer/TraceCache.h" #include "llvm/Reoptimizer/VirtualMem.h" #include "llvm/Reoptimizer/InstrUtils.h" +#include "llvm/Reoptimizer/GetTraceTime.h" #include "llvm/Reoptimizer/Mapping/LLVMinfo.h" #include "llvm/Bytecode/Reader.h" #include "llvm/Module.h" @@ -17,6 +18,10 @@ #include "llvm/Support/CFG.h" #include +#include +#include +#include + using std::vector; using std::map; @@ -24,11 +29,34 @@ extern const unsigned char LLVMBytecode[]; extern void** llvmFunctionTable[]; +#ifdef GET_TRACE_TIME + +static struct timeval llvm_trace_time; + +extern "C" void llvm_time_start(){ + gettimeofday(&llvm_trace_time, (void *)0); +} + +extern "C" void llvm_time_end(){ + static std::ofstream f_out("llvm_last_run"); + + struct timeval time_end; + gettimeofday(&time_end, (void *)0); + + long time = (time_end.tv_sec - llvm_trace_time.tv_sec)*1000000 + + (time_end.tv_usec - llvm_trace_time.tv_usec); + + f_out< &vBB, int pathNo, Function *M); void getBranchExitCode(vector &instVec, map &branchMap, - map &targetMap); + map &targetMap, + map &callMap); extern "C" void llvmInitializeCounter(int *cnt, int k){ for(int i=0; iaddTrace(startAddr, trace, pn, callMap, branchMap)) std::cerr<<"^^^^^^^^^^************** Trace could not be added!!!\n"; @@ -408,7 +438,8 @@ void getBranchExitCode(vector &instVec, map &branchMap, - map &targetMap){ + map &targetMap, + map &callMap){ //for each branch, insert code! int instIndex = instVec.size(); @@ -418,6 +449,18 @@ unsigned int instr = instVec[MI->first]; uint64_t pc = MI->second; +#ifdef GET_TRACE_TIME + instVec.push_back(0);//just dummy, so we can use its adress + + //call llvm_time_end + unsigned int call_inst = getCallInstr((uint64_t)&llvm_time_end, + (uint64_t)&instVec[instIndex]); + instVec[instIndex] = call_inst; + + callMap[instIndex] = (uint64_t)&instVec[instIndex]; + //end call_inst! +#endif + //save %io, ad1 unsigned int stx1 = 0xf077a000|0x7f7; //stx %i0, %fp+offset-8 unsigned int stx2 = 0xf277a000|0x7ef; //stx %i1, offset-16 @@ -475,5 +518,9 @@ branchMap[MI->first] = instIndex; instIndex += 11; + +#ifdef GET_TRACE_TIME + instIndex++; +#endif } } From ashukla at cs.uiuc.edu Tue Oct 8 11:31:00 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Tue Oct 8 11:31:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/VirtualMem.cpp Message-ID: <200210081630.LAA15094@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: VirtualMem.cpp updated: 1.4 -> 1.5 --- Log message: Added functions to time execution inside trace cache --- Diffs of the changes: Index: llvm/lib/Reoptimizer/TraceCache/VirtualMem.cpp diff -u llvm/lib/Reoptimizer/TraceCache/VirtualMem.cpp:1.4 llvm/lib/Reoptimizer/TraceCache/VirtualMem.cpp:1.5 --- llvm/lib/Reoptimizer/TraceCache/VirtualMem.cpp:1.4 Sat Sep 21 00:04:04 2002 +++ llvm/lib/Reoptimizer/TraceCache/VirtualMem.cpp Tue Oct 8 11:30:08 2002 @@ -92,10 +92,20 @@ //write branch inst, followed by a null inst in delay slot void VirtualMem::writeBranchInstruction(uint64_t location, uint64_t target){ - uint64_t instToWrite = getDepJumpInstr(0x10800000, target, location); + //uint64_t instToWrite = getDepJumpInstr(0x10800000, target, location); + unsigned int instToWrite = getDepJumpInstr(0x10800000, target, location); writeInstToVM(location, instToWrite); writeInstToVM(location+4, 0x01000000); } + +#ifdef GET_TRACE_TIME +//write call instruction to llvm_start_time, followed by nop +void VirtualMem::writeCallLLVMTime(uint64_t instAddr){ + unsigned int callInst = getCallInstr((uint64_t)&llvm_time_start, instAddr); + writeInstToVM(instAddr, callInst); + writeInstToVM(instAddr+4, 0x01000000); +} +#endif void VirtualMem::setBranches(std::map &branchMap, uint64_t startAddr){ From ashukla at cs.uiuc.edu Tue Oct 8 11:31:02 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Tue Oct 8 11:31:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp Message-ID: <200210081630.LAA15106@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: TraceCache.cpp updated: 1.7 -> 1.8 --- Log message: Added functions to time execution inside trace cache --- Diffs of the changes: Index: llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp diff -u llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp:1.7 llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp:1.8 --- llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp:1.7 Sat Sep 21 00:04:09 2002 +++ llvm/lib/Reoptimizer/TraceCache/TraceCache.cpp Tue Oct 8 11:30:13 2002 @@ -21,6 +21,7 @@ #include "llvm/Reoptimizer/TraceCache.h" #include "llvm/Reoptimizer/VirtualMem.h" #include "llvm/Reoptimizer/InstrUtils.h" +#include "llvm/Reoptimizer/GetTraceTime.h" #include #include #include @@ -103,16 +104,28 @@ //add instAddr to queue allocationOrder.push_back(instAddr); - //copy the first instruction of the trace in the original code + //copy the first few instructions of the trace in the original code //and write a jump instruction in its place - tracesFirstInstruction[instAddr] = - std::make_pair(vm->readInstrFrmVm(instAddr), - vm->readInstrFrmVm(instAddr+4)); + traceInstructions[instAddr].push_back(vm->readInstrFrmVm(instAddr)); + traceInstructions[instAddr].push_back(vm->readInstrFrmVm(instAddr+4)); + +#ifdef GET_TRACE_TIME + //two more: to accomodate call instruction and get time! + traceInstructions[instAddr].push_back(vm->readInstrFrmVm(instAddr+8)); + traceInstructions[instAddr].push_back(vm->readInstrFrmVm(instAddr+12)); + + //write call instruction! + vm->writeCallLLVMTime(instAddr); //Now write branch instruction with target as //traceStartAddr at the address instAddr - vm->writeBranchInstruction(instAddr, traceStartAddr); + vm->writeBranchInstruction(instAddr+8, traceStartAddr); +#endif +#ifndef GET_TRACE_TIME + vm->writeBranchInstruction(instAddr, traceStartAddr); +#endif + //now set correctly all branches vm->setBranches(branchMap, traceStartAddr); @@ -122,58 +135,13 @@ doFlush(traceStartAddr, traceStartAddr+4*sz); doFlush(instAddr, instAddr+4); - return true; -} -/* -bool TraceCache::addTrace(uint64_t instAddr, unsigned int trace[], - int sz, std::vector &inBranches, - std::vector > &outBranches, int traceUniqId){ - - //remove trace if its already there - if(hasTraceAddr(instAddr)) - removeTrace(instAddr); - - while(isLimitSet && currSize+sz>limit){ - if(currSize == 0) - return false; - - //erase first addr from queue - assert(allocationOrder.size()>0 && "No entries in trace!"); - uint64_t addr = allocationOrder.front(); - allocationOrder.pop_front(); - removeTrace(addr); - } - - uint64_t traceStartAddr = mm->getMemory(sz); - - if(traceStartAddr == 0) return false; //could not allocate space! - - //copy trace to the memory - vm->copyToVM(trace, traceStartAddr, sz); - - traces[instAddr] = traceStartAddr; - traceId[traceUniqId] = traceStartAddr; - reverseTraceId[instAddr] = traceUniqId; - traceSize[instAddr] = sz; - reverseMap[traceStartAddr] = instAddr; - currSize += sz; - - //add instAddr to queue - allocationOrder.push_back(instAddr); +#ifdef GET_TRACE_TIME + doFlush(instAddr+8, instAddr+12); +#endif - //copy the first instruction of the trace in the original code - //and write a jump instruction in its place - tracesFirstInstruction[instAddr] = - std::make_pair(vm->readInstrFrmVm(instAddr), - vm->readInstrFrmVm(instAddr+4)); - - //Now write branch instruction with target as - //traceStartAddr at the address instAddr - vm->writeBranchInstruction(instAddr, traceStartAddr); - return true; } -*/ + void TraceCache::removeTrace(uint64_t n){ //if no trace, do nothing if(traces.find(n) == traces.end()) @@ -182,12 +150,17 @@ uint64_t toRemove = traces[n]; //put back the original instruction at n - assert(tracesFirstInstruction.find(n) != tracesFirstInstruction.end() && + assert(traceInstructions.find(n) != traceInstructions.end() && "Starting instruction not found!"); - vm->writeInstToVM(n, tracesFirstInstruction[n].first); - vm->writeInstToVM(n+4, tracesFirstInstruction[n].second); + + int removeSize = traceInstructions[n].size(); + for(int i=0; i < removeSize; i++) + vm->writeInstToVM(n+4*i, (traceInstructions[n])[i]); + + //vm->writeInstToVM(n, tracesFirstInstruction[n].first); + //vm->writeInstToVM(n+4, tracesFirstInstruction[n].second); - doFlush(n, n+4); + doFlush(n, n+4*(removeSize-1)); //remove n from queue std::list::iterator LI = std::find(allocationOrder.begin(), @@ -206,88 +179,10 @@ traceSize.erase(n); reverseMap.erase(toRemove); - tracesFirstInstruction.erase(n); - -} - -#undef ANAND_TRACE_CACHE_TEST_CODE -#ifdef ANAND_TRACE_CACHE_TEST_CODE - -int f_trial(int a); - -int main(void){ - std::cerr<<"in main "< inBranches; - uint64_t inAddr = (uint64_t)&f_trial+30*k; - inBranches.push_back(inAddr); - std::cerr<<" Incoming add: "<<(void *)inAddr<<"\n"; - - std::vector > outBranches; - outBranches.push_back(std::make_pair((uint64_t)&f_trial+5*k, (uint64_t)&arr[2])); - outBranches.push_back(std::make_pair((uint64_t)&f_trial+10*k, (uint64_t)&arr[7])); - outBranches.push_back(std::make_pair((uint64_t)&f_trial+15*k, (uint64_t)&arr[12])); - outBranches.push_back(std::make_pair((uint64_t)&f_trial+22*k, (uint64_t)&arr[19])); - outBranches.push_back(std::make_pair((uint64_t)&f_trial+26*k, (uint64_t)&arr[23])); - outBranches.push_back(std::make_pair((uint64_t)&f_trial+30*k, (uint64_t)&arr[27])); - - uint64_t traceStartAddr = (uint64_t)&f_trial+k*3; - std::cerr<<(void *)(traceStartAddr)<<" address\n"; - //tr.addTrace((uint64_t)0x10002dbec, arr, 28, inBranches, outBranches, 3); - tr.addTrace(traceStartAddr, arr, 29, inBranches, outBranches, 3); - - int nn = f_trial(6); - std::cerr< Changes in directory llvm/lib/Reoptimizer/TraceCache: InstrUtils.cpp updated: 1.5 -> 1.6 --- Log message: Added functions to time execution inside trace cache --- Diffs of the changes: Index: llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp diff -u llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp:1.5 llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp:1.6 --- llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp:1.5 Sat Sep 21 00:03:55 2002 +++ llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp Tue Oct 8 11:30:21 2002 @@ -127,12 +127,16 @@ } unsigned int getCallInstr(uint64_t to , uint64_t pc){ - assert((((to-pc)/4)&(2^29-1) < 2^29) && "Can't fit call target!"); + if(to>pc) + assert((((to-pc)/4) < 2^29) && "Can't fit call target!"); + else + assert((((pc-to)/4) < 2^29) && "Can't fit call target!"); + unsigned int diff = (((to-pc)/4)&0x1fffffff); //unsigned int sgn = ((((to-pc)/4)&(2^61))>>32); unsigned int sgn=0; if(to Changes in directory llvm/include/llvm/Reoptimizer: GetTraceTime.h added (r1.1) --- Log message: Added functions to time execution inside trace cache --- Diffs of the changes: From ashukla at cs.uiuc.edu Tue Oct 8 11:32:02 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Tue Oct 8 11:32:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Reoptimizer/TraceCache.h Message-ID: <200210081631.LAA15145@trinity.cs.uiuc.edu> Changes in directory llvm/include/llvm/Reoptimizer: TraceCache.h updated: 1.4 -> 1.5 --- Log message: Added functions to time execution inside trace cache --- Diffs of the changes: Index: llvm/include/llvm/Reoptimizer/TraceCache.h diff -u llvm/include/llvm/Reoptimizer/TraceCache.h:1.4 llvm/include/llvm/Reoptimizer/TraceCache.h:1.5 --- llvm/include/llvm/Reoptimizer/TraceCache.h:1.4 Sat Sep 21 00:05:38 2002 +++ llvm/include/llvm/Reoptimizer/TraceCache.h Tue Oct 8 11:31:15 2002 @@ -22,8 +22,7 @@ std::map traceId; std::map reverseTraceId; - std::map > - tracesFirstInstruction; + std::map > traceInstructions; std::map reverseMap; //map frm trace addr to original addr From ashukla at cs.uiuc.edu Tue Oct 8 11:32:03 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Tue Oct 8 11:32:03 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Reoptimizer/VirtualMem.h Message-ID: <200210081631.LAA15154@trinity.cs.uiuc.edu> Changes in directory llvm/include/llvm/Reoptimizer: VirtualMem.h updated: 1.3 -> 1.4 --- Log message: Added functions to time execution inside trace cache --- Diffs of the changes: Index: llvm/include/llvm/Reoptimizer/VirtualMem.h diff -u llvm/include/llvm/Reoptimizer/VirtualMem.h:1.3 llvm/include/llvm/Reoptimizer/VirtualMem.h:1.4 --- llvm/include/llvm/Reoptimizer/VirtualMem.h:1.3 Sat Sep 21 00:05:43 2002 +++ llvm/include/llvm/Reoptimizer/VirtualMem.h Tue Oct 8 11:31:20 2002 @@ -17,6 +17,8 @@ #include #include +#include "llvm/Reoptimizer/GetTraceTime.h" + using std::cerr; class VirtualMem{ @@ -37,6 +39,10 @@ void writeInstToVM(uint64_t dest, unsigned int newInstr); void writeBranchInstruction(uint64_t location, uint64_t target); + +#ifdef GET_TRACE_TIME + void writeCallLLVMTime(uint64_t instAddr); +#endif void setBranches(std::map &branchMap, uint64_t startAddr); From ashukla at cs.uiuc.edu Tue Oct 8 11:55:01 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Tue Oct 8 11:55:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp Message-ID: <200210081654.LAA15392@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/TraceCache: InstrUtils.cpp updated: 1.6 -> 1.7 --- Log message: Some corrections --- Diffs of the changes: Index: llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp diff -u llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp:1.6 llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp:1.7 --- llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp:1.6 Tue Oct 8 11:30:21 2002 +++ llvm/lib/Reoptimizer/TraceCache/InstrUtils.cpp Tue Oct 8 11:54:03 2002 @@ -127,13 +127,14 @@ } unsigned int getCallInstr(uint64_t to , uint64_t pc){ + //check to-pc < 2^29 if(to>pc) - assert((((to-pc)/4) < 2^29) && "Can't fit call target!"); + assert((((to-pc)/4) < 536870912) && "Can't fit call target!"); else - assert((((pc-to)/4) < 2^29) && "Can't fit call target!"); + assert((((pc-to)/4) < 536870912) && "Can't fit call target!"); unsigned int diff = (((to-pc)/4)&0x1fffffff); - //unsigned int sgn = ((((to-pc)/4)&(2^61))>>32); + unsigned int sgn=0; if(to getBPRInstr(unsigned int b, uint64_t to, - uint64_t frm){ - - assert(isBPR(b) && "Not a predicated branch Inst!"); - - unsigned int cond = (b&(234881024))>>25;//b&(2^25+2^26+2^27) - assert(cond !=4 && cond!=0 && cond<8 && - "Incorrect cond codes for BPR Instruction!"); - - //forming branch! - //push frm by 4, because a cmp is to be inserted! - frm+=4; - uint64_t target = (to-frm)/4; - //target < 2^21 - assert((target&(0x7fffffffffffffff))<2097152 && "Target out of range!"); - - unsigned int inst = - ((target & (2097151))|((target&(0x8000000000000000))>>42)); - - inst = inst|(0x00800000);//skeleton filled in - - //fill in branch type - if(cond<4) - inst = inst|(cond<<25); - else - inst = inst|((cond+4)<<25); - - //form cmp instruction: SUBcc - unsigned int cmp = 0x80a02000; //skeleton - //fill in register! - cmp = cmp|(b&507904);//inst|(b&(2^18+2^17+2^16+2^15+2^14)) - - return std::make_pair(cmp, inst); -} -*/ bool isBranchInstr(unsigned int y){ return (((y & 0xc0000000) == 0) && (isBPR(y) || isNonDepJump(y) || isDepJump(y))); From lattner at cs.uiuc.edu Tue Oct 8 12:08:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 12:08:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200210081707.MAA05768@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.60 -> 1.61 --- Log message: It is illegal for PHI nodes to have zero values, delete the code to handle them --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.60 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.61 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.60 Tue Oct 8 11:16:40 2002 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Oct 8 12:07:39 2002 @@ -630,8 +630,6 @@ // Instruction *InstCombiner::visitPHINode(PHINode &PN) { // If the PHI node only has one incoming value, eliminate the PHI node... - if (PN.getNumIncomingValues() == 0) - return ReplaceInstUsesWith(PN, Constant::getNullValue(PN.getType())); if (PN.getNumIncomingValues() == 1) return ReplaceInstUsesWith(PN, PN.getIncomingValue(0)); From lattner at cs.uiuc.edu Tue Oct 8 14:12:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 14:12:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll Message-ID: <200210081911.OAA10313@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CorrelatedExprs: 2002-10-07-DominatorProblem.ll updated: 1.2 -> 1.3 --- Log message: Make test more interesting by adding dummy phi node --- Diffs of the changes: Index: llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll diff -u llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll:1.2 llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll:1.3 --- llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll:1.2 Mon Oct 7 15:25:45 2002 +++ llvm/test/Regression/Transforms/CorrelatedExprs/2002-10-07-DominatorProblem.ll Tue Oct 8 14:11:02 2002 @@ -19,7 +19,8 @@ br bool %c2, label %Forwarded, label %Bottom Forwarded: - call int %test(int 0, int %Z, bool true) + %Z2 = phi int [%Z, %Loop] + call int %test(int 0, int %Z2, bool true) br label %Bottom Bottom: From lattner at cs.uiuc.edu Tue Oct 8 14:12:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 14:12:03 2002 Subject: [llvm-commits] CVS: llvm/test/globaldce.ll Message-ID: <200210081911.OAA10324@apoc.cs.uiuc.edu> Changes in directory llvm/test: globaldce.ll updated: 1.1 -> 1.2 --- Log message: Cleanup testcase --- Diffs of the changes: Index: llvm/test/globaldce.ll diff -u llvm/test/globaldce.ll:1.1 llvm/test/globaldce.ll:1.2 --- llvm/test/globaldce.ll:1.1 Mon Nov 26 14:50:07 2001 +++ llvm/test/globaldce.ll Tue Oct 8 14:11:21 2002 @@ -2,13 +2,12 @@ implementation -internal int "deadfunc"() -begin +internal int "deadfunc"() { %val = load int * %var %val2 = call int %deadfunc() %val3 = add int %val, %val2 ret int %val3 -end +} int "main"(int %argc) ; TODO: , sbyte **argv, sbyte **envp) begin From lattner at cs.uiuc.edu Tue Oct 8 14:13:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 14:13:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200210081912.OAA10339@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.26 -> 1.27 --- Log message: Expose new "recalculate" method from dominatorset --- Diffs of the changes: Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.26 llvm/include/llvm/Analysis/Dominators.h:1.27 --- llvm/include/llvm/Analysis/Dominators.h:1.26 Sun Sep 29 16:37:08 2002 +++ llvm/include/llvm/Analysis/Dominators.h Tue Oct 8 14:12:05 2002 @@ -128,6 +128,11 @@ virtual bool runOnFunction(Function &F); + /// recalculate - This method may be called by external passes that modify the + /// CFG and then need dominator information recalculated. This method is + /// obviously really slow, so it should be avoided if at all possible. + void recalculate(); + // getAnalysisUsage - This simply provides a dominator set virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); From lattner at cs.uiuc.edu Tue Oct 8 14:13:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 14:13:02 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200210081912.OAA10346@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.41 -> 1.42 --- Log message: Expose new "recalculate" method from dominatorset --- Diffs of the changes: Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.41 llvm/lib/VMCore/Dominators.cpp:1.42 --- llvm/lib/VMCore/Dominators.cpp:1.41 Fri Oct 4 09:45:48 2002 +++ llvm/lib/VMCore/Dominators.cpp Tue Oct 8 14:12:08 2002 @@ -92,10 +92,15 @@ // specified function. // bool DominatorSet::runOnFunction(Function &F) { - Doms.clear(); // Reset from the last time we were run... Root = &F.getEntryNode(); assert(pred_begin(Root) == pred_end(Root) && "Root node has predecessors in function!"); + recalculate(); + return false; +} + +void DominatorSet::recalculate() { + Doms.clear(); // Reset from the last time we were run... // Calculate dominator sets for the reachable basic blocks... calculateDominatorsFromBlock(Root); @@ -106,11 +111,10 @@ // extra pass over the function, calculating dominator information for // unreachable blocks. // - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) + Function *F = Root->getParent(); + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) if (Doms[I].count(I) == 0) calculateDominatorsFromBlock(I); - - return false; } From lattner at cs.uiuc.edu Tue Oct 8 16:07:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:07:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Scalar.h Message-ID: <200210082106.QAA14660@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: Scalar.h updated: 1.13 -> 1.14 --- Log message: Expose isCriticalEdge & SplitCriticalEdge methods from crit-edges pass --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.13 llvm/include/llvm/Transforms/Scalar.h:1.14 --- llvm/include/llvm/Transforms/Scalar.h:1.13 Thu Sep 26 11:17:33 2002 +++ llvm/include/llvm/Transforms/Scalar.h Tue Oct 8 16:06:24 2002 @@ -11,6 +11,7 @@ class Pass; class GetElementPtrInst; class PassInfo; +class TerminatorInst; //===----------------------------------------------------------------------===// // @@ -188,6 +189,21 @@ Pass *createBreakCriticalEdgesPass(); extern const PassInfo *BreakCriticalEdgesID; +// The BreakCriticalEdges pass also exposes some low-level functionality that +// may be used by other passes. + +/// isCriticalEdge - Return true if the specified edge is a critical edge. +/// Critical edges are edges from a block with multiple successors to a block +/// with multiple predecessors. +/// +bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum); + +/// SplitCriticalEdge - Insert a new node node to split the critical edge. This +/// will update DominatorSet, ImmediateDominator and DominatorTree information +/// if a pass is specified, thus calling this pass will not invalidate these +/// analyses. +/// +void SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P = 0); //===----------------------------------------------------------------------===// // From lattner at cs.uiuc.edu Tue Oct 8 16:07:06 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:07:06 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Message-ID: <200210082106.QAA14667@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: BreakCriticalEdges.cpp updated: 1.5 -> 1.6 --- Log message: Expose isCriticalEdge & SplitCriticalEdge methods from crit-edges pass --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp diff -u llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.5 llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.6 --- llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.5 Tue Oct 1 17:38:40 2002 +++ llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Tue Oct 8 16:06:27 2002 @@ -28,8 +28,6 @@ AU.addPreserved(); AU.addPreservedID(LoopPreheadersID); // No preheaders deleted. } - private: - void SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum); }; RegisterOpt X("break-crit-edges", @@ -45,9 +43,9 @@ // Critical edges are edges from a block with multiple successors to a block // with multiple predecessors. // -static bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum) { +bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum) { assert(SuccNum < TI->getNumSuccessors() && "Illegal edge specification!"); - assert (TI->getNumSuccessors() > 1); + if (TI->getNumSuccessors() == 1) return false; const BasicBlock *Dest = TI->getSuccessor(SuccNum); pred_const_iterator I = pred_begin(Dest), E = pred_end(Dest); @@ -62,7 +60,7 @@ // will update DominatorSet, ImmediateDominator and DominatorTree information if // it is available, thus calling this pass will not invalidate either of them. // -void BreakCriticalEdges::SplitCriticalEdge(TerminatorInst *TI,unsigned SuccNum){ +void SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P) { assert(isCriticalEdge(TI, SuccNum) && "Cannot break a critical edge, if it isn't a critical edge"); BasicBlock *TIBB = TI->getParent(); @@ -90,12 +88,15 @@ PN->replaceUsesOfWith(TIBB, NewBB); } + // If we don't have a pass object, we can't update anything... + if (P == 0) return; + // Now update analysis information. These are the analyses that we are // currently capable of updating... // // Should we update DominatorSet information? - if (DominatorSet *DS = getAnalysisToUpdate()) { + if (DominatorSet *DS = P->getAnalysisToUpdate()) { // The blocks that dominate the new one are the blocks that dominate TIBB // plus the new block itself. DominatorSet::DomSetType DomSet = DS->getDominators(TIBB); @@ -104,14 +105,14 @@ } // Should we update ImmdediateDominator information? - if (ImmediateDominators *ID = getAnalysisToUpdate()) { + if (ImmediateDominators *ID = P->getAnalysisToUpdate()) { // TIBB is the new immediate dominator for NewBB. NewBB doesn't dominate // anything. ID->addNewBlock(NewBB, TIBB); } // Should we update DominatorTree information? - if (DominatorTree *DT = getAnalysisToUpdate()) { + if (DominatorTree *DT = P->getAnalysisToUpdate()) { DominatorTree::Node *TINode = DT->getNode(TIBB); // The new block is not the immediate dominator for any other nodes, but @@ -131,7 +132,7 @@ if (TI->getNumSuccessors() > 1) for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) if (isCriticalEdge(TI, i)) { - SplitCriticalEdge(TI, i); + SplitCriticalEdge(TI, i, this); ++NumBroken; Changed = true; } From lattner at cs.uiuc.edu Tue Oct 8 16:33:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:33:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/iPHINode.h Message-ID: <200210082132.QAA17363@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: iPHINode.h updated: 1.5 -> 1.6 --- Log message: By default PHINode::removeIncomingValue will delete the phi node if the last incoming value is deleted! --- Diffs of the changes: Index: llvm/include/llvm/iPHINode.h diff -u llvm/include/llvm/iPHINode.h:1.5 llvm/include/llvm/iPHINode.h:1.6 --- llvm/include/llvm/iPHINode.h:1.5 Mon Sep 16 11:06:12 2002 +++ llvm/include/llvm/iPHINode.h Tue Oct 8 16:31:56 2002 @@ -65,7 +65,14 @@ /// removeIncomingValue - Remove an incoming value. This is useful if a /// predecessor basic block is deleted. The value removed is returned. - Value *removeIncomingValue(const BasicBlock *BB); + /// + /// If the last incoming value for a PHI node is removed (and DeletePHIIfEmpty + /// is true), the PHI node is destroyed and any uses of it are replaced with + /// dummy values. The only time there should be zero incoming values to a PHI + /// node is when the block is dead, so this strategy is sound. + /// + Value *removeIncomingValue(const BasicBlock *BB, + bool DeletePHIIfEmpty = true); /// getBasicBlockIndex - Return the first index of the specified basic /// block in the value list for this PHI. Returns -1 if no instance. From lattner at cs.uiuc.edu Tue Oct 8 16:35:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:35:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp Message-ID: <200210082134.QAA17375@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: CorrelatedExprs.cpp updated: 1.5 -> 1.6 --- Log message: - Checkin LARGE number of Changes to CEE pass that will make it much more powerful, but that are largely disabled. The basic idea here is that it is trying to forward branches across basic blocks that have PHI nodes in it, which are crucial to be able to handle cases like whet.ll. Unfortunately we are not updating SSA correctly, causing sim.c to die, and I don't have time to fix the regression now, so I must disable the functionality. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp diff -u llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.5 llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.6 --- llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.5 Tue Oct 1 17:38:40 2002 +++ llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp Tue Oct 8 16:34:15 2002 @@ -167,6 +167,9 @@ // this region. BasicBlock *getEntryBlock() const { return BB; } + // empty - return true if this region has no information known about it. + bool empty() const { return ValueMap.empty(); } + const RegionInfo &operator=(const RegionInfo &RI) { ValueMap = RI.ValueMap; return *this; @@ -174,6 +177,7 @@ // print - Output information about this region... void print(std::ostream &OS) const; + void dump() const; // Allow external access. typedef ValueMapTy::iterator iterator; @@ -191,6 +195,13 @@ if (I != ValueMap.end()) return &I->second; return 0; } + + /// removeValueInfo - Remove anything known about V from our records. This + /// works whether or not we know anything about V. + /// + void removeValueInfo(Value *V) { + ValueMap.erase(V); + } }; /// CEE - Correlated Expression Elimination @@ -231,7 +242,18 @@ bool TransformRegion(BasicBlock *BB, std::set &VisitedBlocks); - BasicBlock *isCorrelatedBranchBlock(BasicBlock *BB, RegionInfo &RI); + bool ForwardCorrelatedEdgeDestination(TerminatorInst *TI, unsigned SuccNo, + RegionInfo &RI); + + void ForwardSuccessorTo(TerminatorInst *TI, unsigned Succ, BasicBlock *D, + RegionInfo &RI); + void ReplaceUsesOfValueInRegion(Value *Orig, Value *New, + BasicBlock *RegionDominator); + void CalculateRegionExitBlocks(BasicBlock *BB, BasicBlock *OldSucc, + std::vector &RegionExitBlocks); + void InsertRegionExitMerges(PHINode *NewPHI, Instruction *OldVal, + const std::vector &RegionExitBlocks); + void PropogateBranchInfo(BranchInst *BI); void PropogateEquality(Value *Op0, Value *Op1, RegionInfo &RI); void PropogateRelation(Instruction::BinaryOps Opcode, Value *Op0, @@ -313,12 +335,13 @@ // information down now. // DominatorTree::Node *BBN = (*DT)[BB]; - for (unsigned i = 0, e = BBN->getChildren().size(); i != e; ++i) { - BasicBlock *Dominated = BBN->getChildren()[i]->getNode(); - assert(RegionInfoMap.find(Dominated) == RegionInfoMap.end() && - "RegionInfo should be calculated in dominanace order!"); - getRegionInfo(Dominated) = RI; - } + if (!RI.empty()) // Time opt: only propogate if we can change something + for (unsigned i = 0, e = BBN->getChildren().size(); i != e; ++i) { + BasicBlock *Dominated = BBN->getChildren()[i]->getNode(); + assert(RegionInfoMap.find(Dominated) == RegionInfoMap.end() && + "RegionInfo should be calculated in dominanace order!"); + getRegionInfo(Dominated) = RI; + } // Now that all of our successors have information if they deserve it, // propogate any information our terminator instruction finds to our @@ -332,25 +355,7 @@ // region, then vector this outgoing edge directly to the known destination. // for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) - while (BasicBlock *Dest = isCorrelatedBranchBlock(TI->getSuccessor(i), RI)){ - // If there are any PHI nodes in the Dest BB, we must duplicate the entry - // in the PHI node for the old successor to now include an entry from the - // current basic block. - // - BasicBlock *OldSucc = TI->getSuccessor(i); - - // Loop over all of the PHI nodes... - for (BasicBlock::iterator I = Dest->begin(); - PHINode *PN = dyn_cast(&*I); ++I) { - // Find the entry in the PHI node for OldSucc, create a duplicate entry - // for BB now. - int BlockIndex = PN->getBasicBlockIndex(OldSucc); - assert(BlockIndex != -1 && "Block should have entry in PHI!"); - PN->addIncoming(PN->getIncomingValue(BlockIndex), BB); - } - - // Actually revector the branch now... - TI->setSuccessor(i, Dest); + while (ForwardCorrelatedEdgeDestination(TI, i, RI)) { ++BranchRevectors; Changed = true; } @@ -362,37 +367,374 @@ return Changed; } -// If this block is a simple block not in the current region, which contains -// only a conditional branch, we determine if the outcome of the branch can be -// determined from information inside of the region. Instead of going to this -// block, we can instead go to the destination we know is the right target. +// isBlockSimpleEnoughForCheck to see if the block is simple enough for us to +// revector the conditional branch in the bottom of the block, do so now. // -BasicBlock *CEE::isCorrelatedBranchBlock(BasicBlock *BB, RegionInfo &RI) { +static bool isBlockSimpleEnough(BasicBlock *BB) { + assert(isa(BB->getTerminator())); + BranchInst *BI = cast(BB->getTerminator()); + assert(BI->isConditional()); + + // Check the common case first: empty block, or block with just a setcc. + if (BB->size() == 1 || + (BB->size() == 2 && &BB->front() == BI->getCondition() && + BI->getCondition()->use_size() == 1)) + return true; + + // Check the more complex case now... + BasicBlock::iterator I = BB->begin(); + + // FIXME: This should be reenabled once the regression with SIM is fixed! +#if 0 + // PHI Nodes are ok, just skip over them... + while (isa(*I)) ++I; +#endif + + // Accept the setcc instruction... + if (&*I == BI->getCondition()) + ++I; + + // Nothing else is acceptable here yet. We must not revector... unless we are + // at the terminator instruction. + if (&*I == BI) + return true; + + return false; +} + + +bool CEE::ForwardCorrelatedEdgeDestination(TerminatorInst *TI, unsigned SuccNo, + RegionInfo &RI) { + // If this successor is a simple block not in the current region, which + // contains only a conditional branch, we decide if the outcome of the branch + // can be determined from information inside of the region. Instead of going + // to this block, we can instead go to the destination we know is the right + // target. + // + // Check to see if we dominate the block. If so, this block will get the // condition turned to a constant anyway. // //if (DS->dominates(RI.getEntryBlock(), BB)) // return 0; - // Check to see if this is a conditional branch... - if (BranchInst *BI = dyn_cast(BB->getTerminator())) - if (BI->isConditional()) { - // Make sure that the block is either empty, or only contains a setcc. - if (BB->size() == 1 || - (BB->size() == 2 && &BB->front() == BI->getCondition() && - BI->getCondition()->use_size() == 1)) - if (SetCondInst *SCI = dyn_cast(BI->getCondition())) { - Relation::KnownResult Result = getSetCCResult(SCI, RI); - - if (Result == Relation::KnownTrue) - return BI->getSuccessor(0); - else if (Result == Relation::KnownFalse) - return BI->getSuccessor(1); - } + BasicBlock *BB = TI->getParent(); + + // Get the destination block of this edge... + BasicBlock *OldSucc = TI->getSuccessor(SuccNo); + + // Make sure that the block ends with a conditional branch and is simple + // enough for use to be able to revector over. + BranchInst *BI = dyn_cast(OldSucc->getTerminator()); + if (BI == 0 || !BI->isConditional() || !isBlockSimpleEnough(OldSucc)) + return false; + + // We can only forward the branch over the block if the block ends with a + // setcc we can determine the outcome for. + // + // FIXME: we can make this more generic. Code below already handles more + // generic case. + SetCondInst *SCI = dyn_cast(BI->getCondition()); + if (SCI == 0) return false; + + // Make a new RegionInfo structure so that we can simulate the effect of the + // PHI nodes in the block we are skipping over... + // + RegionInfo NewRI(RI); + + // Remove value information for all of the values we are simulating... to make + // sure we don't have any stale information. + for (BasicBlock::iterator I = OldSucc->begin(), E = OldSucc->end(); I!=E; ++I) + if (I->getType() != Type::VoidTy) + NewRI.removeValueInfo(I); + + // Put the newly discovered information into the RegionInfo... + for (BasicBlock::iterator I = OldSucc->begin(), E = OldSucc->end(); I!=E; ++I) + if (PHINode *PN = dyn_cast(&*I)) { + int OpNum = PN->getBasicBlockIndex(BB); + assert(OpNum != -1 && "PHI doesn't have incoming edge for predecessor!?"); + PropogateEquality(PN, PN->getIncomingValue(OpNum), NewRI); + } else if (SetCondInst *SCI = dyn_cast(&*I)) { + Relation::KnownResult Res = getSetCCResult(SCI, NewRI); + if (Res == Relation::Unknown) return false; + PropogateEquality(SCI, ConstantBool::get(Res), NewRI); + } else { + assert(isa(*I) && "Unexpected instruction type!"); + } + + // Compute the facts implied by what we have discovered... + ComputeReplacements(NewRI); + + ValueInfo &PredicateVI = NewRI.getValueInfo(BI->getCondition()); + if (PredicateVI.getReplacement() && + isa(PredicateVI.getReplacement())) { + ConstantBool *CB = cast(PredicateVI.getReplacement()); + + // Forward to the successor that corresponds to the branch we will take. + ForwardSuccessorTo(TI, SuccNo, BI->getSuccessor(!CB->getValue()), NewRI); + return true; + } + + return false; +} + +static Value *getReplacementOrValue(Value *V, RegionInfo &RI) { + if (const ValueInfo *VI = RI.requestValueInfo(V)) + if (Value *Repl = VI->getReplacement()) + return Repl; + return V; +} + +/// ForwardSuccessorTo - We have found that we can forward successor # 'SuccNo' +/// of Terminator 'TI' to the 'Dest' BasicBlock. This method performs the +/// mechanics of updating SSA information and revectoring the branch. +/// +void CEE::ForwardSuccessorTo(TerminatorInst *TI, unsigned SuccNo, + BasicBlock *Dest, RegionInfo &RI) { + // If there are any PHI nodes in the Dest BB, we must duplicate the entry + // in the PHI node for the old successor to now include an entry from the + // current basic block. + // + BasicBlock *OldSucc = TI->getSuccessor(SuccNo); + BasicBlock *BB = TI->getParent(); + + DEBUG(std::cerr << "Forwarding branch in basic block %" << BB->getName() + << " from block %" << OldSucc->getName() << " to block %" + << Dest->getName() << "\n"); + + DEBUG(std::cerr << "Before forwarding: " << *BB->getParent()); + + // Because we know that there cannot be critical edges in the flow graph, and + // that OldSucc has multiple outgoing edges, this means that Dest cannot have + // multiple incoming edges. + // +#ifndef NDEBUG + pred_iterator DPI = pred_begin(Dest); ++DPI; + assert(DPI == pred_end(Dest) && "Critical edge found!!"); +#endif + + // Loop over any PHI nodes in the destination, eliminating them, because they + // may only have one input. + // + while (PHINode *PN = dyn_cast(&Dest->front())) { + assert(PN->getNumIncomingValues() == 1 && "Crit edge found!"); + // Eliminate the PHI node + PN->replaceAllUsesWith(PN->getIncomingValue(0)); + Dest->getInstList().erase(PN); + } + + // If there are values defined in the "OldSucc" basic block, we need to insert + // PHI nodes in the regions we are dealing with to emulate them. This can + // insert dead phi nodes, but it is more trouble to see if they are used than + // to just blindly insert them. + // + if (DS->dominates(OldSucc, Dest)) { + // RegionExitBlocks - Find all of the blocks that are not dominated by Dest, + // but have predecessors that are. Additionally, prune down the set to only + // include blocks that are dominated by OldSucc as well. + // + std::vector RegionExitBlocks; + CalculateRegionExitBlocks(Dest, OldSucc, RegionExitBlocks); + + for (BasicBlock::iterator I = OldSucc->begin(), E = OldSucc->end(); + I != E; ++I) + if (I->getType() != Type::VoidTy) { + // Create and insert the PHI node into the top of Dest. + PHINode *NewPN = new PHINode(I->getType(), I->getName()+".fw_merge", + Dest->begin()); + // There is definately an edge from OldSucc... add the edge now + NewPN->addIncoming(I, OldSucc); + + // There is also an edge from BB now, add the edge with the calculated + // value from the RI. + NewPN->addIncoming(getReplacementOrValue(I, RI), BB); + + // Make everything in the Dest region use the new PHI node now... + ReplaceUsesOfValueInRegion(I, NewPN, Dest); + + // Make sure that exits out of the region dominated by NewPN get PHI + // nodes that merge the values as appropriate. + InsertRegionExitMerges(NewPN, I, RegionExitBlocks); + } + } + + // If there were PHI nodes in OldSucc, we need to remove the entry for this + // edge from the PHI node, and we need to replace any references to the PHI + // node with a new value. + // + for (BasicBlock::iterator I = OldSucc->begin(); + PHINode *PN = dyn_cast(&*I); ) { + + // Get the value flowing across the old edge and remove the PHI node entry + // for this edge: we are about to remove the edge! Don't remove the PHI + // node yet though if this is the last edge into it. + Value *EdgeValue = PN->removeIncomingValue(BB, false); + + // Make sure that anything that used to use PN now refers to EdgeValue + ReplaceUsesOfValueInRegion(PN, EdgeValue, Dest); + + // If there is only one value left coming into the PHI node, replace the PHI + // node itself with the one incoming value left. + // + if (PN->getNumIncomingValues() == 1) { + assert(PN->getNumIncomingValues() == 1); + PN->replaceAllUsesWith(PN->getIncomingValue(0)); + PN->getParent()->getInstList().erase(PN); + I = OldSucc->begin(); + } else if (PN->getNumIncomingValues() == 0) { // Nuke the PHI + // If we removed the last incoming value to this PHI, nuke the PHI node + // now. + PN->replaceAllUsesWith(Constant::getNullValue(PN->getType())); + PN->getParent()->getInstList().erase(PN); + I = OldSucc->begin(); + } else { + ++I; // Otherwise, move on to the next PHI node + } + } + + // Actually revector the branch now... + TI->setSuccessor(SuccNo, Dest); + + // If we just introduced a critical edge in the flow graph, make sure to break + // it right away... + if (isCriticalEdge(TI, SuccNo)) + SplitCriticalEdge(TI, SuccNo, this); + + // Make sure that we don't introduce critical edges from oldsucc now! + for (unsigned i = 0, e = OldSucc->getTerminator()->getNumSuccessors(); + i != e; ++i) + if (isCriticalEdge(OldSucc->getTerminator(), i)) + SplitCriticalEdge(OldSucc->getTerminator(), i, this); + + // Since we invalidated the CFG, recalculate the dominator set so that it is + // useful for later processing! + // FIXME: This is much worse than it really should be! + //DS->recalculate(); + + DEBUG(std::cerr << "After forwarding: " << *BB->getParent()); +} + +/// ReplaceUsesOfValueInRegion - This method replaces all uses of Orig with uses +/// of New. It only affects instructions that are defined in basic blocks that +/// are dominated by Head. +/// +void CEE::ReplaceUsesOfValueInRegion(Value *Orig, Value *New, + BasicBlock *RegionDominator) { + assert(Orig != New && "Cannot replace value with itself"); + std::vector InstsToChange; + std::vector PHIsToChange; + InstsToChange.reserve(Orig->use_size()); + + // Loop over instructions adding them to InstsToChange vector, this allows us + // an easy way to avoid invalidating the use_iterator at a bad time. + for (Value::use_iterator I = Orig->use_begin(), E = Orig->use_end(); + I != E; ++I) + if (Instruction *User = dyn_cast(*I)) + if (DS->dominates(RegionDominator, User->getParent())) + InstsToChange.push_back(User); + else if (PHINode *PN = dyn_cast(User)) { + PHIsToChange.push_back(PN); + } + + // PHIsToChange contains PHI nodes that use Orig that do not live in blocks + // dominated by orig. If the block the value flows in from is dominated by + // RegionDominator, then we rewrite the PHI + for (unsigned i = 0, e = PHIsToChange.size(); i != e; ++i) { + PHINode *PN = PHIsToChange[i]; + for (unsigned j = 0, e = PN->getNumIncomingValues(); j != e; ++j) + if (PN->getIncomingValue(j) == Orig && + DS->dominates(RegionDominator, PN->getIncomingBlock(j))) + PN->setIncomingValue(j, New); + } + + // Loop over the InstsToChange list, replacing all uses of Orig with uses of + // New. This list contains all of the instructions in our region that use + // Orig. + for (unsigned i = 0, e = InstsToChange.size(); i != e; ++i) + if (PHINode *PN = dyn_cast(InstsToChange[i])) { + // PHINodes must be handled carefully. If the PHI node itself is in the + // region, we have to make sure to only do the replacement for incoming + // values that correspond to basic blocks in the region. + for (unsigned j = 0, e = PN->getNumIncomingValues(); j != e; ++j) + if (PN->getIncomingValue(j) == Orig && + DS->dominates(RegionDominator, PN->getIncomingBlock(j))) + PN->setIncomingValue(j, New); + + } else { + InstsToChange[i]->replaceUsesOfWith(Orig, New); } - return 0; } +static void CalcRegionExitBlocks(BasicBlock *Header, BasicBlock *BB, + std::set &Visited, + DominatorSet &DS, + std::vector &RegionExitBlocks) { + if (Visited.count(BB)) return; + Visited.insert(BB); + + if (DS.dominates(Header, BB)) { // Block in the region, recursively traverse + for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) + CalcRegionExitBlocks(Header, *I, Visited, DS, RegionExitBlocks); + } else { + // Header does not dominate this block, but we have a predecessor that does + // dominate us. Add ourself to the list. + RegionExitBlocks.push_back(BB); + } +} + +/// CalculateRegionExitBlocks - Find all of the blocks that are not dominated by +/// BB, but have predecessors that are. Additionally, prune down the set to +/// only include blocks that are dominated by OldSucc as well. +/// +void CEE::CalculateRegionExitBlocks(BasicBlock *BB, BasicBlock *OldSucc, + std::vector &RegionExitBlocks){ + std::set Visited; // Don't infinite loop + + // Recursively calculate blocks we are interested in... + CalcRegionExitBlocks(BB, BB, Visited, *DS, RegionExitBlocks); + + // Filter out blocks that are not dominated by OldSucc... + for (unsigned i = 0; i != RegionExitBlocks.size(); ) { + if (DS->dominates(OldSucc, RegionExitBlocks[i])) + ++i; // Block is ok, keep it. + else { + // Move to end of list... + std::swap(RegionExitBlocks[i], RegionExitBlocks.back()); + RegionExitBlocks.pop_back(); // Nuke the end + } + } +} + +void CEE::InsertRegionExitMerges(PHINode *BBVal, Instruction *OldVal, + const std::vector &RegionExitBlocks) { + assert(BBVal->getType() == OldVal->getType() && "Should be derived values!"); + BasicBlock *BB = BBVal->getParent(); + BasicBlock *OldSucc = OldVal->getParent(); + + // Loop over all of the blocks we have to place PHIs in, doing it. + for (unsigned i = 0, e = RegionExitBlocks.size(); i != e; ++i) { + BasicBlock *FBlock = RegionExitBlocks[i]; // Block on the frontier + + // Create the new PHI node + PHINode *NewPN = new PHINode(BBVal->getType(), + OldVal->getName()+".fw_frontier", + FBlock->begin()); + + // Add an incoming value for every predecessor of the block... + for (pred_iterator PI = pred_begin(FBlock), PE = pred_end(FBlock); + PI != PE; ++PI) { + // If the incoming edge is from the region dominated by BB, use BBVal, + // otherwise use OldVal. + NewPN->addIncoming(DS->dominates(BB, *PI) ? BBVal : OldVal, *PI); + } + + // Now make everyone dominated by this block use this new value! + ReplaceUsesOfValueInRegion(OldVal, NewPN, FBlock); + } +} + + + // BuildRankMap - This method builds the rank map data structure which gives // each instruction/value in the function a value based on how early it appears // in the function. We give constants and globals rank 0, arguments are @@ -425,19 +767,16 @@ // void CEE::PropogateBranchInfo(BranchInst *BI) { assert(BI->isConditional() && "Must be a conditional branch!"); - BasicBlock *BB = BI->getParent(); - BasicBlock *TrueBB = BI->getSuccessor(0); - BasicBlock *FalseBB = BI->getSuccessor(1); // Propogate information into the true block... // PropogateEquality(BI->getCondition(), ConstantBool::True, - getRegionInfo(TrueBB)); + getRegionInfo(BI->getSuccessor(0))); // Propogate information into the false block... // PropogateEquality(BI->getCondition(), ConstantBool::False, - getRegionInfo(FalseBB)); + getRegionInfo(BI->getSuccessor(1))); } @@ -702,7 +1041,7 @@ } -// SimplifySetCC - Try to simplify a setcc instruction based on information +// getSetCCResult - Try to simplify a setcc instruction based on information // inherited from a dominating setcc instruction. V is one of the operands to // the setcc instruction, and VI is the set of information known about it. We // take two cases into consideration here. If the comparison is against a @@ -965,5 +1304,7 @@ OS << "\n"; } +// Don't inline these methods or else we won't be able to call them from GDB! void Relation::dump() const { print(std::cerr); } void ValueInfo::dump() const { print(std::cerr, 0); } +void RegionInfo::dump() const { print(std::cerr); } From lattner at cs.uiuc.edu Tue Oct 8 16:36:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:36:00 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/InstrTypes.cpp Message-ID: <200210082135.QAA17388@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: InstrTypes.cpp updated: 1.18 -> 1.19 --- Log message: - Change PHINode::removeIncomingValue to delete the phi node if the last incoming value is removed! --- Diffs of the changes: Index: llvm/lib/VMCore/InstrTypes.cpp diff -u llvm/lib/VMCore/InstrTypes.cpp:1.18 llvm/lib/VMCore/InstrTypes.cpp:1.19 --- llvm/lib/VMCore/InstrTypes.cpp:1.18 Tue Sep 10 10:45:53 2002 +++ llvm/lib/VMCore/InstrTypes.cpp Tue Oct 8 16:34:58 2002 @@ -8,6 +8,7 @@ #include "llvm/iPHINode.h" #include "llvm/Function.h" #include "llvm/SymbolTable.h" +#include "llvm/Constant.h" #include "llvm/Type.h" #include // find @@ -41,11 +42,19 @@ // removeIncomingValue - Remove an incoming value. This is useful if a // predecessor basic block is deleted. -Value *PHINode::removeIncomingValue(const BasicBlock *BB) { +Value *PHINode::removeIncomingValue(const BasicBlock *BB, + bool DeletePHIIfEmpty) { op_iterator Idx = find(Operands.begin(), Operands.end(), (const Value*)BB); assert(Idx != Operands.end() && "BB not in PHI node!"); --Idx; // Back up to value prior to Basic block Value *Removed = *Idx; Operands.erase(Idx, Idx+2); // Erase Value and BasicBlock + + // If the PHI node is dead, because it has zero entries, nuke it now. + if (getNumOperands() == 0 && DeletePHIIfEmpty) { + // If anyone is using this PHI, make them use a dummy value instead... + replaceAllUsesWith(Constant::getNullValue(getType())); + getParent()->getInstList().erase(this); + } return Removed; } From lattner at cs.uiuc.edu Tue Oct 8 16:37:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:37:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp Message-ID: <200210082136.QAA17422@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: ExprTypeConvert.cpp updated: 1.60 -> 1.61 --- Log message: Changes to support PHINode::removeIncoming changes --- Diffs of the changes: Index: llvm/lib/Transforms/ExprTypeConvert.cpp diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.60 llvm/lib/Transforms/ExprTypeConvert.cpp:1.61 --- llvm/lib/Transforms/ExprTypeConvert.cpp:1.60 Tue Oct 1 17:38:34 2002 +++ llvm/lib/Transforms/ExprTypeConvert.cpp Tue Oct 8 16:36:31 2002 @@ -392,7 +392,7 @@ BasicBlock *BB = OldPN->getIncomingBlock(0); Value *OldVal = OldPN->getIncomingValue(0); ValueHandle OldValHandle(VMC, OldVal); - OldPN->removeIncomingValue(BB); + OldPN->removeIncomingValue(BB, false); Value *V = ConvertExpressionToType(OldVal, Ty, VMC); NewPN->addIncoming(V, BB); } @@ -1097,7 +1097,7 @@ while (OldPN->getNumOperands()) { BasicBlock *BB = OldPN->getIncomingBlock(0); Value *OldVal = OldPN->getIncomingValue(0); - OldPN->removeIncomingValue(BB); + OldPN->removeIncomingValue(BB, false); Value *V = ConvertExpressionToType(OldVal, NewTy, VMC); NewPN->addIncoming(V, BB); } From lattner at cs.uiuc.edu Tue Oct 8 16:37:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:37:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200210082136.QAA17429@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: SimplifyCFG.cpp updated: 1.5 -> 1.6 --- Log message: Changes to support PHINode::removeIncoming changes --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp diff -u llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.5 llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.6 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.5 Tue Sep 24 11:09:17 2002 +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp Tue Oct 8 16:36:33 2002 @@ -1,13 +1,6 @@ //===- SimplifyCFG.cpp - Code to perform CFG simplification ---------------===// // -// SimplifyCFG - This function is used to do simplification of a CFG. For -// example, it adjusts branches to branches to eliminate the extra hop, it -// eliminates unreachable basic blocks, and does other "peephole" optimization -// of the CFG. It returns true if a modification was made, and returns an -// iterator that designates the first element remaining after the block that -// was deleted. -// -// WARNING: The entry node of a function may not be simplified. +// Peephole optimize the CFG. // //===----------------------------------------------------------------------===// @@ -48,7 +41,7 @@ // Loop over all of the PHI nodes in the successor BB for (BasicBlock::iterator I = Succ->begin(); PHINode *PN = dyn_cast(&*I); ++I) { - Value *OldVal = PN->removeIncomingValue(BB); + Value *OldVal = PN->removeIncomingValue(BB, false); assert(OldVal && "No entry in PHI for Pred BB!"); for (std::vector::const_iterator PredI = BBPreds.begin(), From lattner at cs.uiuc.edu Tue Oct 8 16:37:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:37:04 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/BasicBlock.cpp Message-ID: <200210082136.QAA17436@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: BasicBlock.cpp updated: 1.26 -> 1.27 --- Log message: Changes to support PHINode::removeIncoming changes --- Diffs of the changes: Index: llvm/lib/VMCore/BasicBlock.cpp diff -u llvm/lib/VMCore/BasicBlock.cpp:1.26 llvm/lib/VMCore/BasicBlock.cpp:1.27 --- llvm/lib/VMCore/BasicBlock.cpp:1.26 Thu Sep 26 00:03:22 2002 +++ llvm/lib/VMCore/BasicBlock.cpp Tue Oct 8 16:36:34 2002 @@ -183,16 +183,15 @@ // Yup, loop through and nuke the PHI nodes while (PHINode *PN = dyn_cast(&front())) { PN->removeIncomingValue(Pred); // Remove the predecessor first... - - assert(PN->getNumIncomingValues() == max_idx-1 && - "PHI node shouldn't have this many values!!!"); // If the PHI _HAD_ two uses, replace PHI node with its now *single* value - if (max_idx == 2) + if (max_idx == 2) { PN->replaceAllUsesWith(PN->getOperand(0)); - else // Otherwise there are no incoming values/edges, replace with dummy - PN->replaceAllUsesWith(Constant::getNullValue(PN->getType())); - getInstList().pop_front(); // Remove the PHI node + getInstList().pop_front(); // Remove the PHI node + } + + // If the PHI node already only had one entry, it got deleted by + // removeIncomingValue. } } else { // Okay, now we know that we need to remove predecessor #pred_idx from all From lattner at cs.uiuc.edu Tue Oct 8 16:55:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:55:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Message-ID: <200210082154.QAA18254@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: BreakCriticalEdges.cpp updated: 1.6 -> 1.7 --- Log message: - Fix bug: cee/2002-10-07-NoImmediateDominator.ll --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp diff -u llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.6 llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.7 --- llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.6 Tue Oct 8 16:06:27 2002 +++ llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Tue Oct 8 16:53:51 2002 @@ -118,7 +118,8 @@ // The new block is not the immediate dominator for any other nodes, but // TINode is the immediate dominator for the new node. // - DT->createNewNode(NewBB, TINode); + if (TINode) // Don't break unreachable code! + DT->createNewNode(NewBB, TINode); } } From lattner at cs.uiuc.edu Tue Oct 8 16:58:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 16:58:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LevelRaise/2002-10-08-VarArgCall.ll Message-ID: <200210082157.QAA18500@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LevelRaise: 2002-10-08-VarArgCall.ll added (r1.1) --- Log message: New testcase for bug that messes up the CWriter --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Oct 8 17:20:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 17:20:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/LevelRaise.cpp Message-ID: <200210082219.RAA19035@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: LevelRaise.cpp updated: 1.72 -> 1.73 --- Log message: - Fix bug: LevelRaise/2002-10-08-VarArgCall.ll --- Diffs of the changes: Index: llvm/lib/Transforms/LevelRaise.cpp diff -u llvm/lib/Transforms/LevelRaise.cpp:1.72 llvm/lib/Transforms/LevelRaise.cpp:1.73 --- llvm/lib/Transforms/LevelRaise.cpp:1.72 Tue Oct 1 17:38:34 2002 +++ llvm/lib/Transforms/LevelRaise.cpp Tue Oct 8 17:19:25 2002 @@ -45,6 +45,9 @@ static Statistic<> NumDCEorCP("raise", "Number of insts DCEd or constprop'd"); +static Statistic<> +NumVarargCallChanges("raise", "Number of vararg call peepholes"); + #define PRINT_PEEPHOLE(ID, NUM, I) \ DEBUG(std::cerr << "Inst P/H " << ID << "[" << NUM << "] " << I) @@ -253,7 +256,8 @@ // source type of the cast... // ConvertedTypes.clear(); - ConvertedTypes[Src] = Src->getType(); // Make sure the source doesn't change type + // Make sure the source doesn't change type + ConvertedTypes[Src] = Src->getType(); if (ValueConvertableToType(CI, Src->getType(), ConvertedTypes)) { PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", Src, CI, BB->getParent()); @@ -454,6 +458,40 @@ ++NumGEPInstFormed; return true; } + } else if (CallInst *CI = dyn_cast(I)) { + // If we have a call with all varargs arguments, convert the call to use the + // actual argument types present... + // + const PointerType *PTy = cast(CI->getCalledValue()->getType()); + const FunctionType *FTy = cast(PTy->getElementType()); + + // Is the call to a vararg variable with no real parameters? + if (FTy->isVarArg() && FTy->getNumParams() == 0) { + // If so, insert a new cast instruction, casting it to a function type + // that matches the current arguments... + // + std::vector Params; // Parameter types... + for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) + Params.push_back(CI->getOperand(i)->getType()); + + FunctionType *NewFT = FunctionType::get(FTy->getReturnType(), + Params, false); + PointerType *NewPFunTy = PointerType::get(NewFT); + + // Create a new cast, inserting it right before the function call... + CastInst *NewCast = new CastInst(CI->getCalledValue(), NewPFunTy, + CI->getCalledValue()->getName(), CI); + + // Create a new call instruction... + CallInst *NewCall = new CallInst(NewCast, + std::vector(CI->op_begin()+1, CI->op_end())); + ++BI; + ReplaceInstWithInst(CI, NewCall); + + ++NumVarargCallChanges; + return true; + } + } return false; From lattner at cs.uiuc.edu Tue Oct 8 17:36:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 17:36:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2002-10-08-LargeArrayPerformance.ll Message-ID: <200210082235.RAA19269@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2002-10-08-LargeArrayPerformance.ll added (r1.1) --- Log message: New testcase that the assembler is unacceptably slow on --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Oct 8 18:35:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 18:35:00 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200210082334.SAA20981@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.28 -> 1.29 --- Log message: Fix bug: Assembler/2002-10-08-LargeArrayPerformance.ll by using std::vector::reserve when possible --- Diffs of the changes: Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.28 llvm/lib/VMCore/Constants.cpp:1.29 --- llvm/lib/VMCore/Constants.cpp:1.28 Fri Sep 13 17:24:57 2002 +++ llvm/lib/VMCore/Constants.cpp Tue Oct 8 18:33:52 2002 @@ -191,7 +191,8 @@ ConstantArray::ConstantArray(const ArrayType *T, const std::vector &V) : Constant(T) { - for (unsigned i = 0; i < V.size(); i++) { + Operands.reserve(V.size()); + for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == T->getElementType()); Operands.push_back(Use(V[i], this)); } @@ -202,7 +203,8 @@ const StructType::ElementTypes &ETypes = T->getElementTypes(); assert(V.size() == ETypes.size() && "Invalid initializer vector for constant structure"); - for (unsigned i = 0; i < V.size(); i++) { + Operands.reserve(V.size()); + for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == ETypes[i]); Operands.push_back(Use(V[i], this)); } From lattner at cs.uiuc.edu Tue Oct 8 18:48:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 18:48:00 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Value.cpp Message-ID: <200210082347.SAA21146@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Value.cpp updated: 1.27 -> 1.28 --- Log message: Fix NASTY N^2 behavior that was causing the gzip benchmark to take forever to assemble. Now we scan the use-list from the back when removing users instead of from the front. --- Diffs of the changes: Index: llvm/lib/VMCore/Value.cpp diff -u llvm/lib/VMCore/Value.cpp:1.27 llvm/lib/VMCore/Value.cpp:1.28 --- llvm/lib/VMCore/Value.cpp:1.27 Sun Sep 8 13:59:35 2002 +++ llvm/lib/VMCore/Value.cpp Tue Oct 8 18:46:55 2002 @@ -77,12 +77,18 @@ Ty = NewTy; } -void Value::killUse(User *i) { - if (i == 0) return; - use_iterator I = find(Uses.begin(), Uses.end(), i); +void Value::killUse(User *U) { + if (U == 0) return; + unsigned i; - assert(I != Uses.end() && "Use not in uses list!!"); - Uses.erase(I); + // Scan backwards through the uses list looking for the user. We do this + // because vectors like to be accessed on the end. This is incredibly + // important from a performance perspective. + for (i = Uses.size()-1; Uses[i] != U; --i) + /* empty */; + + assert(i < Uses.size() && "Use not in uses list!!"); + Uses.erase(Uses.begin()+i); } User *Value::use_remove(use_iterator &I) { From lattner at cs.uiuc.edu Tue Oct 8 19:11:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 19:11:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LevelRaise/2002-10-08-VarArgCallInfLoop.ll Message-ID: <200210090010.TAA22663@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LevelRaise: 2002-10-08-VarArgCallInfLoop.ll added (r1.1) --- Log message: New testcase for infinite loop that the raise pass is getting into --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Oct 8 19:17:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 19:17:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp Message-ID: <200210090016.TAA23385@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: ExprTypeConvert.cpp updated: 1.61 -> 1.62 --- Log message: - Rename MTy to FTy (no methods exist anymore) - Fix bug: LevelRaise/2002-10-08-VarArgCallInfLoop.ll --- Diffs of the changes: Index: llvm/lib/Transforms/ExprTypeConvert.cpp diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.61 llvm/lib/Transforms/ExprTypeConvert.cpp:1.62 --- llvm/lib/Transforms/ExprTypeConvert.cpp:1.61 Tue Oct 8 16:36:31 2002 +++ llvm/lib/Transforms/ExprTypeConvert.cpp Tue Oct 8 19:16:00 2002 @@ -782,8 +782,12 @@ if (OpNum == 0) { const PointerType *PTy = dyn_cast(Ty); if (PTy == 0) return false; // Can't convert to a non-pointer type... - const FunctionType *MTy = dyn_cast(PTy->getElementType()); - if (MTy == 0) return false; // Can't convert to a non ptr to function... + const FunctionType *FTy = dyn_cast(PTy->getElementType()); + if (FTy == 0) return false; // Can't convert to a non ptr to function... + + // Do not allow converting to a call where all of the operands are ...'s + if (FTy->getNumParams() == 0 && FTy->isVarArg()) + return false; // Do not permit this conversion! // Perform sanity checks to make sure that new function type has the // correct number of arguments... @@ -793,12 +797,12 @@ // Cannot convert to a type that requires more fixed arguments than // the call provides... // - if (NumArgs < MTy->getParamTypes().size()) return false; + if (NumArgs < FTy->getNumParams()) return false; // Unless this is a vararg function type, we cannot provide more arguments // than are desired... // - if (!MTy->isVarArg() && NumArgs > MTy->getParamTypes().size()) + if (!FTy->isVarArg() && NumArgs > FTy->getNumParams()) return false; // Okay, at this point, we know that the call and the function type match @@ -808,7 +812,7 @@ // reason for this is that we prefer to have resolved functions but casted // arguments if possible. // - const FunctionType::ParamTypes &PTs = MTy->getParamTypes(); + const FunctionType::ParamTypes &PTs = FTy->getParamTypes(); for (unsigned i = 0, NA = PTs.size(); i < NA; ++i) if (!PTs[i]->isLosslesslyConvertableTo(I->getOperand(i+1)->getType())) return false; // Operands must have compatible types! @@ -817,14 +821,14 @@ // converted. We succeed if we can change the return type if // neccesary... // - return ValueConvertableToType(I, MTy->getReturnType(), CTMap); + return ValueConvertableToType(I, FTy->getReturnType(), CTMap); } const PointerType *MPtr = cast(I->getOperand(0)->getType()); - const FunctionType *MTy = cast(MPtr->getElementType()); - if (!MTy->isVarArg()) return false; + const FunctionType *FTy = cast(MPtr->getElementType()); + if (!FTy->isVarArg()) return false; - if ((OpNum-1) < MTy->getParamTypes().size()) + if ((OpNum-1) < FTy->getParamTypes().size()) return false; // It's not in the varargs section... // If we get this far, we know the value is in the varargs section of the From lattner at cs.uiuc.edu Tue Oct 8 19:26:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 19:26:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Value.h Message-ID: <200210090025.TAA24802@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Value.h updated: 1.37 -> 1.38 --- Log message: - Remove Value::use_push_back & Value::use_remove --- Diffs of the changes: Index: llvm/include/llvm/Value.h diff -u llvm/include/llvm/Value.h:1.37 llvm/include/llvm/Value.h:1.38 --- llvm/include/llvm/Value.h:1.37 Mon Sep 23 12:45:52 2002 +++ llvm/include/llvm/Value.h Tue Oct 8 19:25:01 2002 @@ -110,9 +110,8 @@ inline User *use_back() { return Uses.back(); } inline const User *use_back() const { return Uses.back(); } - inline void use_push_back(User *I) { Uses.push_back(I); } - User *use_remove(use_iterator &I); - + /// addUse/killUse - These two methods should only be used by the Use class + /// below. inline void addUse(User *I) { Uses.push_back(I); } void killUse(User *I); }; From lattner at cs.uiuc.edu Tue Oct 8 19:26:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 19:26:02 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Value.cpp Message-ID: <200210090025.TAA24809@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Value.cpp updated: 1.28 -> 1.29 --- Log message: - Remove Value::use_remove --- Diffs of the changes: Index: llvm/lib/VMCore/Value.cpp diff -u llvm/lib/VMCore/Value.cpp:1.28 llvm/lib/VMCore/Value.cpp:1.29 --- llvm/lib/VMCore/Value.cpp:1.28 Tue Oct 8 18:46:55 2002 +++ llvm/lib/VMCore/Value.cpp Tue Oct 8 19:25:05 2002 @@ -91,13 +91,6 @@ Uses.erase(Uses.begin()+i); } -User *Value::use_remove(use_iterator &I) { - assert(I != Uses.end() && "Trying to remove the end of the use list!!!"); - User *i = *I; - I = Uses.erase(I); - return i; -} - //===----------------------------------------------------------------------===// // User Class //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Tue Oct 8 19:26:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 19:26:04 2002 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200210090025.TAA24821@apoc.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.94 -> 1.95 --- Log message: Minor, non-functionality changing, formatting fix --- Diffs of the changes: Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.94 llvm/lib/AsmParser/llvmAsmParser.y:1.95 --- llvm/lib/AsmParser/llvmAsmParser.y:1.94 Sun Oct 6 17:45:09 2002 +++ llvm/lib/AsmParser/llvmAsmParser.y Tue Oct 8 19:25:32 2002 @@ -992,20 +992,20 @@ delete $1; }; -ConstVal : SIntType EINT64VAL { // integral constants +ConstVal : SIntType EINT64VAL { // integral constants if (!ConstantSInt::isValueValidForType($1, $2)) ThrowException("Constant value doesn't fit in type!"); $$ = ConstantSInt::get($1, $2); - } - | UIntType EUINT64VAL { // integral constants + } + | UIntType EUINT64VAL { // integral constants if (!ConstantUInt::isValueValidForType($1, $2)) ThrowException("Constant value doesn't fit in type!"); $$ = ConstantUInt::get($1, $2); - } - | BOOL TRUE { // Boolean constants + } + | BOOL TRUE { // Boolean constants $$ = ConstantBool::True; } - | BOOL FALSE { // Boolean constants + | BOOL FALSE { // Boolean constants $$ = ConstantBool::False; } | FPType FPVAL { // Float & Double constants From brukman at cs.uiuc.edu Tue Oct 8 19:30:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 8 19:30:00 2002 Subject: [llvm-commits] CVS: llvm/utils/emacs/ Message-ID: <200210090029.TAA24888@apoc.cs.uiuc.edu> Changes in directory llvm/utils/emacs: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/utils/emacs added to the repository --- Diffs of the changes: From brukman at cs.uiuc.edu Tue Oct 8 19:31:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Oct 8 19:31:01 2002 Subject: [llvm-commits] CVS: llvm/utils/emacs/llvm-mode.el Message-ID: <200210090030.TAA24904@apoc.cs.uiuc.edu> Changes in directory llvm/utils/emacs: llvm-mode.el added (r1.1) --- Log message: Added a major mode for Emacs to edit LLVM assembler code with syntax highlighting. --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Oct 8 19:43:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Oct 8 19:43:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Value.h Message-ID: <200210090042.TAA27369@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Value.h updated: 1.38 -> 1.39 --- Log message: - Detemplatize UseTy<> in Value.h, because it's only instantiated for one type! --- Diffs of the changes: Index: llvm/include/llvm/Value.h diff -u llvm/include/llvm/Value.h:1.38 llvm/include/llvm/Value.h:1.39 --- llvm/include/llvm/Value.h:1.38 Tue Oct 8 19:25:01 2002 +++ llvm/include/llvm/Value.h Tue Oct 8 19:42:03 2002 @@ -131,45 +131,42 @@ //===----------------------------------------------------------------------===// -// UseTy Class +// Use Class //===----------------------------------------------------------------------===// -// UseTy and it's friendly typedefs (Use) are here to make keeping the "use" -// list of a definition node up-to-date really easy. +// Use is here to make keeping the "use" list of a Value up-to-date really easy. // -template -class UseTy { - ValueSubclass *Val; +class Use { + Value *Val; User *U; public: - inline UseTy(ValueSubclass *v, User *user) { + inline Use(Value *v, User *user) { Val = v; U = user; if (Val) Val->addUse(U); } - inline ~UseTy() { if (Val) Val->killUse(U); } - - inline operator ValueSubclass *() const { return Val; } - - inline UseTy(const UseTy &user) { + inline Use(const Use &user) { Val = 0; U = user.U; operator=(user.Val); } - inline ValueSubclass *operator=(ValueSubclass *V) { + inline ~Use() { if (Val) Val->killUse(U); } + inline operator Value*() const { return Val; } + + inline Value *operator=(Value *V) { if (Val) Val->killUse(U); Val = V; if (V) V->addUse(U); return V; } - inline ValueSubclass *operator->() { return Val; } - inline const ValueSubclass *operator->() const { return Val; } + inline Value *operator->() { return Val; } + inline const Value *operator->() const { return Val; } - inline ValueSubclass *get() { return Val; } - inline const ValueSubclass *get() const { return Val; } + inline Value *get() { return Val; } + inline const Value *get() const { return Val; } - inline UseTy &operator=(const UseTy &user) { + inline const Use &operator=(const Use &user) { if (Val) Val->killUse(U); Val = user.Val; Val->addUse(U); @@ -177,19 +174,17 @@ } }; -typedef UseTy Use; // Provide Use as a common UseTy type - -template struct simplify_type > { - typedef typename simplify_type::SimpleType SimpleType; +template<> struct simplify_type { + typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const UseTy &Val) { + static SimpleType getSimplifiedValue(const Use &Val) { return (SimpleType)Val.get(); } }; -template struct simplify_type > { - typedef typename simplify_type::SimpleType SimpleType; +template<> struct simplify_type { + typedef Value* SimpleType; - static SimpleType getSimplifiedValue(const UseTy &Val) { + static SimpleType getSimplifiedValue(const Use &Val) { return (SimpleType)Val.get(); } }; From lattner at cs.uiuc.edu Wed Oct 9 11:49:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 11:49:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2002-10-09-ArrayResolution.c Message-ID: <200210091648.LAA31505@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/UnitTests: 2002-10-09-ArrayResolution.c added (r1.1) --- Log message: New testcase distilled from SPECINT gzip benchmark --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Oct 9 12:45:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 12:45:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll Message-ID: <200210091744.MAA04015@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/FunctionResolve: 2002-08-19-ResolveGlobalVars.ll updated: 1.1 -> 1.2 --- Log message: Cleanup testcase a lot to test JUST funcresolve of globals --- Diffs of the changes: Index: llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll diff -u llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll:1.1 llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll:1.2 --- llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll:1.1 Mon Aug 19 14:08:52 2002 +++ llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll Wed Oct 9 12:44:34 2002 @@ -1,25 +1,22 @@ -; Test that: extern int X[] and int X[] = { 1, 2, 3, 4 } are resolved correctly. +; Test that: extern int X[] and int X[] = { 1, 2, 3, 4 } are resolved +; correctly. ; -; RUN: if as < %s | opt -gcse -instcombine -constprop -dce | dis | grep getelementptr +; RUN: if as < %s | opt -funcresolve | dis | grep external ; RUN: then exit 1 ; RUN: else exit 0 ; RUN: fi ; -%X = uninitialized global int ; [#uses=1] -%X = global [4 x int] [ int 1, int 2, int 3, int 4 ] ; <[4 x int]*> [#uses=1] +%X = external global int +%X = global [4 x int] [ int 1, int 2, int 3, int 4 ] implementation ; Functions: int %foo(int %x) { bb1: ;[#uses=0] - %reg107-idxcast = cast int %x to uint ; [#uses=2] - %reg113 = getelementptr int* %X, uint %reg107-idxcast ; [#uses=1] - %reg120 = getelementptr [4 x int]* %X, uint 0, uint %reg107-idxcast ; [#uses=1] - %reg123 = sub int* %reg113, %reg120 ; [#uses=1] - %cast232 = cast int* %reg123 to long ; [#uses=1] - %reg234 = div long %cast232, 4 ; [#uses=1] - %cast108 = cast long %reg234 to int ; [#uses=1] - ret int %cast108 + store int 5, int* getelementptr (int* %X, long 2) + %F = getelementptr int* %X, long 2 + %val = load int* %F + ret int %val } From vadve at cs.uiuc.edu Wed Oct 9 15:07:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/176.gcc/ Message-ID: <200210092006.PAA32139@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/176.gcc: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/176.gcc added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:08 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:08 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/164.gzip/ Message-ID: <200210092006.PAA32130@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/164.gzip: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/164.gzip added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:11 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:11 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/ Message-ID: <200210092006.PAA32124@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:14 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:14 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/181.mcf/ Message-ID: <200210092006.PAA32144@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/181.mcf: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/181.mcf added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:18 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:18 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/ Message-ID: <200210092006.PAA32127@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000 added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:21 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:21 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/186.crafty/ Message-ID: <200210092006.PAA32149@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/186.crafty: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/186.crafty added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:24 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:24 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/197.parser/ Message-ID: <200210092006.PAA32154@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/197.parser: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/197.parser added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:28 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:28 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/254.gap/ Message-ID: <200210092006.PAA32159@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/254.gap: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/254.gap added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:31 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:31 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/255.vortex/ Message-ID: <200210092006.PAA32164@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/255.vortex: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/255.vortex added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:34 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:34 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/256.bzip2/ Message-ID: <200210092006.PAA32169@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/256.bzip2: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/256.bzip2 added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:07:38 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:07:38 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/300.twolf/ Message-ID: <200210092006.PAA32174@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/300.twolf: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/300.twolf added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Oct 9 15:38:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 15:38:00 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/FunctionResolve/retmismatch1.ll retmismatch2.ll Message-ID: <200210092037.PAA08819@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/FunctionResolve: retmismatch1.ll updated: 1.1 -> 1.2 retmismatch2.ll updated: 1.1 -> 1.2 --- Log message: Avoid having testcases spit out bytecode on error --- Diffs of the changes: Index: llvm/test/Regression/Transforms/FunctionResolve/retmismatch1.ll diff -u llvm/test/Regression/Transforms/FunctionResolve/retmismatch1.ll:1.1 llvm/test/Regression/Transforms/FunctionResolve/retmismatch1.ll:1.2 --- llvm/test/Regression/Transforms/FunctionResolve/retmismatch1.ll:1.1 Fri May 24 16:27:41 2002 +++ llvm/test/Regression/Transforms/FunctionResolve/retmismatch1.ll Wed Oct 9 15:36:54 2002 @@ -1,6 +1,6 @@ ; This shows where the function is called with the prototype indicating a ; return type exists, but it really doesn't. -; RUN: if as < %s | opt -funcresolve +; RUN: if as < %s | opt -funcresolve > /dev/null ; RUN: then echo "opt ok" ; RUN: else exit 1 # Make sure opt doesn't abort! ; RUN: fi Index: llvm/test/Regression/Transforms/FunctionResolve/retmismatch2.ll diff -u llvm/test/Regression/Transforms/FunctionResolve/retmismatch2.ll:1.1 llvm/test/Regression/Transforms/FunctionResolve/retmismatch2.ll:1.2 --- llvm/test/Regression/Transforms/FunctionResolve/retmismatch2.ll:1.1 Fri May 24 16:27:41 2002 +++ llvm/test/Regression/Transforms/FunctionResolve/retmismatch2.ll Wed Oct 9 15:36:54 2002 @@ -1,7 +1,7 @@ ; This shows where the function is called with the prototype indicating a ; return type doesn't exists, but it really does. ; -; RUN: if as < %s | opt -funcresolve +; RUN: if as < %s | opt -funcresolve > /dev/null ; RUN: then echo "opt ok" ; RUN: else exit 1 # Make sure opt doesn't abort! ; RUN: fi From lattner at cs.uiuc.edu Wed Oct 9 15:38:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 15:38:03 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVarsEasier.ll Message-ID: <200210092037.PAA08834@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/FunctionResolve: 2002-08-19-ResolveGlobalVarsEasier.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:43:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:43:00 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/Makefile.spec Message-ID: <200210092042.PAA01095@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC: Makefile.spec added (r1.1) --- Log message: Makefile for testing the SPEC benchmarks. This currently does not compile them from source, but copies the bytecode from a global location. --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:47:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:47:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/Makefile Message-ID: <200210092046.PAA01180@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000: Makefile added (r1.1) --- Log message: Test Makefile for SPEC/CINT2000. --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Oct 9 15:56:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 15:56:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll Message-ID: <200210092055.PAA10074@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/FunctionResolve: 2002-08-19-ResolveGlobalVars.ll updated: 1.2 -> 1.3 --- Log message: Add check to see if opt aborts --- Diffs of the changes: Index: llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll diff -u llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll:1.2 llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll:1.3 --- llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll:1.2 Wed Oct 9 12:44:34 2002 +++ llvm/test/Regression/Transforms/FunctionResolve/2002-08-19-ResolveGlobalVars.ll Wed Oct 9 15:55:32 2002 @@ -1,6 +1,11 @@ ; Test that: extern int X[] and int X[] = { 1, 2, 3, 4 } are resolved ; correctly. ; +; RUN: if as < %s | opt -funcresolve > /dev/null +; RUN: then echo "opt ok" +; RUN: else exit 1 # Make sure opt doesn't abort! +; RUN: fi +; ; RUN: if as < %s | opt -funcresolve | dis | grep external ; RUN: then exit 1 ; RUN: else exit 0 From vadve at cs.uiuc.edu Wed Oct 9 15:57:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:57:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/164.gzip/data/ Message-ID: <200210092056.PAA01330@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/164.gzip/data: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Programs/MultiSource/SPEC/CINT2000/164.gzip/data added to the repository --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:58:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:58:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/164.gzip/Makefile Message-ID: <200210092057.PAA01345@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/164.gzip: Makefile added (r1.1) --- Log message: Makefile for 164.gzip. --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:58:03 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:58:03 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/181.mcf/Makefile Message-ID: <200210092057.PAA01356@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/181.mcf: Makefile added (r1.1) --- Log message: Makefile for 181.mcf. --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 15:59:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 15:59:00 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/197.parser/Makefile Message-ID: <200210092058.PAA01374@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/197.parser: Makefile added (r1.1) --- Log message: Makefile for 197.parser. --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 16:00:02 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 16:00:02 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/254.gap/Makefile Message-ID: <200210092059.PAA01384@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/254.gap: Makefile added (r1.1) --- Log message: Makefile for 254.gap. --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 16:00:04 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 16:00:04 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/255.vortex/Makefile Message-ID: <200210092059.PAA01394@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/255.vortex: Makefile added (r1.1) --- Log message: Makefile for 255.vortex. --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 16:00:07 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 16:00:07 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/256.bzip2/Makefile Message-ID: <200210092059.PAA01402@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/256.bzip2: Makefile added (r1.1) --- Log message: Makefile for 256.bzip2. --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 16:00:09 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 16:00:09 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/CINT2000/300.twolf/Makefile Message-ID: <200210092059.PAA01413@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC/CINT2000/300.twolf: Makefile added (r1.1) --- Log message: Makefile for 300.twolf. --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Oct 9 16:11:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 16:11:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionResolution.cpp Message-ID: <200210092110.QAA10439@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionResolution.cpp updated: 1.12 -> 1.13 --- Log message: Almost a complete rewrite of FunctionResolution to now resolve functions and global variables. This fixes bug: FuncResolve/2002-08-19-ResolveGlobalVarsEasier.ll And bug: SingleSource/UnitTests/2002-10-09-ArrayResolution.c Note that this does not fix bug: FunctionResolve/2002-08-19-ResolveGlobalVars.ll because replaceAllUsesWith breaks when a constantexpr is pointing to the thing being replaced. This is more of an infrastructure problem than anything. --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.12 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.13 --- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.12 Tue Oct 1 17:38:36 2002 +++ llvm/lib/Transforms/IPO/FunctionResolution.cpp Wed Oct 9 16:10:06 2002 @@ -17,7 +17,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Pass.h" #include "llvm/iOther.h" -#include "llvm/Constant.h" +#include "llvm/Constants.h" #include "Support/Statistic.h" #include @@ -27,6 +27,7 @@ namespace { Statistic<>NumResolved("funcresolve", "Number of varargs functions resolved"); + Statistic<> NumGlobals("funcresolve", "Number of global variables resolved"); struct FunctionResolvingPass : public Pass { bool run(Module &M); @@ -111,144 +112,234 @@ } +static bool ResolveFunctions(Module &M, vector &Globals, + Function *Concrete) { + bool Changed = false; + for (unsigned i = 0; i != Globals.size(); ++i) + if (Globals[i] != Concrete) { + Function *Old = cast(Globals[i]); + const FunctionType *OldMT = Old->getFunctionType(); + const FunctionType *ConcreteMT = Concrete->getFunctionType(); + + assert(OldMT->getParamTypes().size() <= + ConcreteMT->getParamTypes().size() && + "Concrete type must have more specified parameters!"); + + // Check to make sure that if there are specified types, that they + // match... + // + for (unsigned i = 0; i < OldMT->getParamTypes().size(); ++i) + if (OldMT->getParamTypes()[i] != ConcreteMT->getParamTypes()[i]) { + cerr << "Parameter types conflict for" << OldMT + << " and " << ConcreteMT; + return Changed; + } + + // Attempt to convert all of the uses of the old function to the + // concrete form of the function. If there is a use of the fn that + // we don't understand here we punt to avoid making a bad + // transformation. + // + // At this point, we know that the return values are the same for + // our two functions and that the Old function has no varargs fns + // specified. In otherwords it's just (...) + // + for (unsigned i = 0; i < Old->use_size(); ) { + User *U = *(Old->use_begin()+i); + if (CastInst *CI = dyn_cast(U)) { + // Convert casts directly + assert(CI->getOperand(0) == Old); + CI->setOperand(0, Concrete); + Changed = true; + ++NumResolved; + } else if (CallInst *CI = dyn_cast(U)) { + // Can only fix up calls TO the argument, not args passed in. + if (CI->getCalledValue() == Old) { + ConvertCallTo(CI, Concrete); + Changed = true; + ++NumResolved; + } else { + cerr << "Couldn't cleanup this function call, must be an" + << " argument or something!" << CI; + ++i; + } + } else { + cerr << "Cannot convert use of function: " << U << "\n"; + ++i; + } + } + } + return Changed; +} + + +static bool ResolveGlobalVariables(Module &M, vector &Globals, + GlobalVariable *Concrete) { + bool Changed = false; + assert(isa(Concrete->getType()->getElementType()) && + "Concrete version should be an array type!"); + + // Get the type of the things that may be resolved to us... + const Type *AETy = + cast(Concrete->getType()->getElementType())->getElementType(); + + std::vector Args; + Args.push_back(Constant::getNullValue(Type::LongTy)); + Args.push_back(Constant::getNullValue(Type::LongTy)); + ConstantExpr *Replacement = + ConstantExpr::getGetElementPtr(ConstantPointerRef::get(Concrete), Args); + + for (unsigned i = 0; i != Globals.size(); ++i) + if (Globals[i] != Concrete) { + GlobalVariable *Old = cast(Globals[i]); + if (Old->getType()->getElementType() != AETy) { + std::cerr << "WARNING: Two global variables exist with the same name " + << "that cannot be resolved!\n"; + return false; + } + + // In this case, Old is a pointer to T, Concrete is a pointer to array of + // T. Because of this, replace all uses of Old with a constantexpr + // getelementptr that returns the address of the first element of the + // array. + // + Old->replaceAllUsesWith(Replacement); + // Since there are no uses of Old anymore, remove it from the module. + M.getGlobalList().erase(Old); + + ++NumGlobals; + Changed = true; + } + return Changed; +} + +static bool ProcessGlobalsWithSameName(Module &M, + vector &Globals) { + assert(!Globals.empty() && "Globals list shouldn't be empty here!"); + + bool isFunction = isa(Globals[0]); // Is this group all functions? + bool Changed = false; + GlobalValue *Concrete = 0; // The most concrete implementation to resolve to + + assert((isFunction ^ isa(Globals[0])) && + "Should either be function or gvar!"); + + for (unsigned i = 0; i != Globals.size(); ) { + if (isa(Globals[i]) != isFunction) { + std::cerr << "WARNING: Found function and global variable with the " + << "same name: '" << Globals[i]->getName() << "'.\n"; + return false; // Don't know how to handle this, bail out! + } + + // Ignore globals that are never used so they don't cause spurious + // warnings... here we will actually DCE the function so that it isn't used + // later. + // + if (Globals[i]->isExternal() && Globals[i]->use_empty()) { + if (isFunction) + M.getFunctionList().erase(cast(Globals[i])); + else + M.getGlobalList().erase(cast(Globals[i])); + + Globals.erase(Globals.begin()+i); + Changed = true; + ++NumResolved; + } else if (isFunction) { + // For functions, we look to merge functions definitions of "int (...)" + // to 'int (int)' or 'int ()' or whatever else is not completely generic. + // + Function *F = cast(Globals[i]); + if (!F->getFunctionType()->isVarArg() || + F->getFunctionType()->getNumParams()) { + if (Concrete) + return false; // Found two different functions types. Can't choose! + + Concrete = Globals[i]; + } + ++i; + } else { + // For global variables, we have to merge C definitions int A[][4] with + // int[6][4] + GlobalVariable *GV = cast(Globals[i]); + if (Concrete == 0) { + if (isa(GV->getType()->getElementType())) + Concrete = GV; + } else { // Must have different types... one is an array of the other? + const ArrayType *AT = + dyn_cast(GV->getType()->getElementType()); + + // If GV is an array of Concrete, then GV is the array. + if (AT && AT->getElementType() == Concrete->getType()->getElementType()) + Concrete = GV; + else { + // Concrete must be an array type, check to see if the element type of + // concrete is already GV. + AT = cast(Concrete->getType()->getElementType()); + if (AT->getElementType() != GV->getType()->getElementType()) + Concrete = 0; // Don't know how to handle it! + } + } + + ++i; + } + } + + if (Globals.size() > 1) { // Found a multiply defined global... + // We should find exactly one concrete function definition, which is + // probably the implementation. Change all of the function definitions and + // uses to use it instead. + // + if (!Concrete) { + cerr << "WARNING: Found function types that are not compatible:\n"; + for (unsigned i = 0; i < Globals.size(); ++i) { + cerr << "\t" << Globals[i]->getType()->getDescription() << " %" + << Globals[i]->getName() << "\n"; + } + cerr << " No linkage of globals named '" << Globals[0]->getName() + << "' performed!\n"; + return Changed; + } + + if (isFunction) + return Changed | ResolveFunctions(M, Globals, cast(Concrete)); + else + return Changed | ResolveGlobalVariables(M, Globals, + cast(Concrete)); + } + return Changed; +} + bool FunctionResolvingPass::run(Module &M) { SymbolTable *ST = M.getSymbolTable(); if (!ST) return false; - std::map > Functions; + std::map > Globals; // Loop over the entries in the symbol table. If an entry is a func pointer, // then add it to the Functions map. We do a two pass algorithm here to avoid // problems with iterators getting invalidated if we did a one pass scheme. // for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I) - if (const PointerType *PT = dyn_cast(I->first)) - if (isa(PT->getElementType())) { - SymbolTable::VarMap &Plane = I->second; - for (SymbolTable::type_iterator PI = Plane.begin(), PE = Plane.end(); - PI != PE; ++PI) { - Function *F = cast(PI->second); - assert(PI->first == F->getName() && - "Function name and symbol table do not agree!"); - if (F->hasExternalLinkage()) // Only resolve decls to external fns - Functions[PI->first].push_back(F); - } + if (const PointerType *PT = dyn_cast(I->first)) { + SymbolTable::VarMap &Plane = I->second; + for (SymbolTable::type_iterator PI = Plane.begin(), PE = Plane.end(); + PI != PE; ++PI) { + GlobalValue *GV = cast(PI->second); + assert(PI->first == GV->getName() && + "Global name and symbol table do not agree!"); + if (GV->hasExternalLinkage()) // Only resolve decls to external fns + Globals[PI->first].push_back(GV); } + } bool Changed = false; // Now we have a list of all functions with a particular name. If there is // more than one entry in a list, merge the functions together. // - for (std::map >::iterator I = Functions.begin(), - E = Functions.end(); I != E; ++I) { - vector &Functions = I->second; - Function *Implementation = 0; // Find the implementation - Function *Concrete = 0; - for (unsigned i = 0; i < Functions.size(); ) { - if (!Functions[i]->isExternal()) { // Found an implementation - if (Implementation != 0) - assert(Implementation == 0 && "Multiple definitions of the same" - " function. Case not handled yet!"); - Implementation = Functions[i]; - } else { - // Ignore functions that are never used so they don't cause spurious - // warnings... here we will actually DCE the function so that it isn't - // used later. - // - if (Functions[i]->use_empty()) { - M.getFunctionList().erase(Functions[i]); - Functions.erase(Functions.begin()+i); - Changed = true; - ++NumResolved; - continue; - } - } - - if (Functions[i] && (!Functions[i]->getFunctionType()->isVarArg())) { - if (Concrete) { // Found two different functions types. Can't choose - Concrete = 0; - break; - } - Concrete = Functions[i]; - } - ++i; - } - - if (Functions.size() > 1) { // Found a multiply defined function... - // We should find exactly one non-vararg function definition, which is - // probably the implementation. Change all of the function definitions - // and uses to use it instead. - // - if (!Concrete) { - cerr << "Warning: Found functions types that are not compatible:\n"; - for (unsigned i = 0; i < Functions.size(); ++i) { - cerr << "\t" << Functions[i]->getType()->getDescription() << " %" - << Functions[i]->getName() << "\n"; - } - cerr << " No linkage of functions named '" << Functions[0]->getName() - << "' performed!\n"; - } else { - for (unsigned i = 0; i < Functions.size(); ++i) - if (Functions[i] != Concrete) { - Function *Old = Functions[i]; - const FunctionType *OldMT = Old->getFunctionType(); - const FunctionType *ConcreteMT = Concrete->getFunctionType(); - bool Broken = false; - - assert(OldMT->getParamTypes().size() <= - ConcreteMT->getParamTypes().size() && - "Concrete type must have more specified parameters!"); - - // Check to make sure that if there are specified types, that they - // match... - // - for (unsigned i = 0; i < OldMT->getParamTypes().size(); ++i) - if (OldMT->getParamTypes()[i] != ConcreteMT->getParamTypes()[i]) { - cerr << "Parameter types conflict for" << OldMT - << " and " << ConcreteMT; - Broken = true; - } - if (Broken) break; // Can't process this one! - - - // Attempt to convert all of the uses of the old function to the - // concrete form of the function. If there is a use of the fn that - // we don't understand here we punt to avoid making a bad - // transformation. - // - // At this point, we know that the return values are the same for - // our two functions and that the Old function has no varargs fns - // specified. In otherwords it's just (...) - // - for (unsigned i = 0; i < Old->use_size(); ) { - User *U = *(Old->use_begin()+i); - if (CastInst *CI = dyn_cast(U)) { - // Convert casts directly - assert(CI->getOperand(0) == Old); - CI->setOperand(0, Concrete); - Changed = true; - ++NumResolved; - } else if (CallInst *CI = dyn_cast(U)) { - // Can only fix up calls TO the argument, not args passed in. - if (CI->getCalledValue() == Old) { - ConvertCallTo(CI, Concrete); - Changed = true; - ++NumResolved; - } else { - cerr << "Couldn't cleanup this function call, must be an" - << " argument or something!" << CI; - ++i; - } - } else { - cerr << "Cannot convert use of function: " << U << "\n"; - ++i; - } - } - } - } - } - } + for (std::map >::iterator I = Globals.begin(), + E = Globals.end(); I != E; ++I) + Changed |= ProcessGlobalsWithSameName(M, I->second); return Changed; } From vadve at cs.uiuc.edu Wed Oct 9 16:17:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 16:17:00 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/Makefile.spec Message-ID: <200210092116.QAA01566@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC: Makefile.spec updated: 1.1 -> 1.2 --- Log message: Fix so that symbolic link "data" is created if needed. --- Diffs of the changes: Index: llvm/test/Programs/MultiSource/SPEC/Makefile.spec diff -u llvm/test/Programs/MultiSource/SPEC/Makefile.spec:1.1 llvm/test/Programs/MultiSource/SPEC/Makefile.spec:1.2 --- llvm/test/Programs/MultiSource/SPEC/Makefile.spec:1.1 Wed Oct 9 15:42:33 2002 +++ llvm/test/Programs/MultiSource/SPEC/Makefile.spec Wed Oct 9 16:16:40 2002 @@ -17,8 +17,12 @@ PROGRAMS_TO_TEST = $(BENCH) + include $(LEVEL)/test/Makefile.tests +data: + @test -L data || ln -s $(BENCHDATADIR) + ifndef DISABLE_LLC all :: Output/$(BENCH).diff-llc endif @@ -30,13 +34,19 @@ ##--- SPEC-dependent rules to do a test run or a reportable reference run -## EXPECTED_OUTPUTS includes all the output files provided in the output dir. +# BENCHDATADIR - The directory holding expected SPEC benchmark results +BENCHDATADIR = /home/vadve/shared/Benchmarks/speccpu2000/benchspec/CINT2000/$(BENCH)/data + +## BENCHMARK_OUTPUTS includes all the output files provided in the output dir. ## $(BENCHOUT) defined above should be one of these output files. ## -EXPECTED_OUTPUTS = $(wildcard data/test/output/*.out) -LLC_OUTPUTS = $(subst data/test/output/,,$(EXPECTED_OUTPUTS)) +BENCHMARK_OUTPUTS = $(wildcard $(BENCHDATADIR)/test/output/*.out) +LLC_OUTPUTS = $(subst $(BENCHDATADIR)/test/output/,,$(BENCHMARK_OUTPUTS)) CBE_OUTPUTS = $(LLC_OUTPUTS) +check: + echo orig = $(BENCHMARK_OUTPUTS) + echo llc = $(LLC_OUTPUTS) ref: Output/$(BENCH).llc Output/$(BENCH).llc $(REFOPTS) @@ -69,8 +79,8 @@ Output/%.cbe: Output/%.cbe.c $(CC) -o $@ $< $(LDFLAGS) $(CFLAGS) -Output/%.out-nat: $(EXPECTED_OUTPUTS) Output/.dir - cat $(EXPECTED_OUTPUTS) > $@ +Output/%.out-nat: $(BENCHMARK_OUTPUTS) Output/.dir + cat $(BENCHMARK_OUTPUTS) > $@ ifdef COPYFILES Output/.copy: @@ -94,7 +104,7 @@ Output/%.diff-llc: Output/%.out-nat Output/%.out-llc Output/.dir $(DIFFPROG) llc $(subst Output/,,$(@:.diff-llc=)) -Output/%.diff-cbe: Output/%.out-nat Output/%.out-cbe Output/.dir +Output/%.diff-cbe: data Output/%.out-nat Output/%.out-cbe Output/.dir $(DIFFPROG) cbe $(subst Output/,,$(@:.diff-cbe=)) From hldnbrnd at cs.uiuc.edu Wed Oct 9 16:50:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Wed Oct 9 16:50:01 2002 Subject: [llvm-commits] CVS: llvm/www/docs/TestStatus.html Message-ID: <200210092149.QAA18931@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: TestStatus.html added (r1.1) --- Log message: Table with current status of tests in the /test/Programs/ directory --- Diffs of the changes: From vadve at cs.uiuc.edu Wed Oct 9 16:51:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Wed Oct 9 16:51:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/SPEC/Makefile Message-ID: <200210092150.QAA01996@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/SPEC: Makefile added (r1.1) --- Log message: Makefile for test/Programs/MultiSource/SPEC directory. --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Oct 9 18:12:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 18:12:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Function.h GlobalValue.h GlobalVariable.h Message-ID: <200210092311.SAA20210@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Function.h updated: 1.36 -> 1.37 GlobalValue.h updated: 1.7 -> 1.8 GlobalVariable.h updated: 1.16 -> 1.17 --- Log message: Make isExtern() be a virtual function inherited from GlobalValue --- Diffs of the changes: Index: llvm/include/llvm/Function.h diff -u llvm/include/llvm/Function.h:1.36 llvm/include/llvm/Function.h:1.37 --- llvm/include/llvm/Function.h:1.36 Fri Sep 6 16:31:57 2002 +++ llvm/include/llvm/Function.h Wed Oct 9 18:11:32 2002 @@ -85,7 +85,7 @@ /// is empty if so) this is true for external functions, defined as forward /// "declare"ations /// - bool isExternal() const { return BasicBlocks.empty(); } + virtual bool isExternal() const { return BasicBlocks.empty(); } // getNext/Prev - Return the next or previous function in the list. These // methods should never be used directly, and are only used to implement the Index: llvm/include/llvm/GlobalValue.h diff -u llvm/include/llvm/GlobalValue.h:1.7 llvm/include/llvm/GlobalValue.h:1.8 --- llvm/include/llvm/GlobalValue.h:1.7 Fri Sep 6 16:31:57 2002 +++ llvm/include/llvm/GlobalValue.h Wed Oct 9 18:11:33 2002 @@ -26,17 +26,22 @@ public: ~GlobalValue() {} - // getType - Global values are always pointers. + /// getType - Global values are always pointers. inline const PointerType *getType() const { return (const PointerType*)User::getType(); } - // Internal Linkage - True if the global value is inaccessible to + /// Internal Linkage - True if the global value is inaccessible to bool hasInternalLinkage() const { return HasInternalLinkage; } bool hasExternalLinkage() const { return !HasInternalLinkage; } void setInternalLinkage(bool HIL) { HasInternalLinkage = HIL; } - // Get the module that this global value is contained inside of... + /// isExternal - Return true if the primary definition of this global value is + /// outside of the current translation unit... + virtual bool isExternal() const = 0; + + /// getParent - Get the module that this global value is contained inside + /// of... inline Module *getParent() { return Parent; } inline const Module *getParent() const { return Parent; } Index: llvm/include/llvm/GlobalVariable.h diff -u llvm/include/llvm/GlobalVariable.h:1.16 llvm/include/llvm/GlobalVariable.h:1.17 --- llvm/include/llvm/GlobalVariable.h:1.16 Sun Oct 6 17:29:58 2002 +++ llvm/include/llvm/GlobalVariable.h Wed Oct 9 18:11:33 2002 @@ -46,7 +46,7 @@ /// global variable is defined in some other translation unit, and is thus /// externally defined here. /// - bool isExternal() const { return Operands.empty(); } + virtual bool isExternal() const { return Operands.empty(); } /// hasInitializer - Unless a global variable isExternal(), it has an /// initializer. The initializer for the global variable/constant is held by From lattner at cs.uiuc.edu Wed Oct 9 18:13:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 18:13:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Constants.h Message-ID: <200210092312.SAA20228@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.4 -> 1.5 Constants.h updated: 1.16 -> 1.17 --- Log message: - Add new Constant::replaceUsesOfWithOnConstant which has an end result similar to User::replaceUsesOfWith but actually does the right thing for constants. --- Diffs of the changes: Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.4 llvm/include/llvm/Constant.h:1.5 --- llvm/include/llvm/Constant.h:1.4 Sun Aug 25 17:54:54 2002 +++ llvm/include/llvm/Constant.h Wed Oct 9 18:12:22 2002 @@ -16,10 +16,11 @@ void destroyConstantImpl(); public: - /// setName - Specialize setName to handle symbol table majik... + // setName - Specialize setName to handle symbol table majik... virtual void setName(const std::string &name, SymbolTable *ST = 0); /// Static constructor to get a '0' constant of arbitrary type... + /// static Constant *getNullValue(const Type *Ty); /// isNullValue - Return true if this is the value that would be returned by @@ -29,6 +30,7 @@ virtual void print(std::ostream &O) const; /// isConstantExpr - Return true if this is a ConstantExpr + /// virtual bool isConstantExpr() const { return false; } @@ -49,10 +51,29 @@ virtual void destroyConstant() { assert(0 && "Not reached!"); } - /// Methods for support type inquiry through isa, cast, and dyn_cast: + //// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Constant *) { return true; } static inline bool classof(const Value *V) { return V->getValueType() == Value::ConstantVal; + } + + /// replaceUsesOfWithOnConstant - This method is a special form of + /// User::replaceUsesOfWith (which does not work on constants) that does work + /// on constants. Basically this method goes through the trouble of building + /// a new constant that is equivalent to the current one, with all uses of + /// From replaced with uses of To. After this construction is completed, all + /// of the users of 'this' are replaced to use the new constant, and then + /// 'this' is deleted. In general, you should not call this method, instead, + /// use Value::replaceAllUsesWith, which automatically dispatches to this + /// method as needed. + /// + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To) { + // Provide a default implementation for constants (like integers) that + // cannot use any other values. This cannot be called at runtime, but needs + // to be here to avoid link errors. + assert(getNumOperands() == 0 && "replaceUsesOfWithOnConstant must be " + "implemented for all constants that have operands!"); + assert(0 && "Constants that do not have operands cannot be using 'From'!"); } // WARNING: Only to be used by Bytecode & Assembly Parsers! USER CODE SHOULD Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.16 llvm/include/llvm/Constants.h:1.17 --- llvm/include/llvm/Constants.h:1.16 Mon Aug 26 12:53:53 2002 +++ llvm/include/llvm/Constants.h Wed Oct 9 18:12:22 2002 @@ -292,6 +292,7 @@ virtual bool isNullValue() const { return false; } virtual void destroyConstant(); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantArray *) { return true; } @@ -330,6 +331,7 @@ virtual bool isNullValue() const { return false; } virtual void destroyConstant(); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantStruct *) { return true; } @@ -423,6 +425,7 @@ } virtual void destroyConstant(); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantPointerRef *) { return true; } @@ -489,6 +492,7 @@ virtual bool isConstantExpr() const { return true; } virtual void destroyConstant(); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantExpr *) { return true; } From lattner at cs.uiuc.edu Wed Oct 9 18:13:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 18:13:04 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200210092312.SAA20235@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.29 -> 1.30 --- Log message: - Add new Constant::replaceUsesOfWithOnConstant which has an end result similar to User::replaceUsesOfWith but actually does the right thing for constants. --- Diffs of the changes: Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.29 llvm/lib/VMCore/Constants.cpp:1.30 --- llvm/lib/VMCore/Constants.cpp:1.29 Tue Oct 8 18:33:52 2002 +++ llvm/lib/VMCore/Constants.cpp Wed Oct 9 18:12:25 2002 @@ -327,6 +327,112 @@ }; //===----------------------------------------------------------------------===// +// replaceUsesOfWithOnConstant implementations + +void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To) { + assert(isa(To) && "Cannot make Constant refer to non-constant!"); + + std::vector Values; + Values.reserve(getValues().size()); // Build replacement array... + for (unsigned i = 0, e = getValues().size(); i != e; ++i) { + Constant *Val = cast(getValues()[i]); + if (Val == From) Val = cast(To); + Values.push_back(Val); + } + + ConstantArray *Replacement = ConstantArray::get(getType(), Values); + assert(Replacement != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement... + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); +} + +void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To) { + assert(isa(To) && "Cannot make Constant refer to non-constant!"); + + std::vector Values; + Values.reserve(getValues().size()); + for (unsigned i = 0, e = getValues().size(); i != e; ++i) { + Constant *Val = cast(getValues()[i]); + if (Val == From) Val = cast(To); + Values.push_back(Val); + } + + ConstantStruct *Replacement = ConstantStruct::get(getType(), Values); + assert(Replacement != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement... + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); +} + +void ConstantPointerRef::replaceUsesOfWithOnConstant(Value *From, Value *To) { + if (isa(To)) { + assert(From == getOperand(0) && "Doesn't contain from!"); + ConstantPointerRef *Replacement = + ConstantPointerRef::get(cast(To)); + + // Everyone using this now uses the replacement... + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); + } else { + // Just replace ourselves with the To value specified. + replaceAllUsesWith(To); + + // Delete the old constant! + destroyConstant(); + } +} + +void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *To) { + assert(isa(To) && "Cannot make Constant refer to non-constant!"); + + ConstantExpr *Replacement = 0; + if (getOpcode() == Instruction::GetElementPtr) { + std::vector Indices; + Constant *Pointer = cast(getOperand(0)); + Indices.reserve(getNumOperands()-1); + if (Pointer == From) Pointer = cast(To); + + for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { + Constant *Val = cast(getOperand(i)); + if (Val == From) Val = cast(To); + Indices.push_back(Val); + } + Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices); + } else if (getOpcode() == Instruction::Cast) { + assert(getOperand(0) == From && "Cast only has one use!"); + Replacement = ConstantExpr::getCast(cast(To), getType()); + } else if (getNumOperands() == 2) { + Constant *C1 = cast(getOperand(0)); + Constant *C2 = cast(getOperand(1)); + if (C1 == From) C1 = cast(To); + if (C2 == From) C2 = cast(To); + Replacement = ConstantExpr::get(getOpcode(), C1, C2); + } else { + assert(0 && "Unknown ConstantExpr type!"); + return; + } + + assert(Replacement != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement... + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); +} + + + +//===----------------------------------------------------------------------===// // Factory Function Implementation template From lattner at cs.uiuc.edu Wed Oct 9 18:14:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 18:14:01 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Value.cpp Message-ID: <200210092313.SAA20249@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Value.cpp updated: 1.29 -> 1.30 --- Log message: - Make Value::replaceAllUsesWith work with constants correctly. This fixes bug FuncResolve/2002-08-19-ResolveGlobalVars.ll and gzip looks better. --- Diffs of the changes: Index: llvm/lib/VMCore/Value.cpp diff -u llvm/lib/VMCore/Value.cpp:1.29 llvm/lib/VMCore/Value.cpp:1.30 --- llvm/lib/VMCore/Value.cpp:1.29 Tue Oct 8 19:25:05 2002 +++ llvm/lib/VMCore/Value.cpp Wed Oct 9 18:12:59 2002 @@ -7,6 +7,7 @@ #include "llvm/InstrTypes.h" #include "llvm/SymbolTable.h" #include "llvm/DerivedTypes.h" +#include "llvm/Constant.h" #include "Support/LeakDetector.h" #include @@ -45,23 +46,23 @@ LeakDetector::removeGarbageObject(this); } -void Value::replaceAllUsesWith(Value *D) { - assert(D && "Value::replaceAllUsesWith() is invalid!"); - assert(D != this && "V->replaceAllUsesWith(V) is NOT valid!"); - assert(D->getType() == getType() && + + + +void Value::replaceAllUsesWith(Value *New) { + assert(New && "Value::replaceAllUsesWith() is invalid!"); + assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!"); + assert(New->getType() == getType() && "replaceAllUses of value with new value of different type!"); while (!Uses.empty()) { User *Use = Uses.back(); -#ifndef NDEBUG - unsigned NumUses = Uses.size(); -#endif - Use->replaceUsesOfWith(this, D); - -#ifndef NDEBUG // only in -g mode... - if (Uses.size() == NumUses) - std::cerr << "Use: " << *Use << "replace with: " << *D; -#endif - assert(Uses.size() != NumUses && "Didn't remove definition!"); + // Must handle Constants specially, we cannot call replaceUsesOfWith on a + // constant! + if (Constant *C = dyn_cast(Use)) { + C->replaceUsesOfWithOnConstant(this, New); + } else { + Use->replaceUsesOfWith(this, New); + } } } @@ -105,6 +106,9 @@ void User::replaceUsesOfWith(Value *From, Value *To) { if (From == To) return; // Duh what? + assert(!isa(this) && + "Cannot call User::replaceUsesofWith on a constant!"); + for (unsigned i = 0, E = getNumOperands(); i != E; ++i) if (getOperand(i) == From) { // Is This operand is pointing to oldval? // The side effects of this setOperand call include linking to @@ -113,5 +117,3 @@ setOperand(i, To); // Fix it now... } } - - From lattner at cs.uiuc.edu Wed Oct 9 18:17:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Oct 9 18:17:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/ConstantMerge.cpp Message-ID: <200210092316.SAA20511@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: ConstantMerge.cpp updated: 1.17 -> 1.18 --- Log message: - Dramatically simplify the ConstantMerge code now that Value::replaceAllUsesWith works with constants correctly. --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/ConstantMerge.cpp diff -u llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.17 llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.18 --- llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.17 Tue Oct 1 17:38:35 2002 +++ llvm/lib/Transforms/IPO/ConstantMerge.cpp Wed Oct 9 18:16:04 2002 @@ -12,23 +12,19 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Module.h" -#include "llvm/Constants.h" #include "llvm/Pass.h" #include "Support/Statistic.h" namespace { + Statistic<> NumMerged("constmerge", "Number of global constants merged"); + struct ConstantMerge : public Pass { // run - For this pass, process all of the globals in the module, // eliminating duplicate constants. // bool run(Module &M); - - private: - void replaceUsesOfWith(GlobalVariable *Old, GlobalVariable *New); - void replaceConstantWith(Constant *Old, Constant *New); }; - Statistic<> NumMerged("constmerge", "Number of global constants merged"); RegisterOpt X("constmerge","Merge Duplicate Global Constants"); } @@ -51,7 +47,7 @@ CMap.insert(I, std::make_pair(Init, GV)); } else { // Yup, this is a duplicate! // Make all uses of the duplicate constant use the cannonical version... - replaceUsesOfWith(GV, I->second); + GV->replaceAllUsesWith(I->second); // Delete the global value from the module... and back up iterator to // not skip the next global... @@ -63,99 +59,4 @@ } return MadeChanges; -} - -/// replaceUsesOfWith - Replace all uses of Old with New. For instructions, -/// this is a really simple matter of replacing the reference to Old with a -/// reference to New. For constants references, however, we must carefully -/// build replacement constants to substitute in. -/// -void ConstantMerge::replaceUsesOfWith(GlobalVariable *Old, GlobalVariable *New){ - while (!Old->use_empty()) { - User *U = Old->use_back(); - if (ConstantPointerRef *CPR = dyn_cast(U)) - replaceConstantWith(CPR, ConstantPointerRef::get(New)); - else - U->replaceUsesOfWith(Old, New); - } -} - -/// replaceWith - Ok, so we have a constant 'Old' and we want to replace it with -/// 'New'. To do this, we have to recursively go through the uses of Old, -/// replacing them with new things. The problem is that if a constant uses Old, -/// then we need to replace the uses of the constant with uses of the equivalent -/// constant that uses New instead. -/// -void ConstantMerge::replaceConstantWith(Constant *Old, Constant *New) { - while (!Old->use_empty()) { - User *U = Old->use_back(); - - if (Constant *C = dyn_cast(U)) { - Constant *Replacement = 0; - - // Depending on the type of constant, build a suitable replacement... - if (ConstantExpr *CE = dyn_cast(C)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - std::vector Indices; - Constant *Pointer = cast(CE->getOperand(0)); - Indices.reserve(CE->getNumOperands()-1); - if (Pointer == Old) Pointer = New; - - for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) { - Constant *Val = cast(CE->getOperand(i)); - if (Val == Old) Val = New; - Indices.push_back(Val); - } - Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices); - } else if (CE->getOpcode() == Instruction::Cast) { - assert(CE->getOperand(0) == Old && "Cast only has one use!"); - Replacement = ConstantExpr::getCast(New, CE->getType()); - } else if (CE->getNumOperands() == 2) { - Constant *C1 = cast(CE->getOperand(0)); - Constant *C2 = cast(CE->getOperand(1)); - if (C1 == Old) C1 = New; - if (C2 == Old) C2 = New; - Replacement = ConstantExpr::get(CE->getOpcode(), C1, C2); - } else { - assert(0 && "Unknown ConstantExpr type!"); - } - - - } else if (ConstantArray *CA = dyn_cast(C)) { - std::vector Values; - Values.reserve(CA->getValues().size()); - for (unsigned i = 0, e = CA->getValues().size(); i != e; ++i) { - Constant *Val = cast(CA->getValues()[i]); - if (Val == Old) Val = New; - Values.push_back(Val); - } - - Replacement = ConstantArray::get(CA->getType(), Values); - } else if (ConstantStruct *CS = dyn_cast(C)) { - std::vector Values; - Values.reserve(CS->getValues().size()); - - for (unsigned i = 0, e = CS->getValues().size(); i != e; ++i) { - Constant *Val = cast(CS->getValues()[i]); - if (Val == Old) Val = New; - Values.push_back(Val); - } - - Replacement = ConstantStruct::get(CS->getType(), Values); - } else { - assert(0 && "Unexpected/unknown constant type!"); - } - - // Now that we have a suitable replacement, recursively eliminate C. - replaceConstantWith(C, Replacement); - - } else { - // If it is not a constant, we can simply replace uses of Old with New. - U->replaceUsesOfWith(Old, New); - } - - } - - // No-one refers to this old dead constant now, destroy it! - Old->destroyConstant(); } From lattner at cs.uiuc.edu Thu Oct 10 14:29:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 10 14:29:01 2002 Subject: [llvm-commits] CVS: llvm/Makefile.SunOS Message-ID: <200210101928.OAA05898@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.SunOS updated: 1.2 -> 1.3 --- Log message: Switch over to the right sparc c frontend --- Diffs of the changes: Index: llvm/Makefile.SunOS diff -u llvm/Makefile.SunOS:1.2 llvm/Makefile.SunOS:1.3 --- llvm/Makefile.SunOS:1.2 Thu Sep 19 14:44:28 2002 +++ llvm/Makefile.SunOS Thu Oct 10 14:28:10 2002 @@ -19,5 +19,5 @@ # be overriden by the Makefile.config option, and should not override it if set. # ifndef LLVMGCCDIR -LLVMGCCDIR := /home/vadve/lattner/cvs/gcc_install +LLVMGCCDIR := /home/vadve/lattner/cvs/gcc_install_sparc endif From lattner at cs.uiuc.edu Thu Oct 10 15:34:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 10 15:34:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PoolAllocate.cpp Message-ID: <200210102033.PAA06536@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PoolAllocate.cpp updated: 1.41 -> 1.42 --- Log message: Stop using DataStructureGraph.h --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PoolAllocate.cpp diff -u llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.41 llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.42 --- llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.41 Fri Sep 13 17:28:36 2002 +++ llvm/lib/Transforms/IPO/PoolAllocate.cpp Thu Oct 10 15:33:46 2002 @@ -4,14 +4,11 @@ // allocated out of different pools of memory, increasing locality and shrinking // pointer size. // -// This pass requires a DCE & instcombine pass to be run after it for best -// results. -// //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Utils/CloneFunction.h" -#include "llvm/Analysis/DataStructureGraph.h" +#include "llvm/Analysis/DataStructure.h" #include "llvm/Module.h" #include "llvm/iMemory.h" #include "llvm/iTerminators.h" From lattner at cs.uiuc.edu Thu Oct 10 15:37:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 10 15:37:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraphTraits.h DataStructureGraph.h Message-ID: <200210102036.PAA06679@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraphTraits.h updated: 1.5 -> 1.6 DataStructureGraph.h (r1.5) removed --- Log message: Rename DataStructureGraph.h to DSGraphTraits.h --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraphTraits.h diff -u llvm/include/llvm/Analysis/DSGraphTraits.h:1.5 llvm/include/llvm/Analysis/DSGraphTraits.h:1.6 --- llvm/include/llvm/Analysis/DSGraphTraits.h:1.5 Tue Oct 1 17:34:45 2002 +++ llvm/include/llvm/Analysis/DSGraphTraits.h Thu Oct 10 15:36:37 2002 @@ -1,4 +1,4 @@ -//===- DataStructureGraph.h - Provide graph classes --------------*- C++ -*--=// +//===- DSGraphTraits.h - Provide generic graph interface --------*- C++ -*-===// // // This file provides GraphTraits specializations for the DataStructure graph // nodes, allowing datastructure graphs to be processed by generic graph @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_DATASTRUCTURE_GRAPH_H -#define LLVM_ANALYSIS_DATASTRUCTURE_GRAPH_H +#ifndef LLVM_ANALYSIS_DSGRAPHTRAITS_H +#define LLVM_ANALYSIS_DSGRAPHTRAITS_H -#include "llvm/Analysis/DataStructure.h" +#include "llvm/Analysis/DSGraph.h" #include "Support/GraphTraits.h" #include "Support/iterator" From lattner at cs.uiuc.edu Thu Oct 10 17:30:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 10 17:30:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/DOTGraphTraits.h Message-ID: <200210102229.RAA08275@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: DOTGraphTraits.h updated: 1.1 -> 1.2 --- Log message: Add new getGraphProperties that may be specialized by graphs --- Diffs of the changes: Index: llvm/include/Support/DOTGraphTraits.h diff -u llvm/include/Support/DOTGraphTraits.h:1.1 llvm/include/Support/DOTGraphTraits.h:1.2 --- llvm/include/Support/DOTGraphTraits.h:1.1 Mon Oct 7 13:37:10 2002 +++ llvm/include/Support/DOTGraphTraits.h Thu Oct 10 17:29:10 2002 @@ -23,6 +23,14 @@ /// static std::string getGraphName(void *Graph) { return ""; } + /// getGraphProperties - Return any custom properties that should be included + /// in the top level graph structure for dot. By default, we resize the graph + /// to fit on a letter size page. + /// + static std::string getGraphProperties(void *Graph) { + return "\tsize=\"7.5,10\";\n"; // Size to fit on a page + } + /// getNodeLabel - Given a node and a pointer to the top level graph, return /// the label to print in the node. static std::string getNodeLabel(void *Node, void *Graph) { return ""; } From lattner at cs.uiuc.edu Thu Oct 10 17:31:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 10 17:31:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/GraphWriter.h Message-ID: <200210102230.RAA08326@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: GraphWriter.h updated: 1.2 -> 1.3 --- Log message: * Don't only print out reachable nodes in the graph. * use new api to get all nodes in the graph * Allow custom graph traits --- Diffs of the changes: Index: llvm/include/Support/GraphWriter.h diff -u llvm/include/Support/GraphWriter.h:1.2 llvm/include/Support/GraphWriter.h:1.3 --- llvm/include/Support/GraphWriter.h:1.2 Mon Oct 7 17:37:03 2002 +++ llvm/include/Support/GraphWriter.h Thu Oct 10 17:29:51 2002 @@ -17,7 +17,7 @@ #define SUPPORT_GRAPHWRITER_H #include "Support/DOTGraphTraits.h" -#include "Support/DepthFirstIterator.h" +#include "Support/GraphTraits.h" #include namespace DOT { // Private functions... @@ -53,19 +53,19 @@ typedef DOTGraphTraits DOTTraits; typedef GraphTraits GTraits; typedef typename GTraits::NodeType NodeType; + typedef typename GTraits::nodes_iterator node_iterator; - O << "digraph foo {\n" // Graph name doesn't matter - << "\tsize=\"7.5,10\";\n"; // Size to fit on a page - + O << "digraph foo {\n"; // Graph name doesn't matter std::string GraphName = DOTTraits::getGraphName(G); if (!GraphName.empty()) O << "\tlabel=\"" << DOT::EscapeString(GraphName) << "\";\n"; + O << DOTTraits::getGraphProperties(G); O << "\n"; // Loop over the graph in DFO, printing it out... - NodeType *Root = GTraits::getEntryNode(G); - for (df_iterator I = df_begin(G), E = df_end(G); I != E; ++I) { - NodeType *Node = *I; + for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G); + I != E; ++I) { + NodeType *Node = &*I; std::string NodeAttributes = DOTTraits::getNodeAttributes(Node); From lattner at cs.uiuc.edu Thu Oct 10 17:32:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 10 17:32:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h Message-ID: <200210102231.RAA08339@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.3 -> 1.4 --- Log message: Change reference --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.3 llvm/include/llvm/Analysis/DSGraph.h:1.4 --- llvm/include/llvm/Analysis/DSGraph.h:1.3 Wed Oct 2 16:55:24 2002 +++ llvm/include/llvm/Analysis/DSGraph.h Thu Oct 10 17:31:02 2002 @@ -157,7 +157,7 @@ // Iterator for graph interface... typedef DSNodeIterator iterator; - inline iterator begin(); // Defined in DataStructureGraph.h + inline iterator begin(); // Defined in DSGraphTraits.h inline iterator end(); //===-------------------------------------------------- From lattner at cs.uiuc.edu Thu Oct 10 17:32:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Oct 10 17:32:04 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/CFG.h Message-ID: <200210102231.RAA08352@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: CFG.h updated: 1.7 -> 1.8 --- Log message: Expose API to graph library to allow iteration over all nodes, even unreachable ones --- Diffs of the changes: Index: llvm/include/llvm/Support/CFG.h diff -u llvm/include/llvm/Support/CFG.h:1.7 llvm/include/llvm/Support/CFG.h:1.8 --- llvm/include/llvm/Support/CFG.h:1.7 Mon Oct 7 12:13:22 2002 +++ llvm/include/llvm/Support/CFG.h Thu Oct 10 17:31:31 2002 @@ -10,7 +10,6 @@ #include "Support/GraphTraits.h" #include "llvm/Function.h" -#include "llvm/BasicBlock.h" #include "llvm/InstrTypes.h" #include "Support/iterator" @@ -220,10 +219,20 @@ // template <> struct GraphTraits : public GraphTraits { static NodeType *getEntryNode(Function *F) { return &F->getEntryNode(); } + + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + typedef Function::iterator nodes_iterator; + static nodes_iterator nodes_begin(Function *F) { return F->begin(); } + static nodes_iterator nodes_end (Function *F) { return F->end(); } }; template <> struct GraphTraits : public GraphTraits { static NodeType *getEntryNode(const Function *F) { return &F->getEntryNode();} + + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + typedef Function::const_iterator nodes_iterator; + static nodes_iterator nodes_begin(const Function *F) { return F->begin(); } + static nodes_iterator nodes_end (const Function *F) { return F->end(); } }; From brukman at cs.uiuc.edu Fri Oct 11 00:31:03 2002 From: brukman at cs.uiuc.edu (Michael Brukman) Date: Fri Oct 11 00:31:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200210110530.AAA19167@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.25 -> 1.26 --- Log message: Added helper functions in LoopInfo: isLoopExit and numBackEdges. --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.25 llvm/lib/Analysis/LoopInfo.cpp:1.26 --- llvm/lib/Analysis/LoopInfo.cpp:1.25 Sun Sep 29 17:59:29 2002 +++ llvm/lib/Analysis/LoopInfo.cpp Fri Oct 11 00:30:13 2002 @@ -24,6 +24,30 @@ return find(Blocks.begin(), Blocks.end(), BB) != Blocks.end(); } +bool Loop::isLoopExit(const BasicBlock *BB) const { + for (BasicBlock::succ_const_iterator SI = succ_begin(BB), SE = succ_end(BB); + SI != SE; ++SI) { + if (! contains(*SI)) + return true; + } + return false; +} + +unsigned Loop::getNumBackEdges() const { + 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) + ++numBackEdges; + } + } + return numBackEdges; +} + void Loop::print(std::ostream &OS) const { OS << std::string(getLoopDepth()*2, ' ') << "Loop Containing: "; From brukman at cs.uiuc.edu Fri Oct 11 00:32:02 2002 From: brukman at cs.uiuc.edu (Michael Brukman) Date: Fri Oct 11 00:32:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/LoopInfo.h Message-ID: <200210110531.AAA19185@trinity.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: LoopInfo.h updated: 1.19 -> 1.20 --- Log message: Added helper functions in LoopInfo: isLoopExit and numBackEdges. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/LoopInfo.h diff -u llvm/include/llvm/Analysis/LoopInfo.h:1.19 llvm/include/llvm/Analysis/LoopInfo.h:1.20 --- llvm/include/llvm/Analysis/LoopInfo.h:1.19 Thu Sep 26 11:15:19 2002 +++ llvm/include/llvm/Analysis/LoopInfo.h Fri Oct 11 00:31:10 2002 @@ -44,7 +44,10 @@ /// isLoopExit - True if terminator in the block can branch to another block /// that is outside of the current loop. - bool isLoopExit(BasicBlock *BB) const; + bool isLoopExit(const BasicBlock *BB) const; + + /// Find number of back edges + unsigned getNumBackEdges() const; /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop From brukman at cs.uiuc.edu Fri Oct 11 00:35:01 2002 From: brukman at cs.uiuc.edu (Michael Brukman) Date: Fri Oct 11 00:35:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/InductionVariable.cpp Message-ID: <200210110534.AAA19205@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: InductionVariable.cpp updated: 1.19 -> 1.20 --- Log message: Added capability to get execution count of a loop if it is a predictable number of iterations. --- Diffs of the changes: Index: llvm/lib/Analysis/InductionVariable.cpp diff -u llvm/lib/Analysis/InductionVariable.cpp:1.19 llvm/lib/Analysis/InductionVariable.cpp:1.20 --- llvm/lib/Analysis/InductionVariable.cpp:1.19 Tue Sep 10 10:35:39 2002 +++ llvm/lib/Analysis/InductionVariable.cpp Fri Oct 11 00:34:27 2002 @@ -19,11 +19,15 @@ #include "llvm/Analysis/InductionVariable.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/Expressions.h" +#include "llvm/BasicBlock.h" #include "llvm/iPHINode.h" -#include "llvm/InstrTypes.h" +#include "llvm/iOperators.h" +#include "llvm/iTerminators.h" #include "llvm/Type.h" #include "llvm/Constants.h" +#include "llvm/Support/CFG.h" #include "llvm/Assembly/Writer.h" +#include "Support/Statistic.h" static bool isLoopInvariant(const Value *V, const Loop *L) { if (isa(V) || isa(V) || isa(V)) @@ -37,14 +41,14 @@ enum InductionVariable::iType InductionVariable::Classify(const Value *Start, const Value *Step, - const Loop *L) { + const Loop *L) { // Check for cannonical and simple linear expressions now... if (const ConstantInt *CStart = dyn_cast(Start)) if (const ConstantInt *CStep = dyn_cast(Step)) { if (CStart->equalsInt(0) && CStep->equalsInt(1)) - return Cannonical; + return Cannonical; else - return SimpleLinear; + return SimpleLinear; } // Without loop information, we cannot do any better, so bail now... @@ -58,7 +62,7 @@ // Create an induction variable for the specified value. If it is a PHI, and // if it's recognizable, classify it and fill in instance variables. // -InductionVariable::InductionVariable(PHINode *P, LoopInfo *LoopInfo) { +InductionVariable::InductionVariable(PHINode *P, LoopInfo *LoopInfo): End(0) { InductionType = Unknown; // Assume the worst Phi = P; @@ -92,7 +96,7 @@ // with respect to the PHI node. // if (E1.ExprTy > ExprType::Constant || E2.ExprTy != ExprType::Linear || - E2.Var != Phi) + E2.Var != Phi) return; // Okay, we have found an induction variable. Save the start and step values @@ -117,17 +121,17 @@ } else if (BinaryOperator *I = dyn_cast(V2)) { // TODO: This could be much better... if (I->getOpcode() == Instruction::Add) { - if (I->getOperand(0) == Phi) - Step = I->getOperand(1); - else if (I->getOperand(1) == Phi) - Step = I->getOperand(0); + if (I->getOperand(0) == Phi) + Step = I->getOperand(1); + else if (I->getOperand(1) == Phi) + Step = I->getOperand(0); } } if (Step == 0) { // Unrecognized step value... ExprType StepE = ClassifyExpression(V2); if (StepE.ExprTy != ExprType::Linear || - StepE.Var != Phi) return; + StepE.Var != Phi) return; const Type *ETy = Phi->getType(); if (isa(ETy)) ETy = Type::ULongTy; @@ -153,6 +157,125 @@ InductionType = InductionVariable::Classify(Start, Step, L); } + +Value* InductionVariable::getExecutionCount(LoopInfo *LoopInfo) { + DEBUG(std::cerr << "entering getExecutionCount\n"); + + // Don't recompute if already available + if (End) { + DEBUG(std::cerr << "returning cached End value.\n"); + return End; + } + + const Loop *L = LoopInfo ? LoopInfo->getLoopFor(Phi->getParent()) : 0; + if (!L) { + DEBUG(std::cerr << "null loop. oops\n"); + return NULL; + } + + // >1 backedge => cannot predict number of iterations + if (Phi->getNumIncomingValues() != 2) { + DEBUG(std::cerr << ">2 incoming values. oops\n"); + return NULL; + } + + // Find final node: predecesor of the loop header that's also an exit + BasicBlock *terminator; + BasicBlock *header = L->getHeader(); + for (pred_iterator PI = pred_begin(header), PE = pred_end(header); + PI != PE; ++PI) { + if (L->isLoopExit(*PI)) { + terminator = *PI; + break; + } + } + + // Break in the loop => cannot predict number of iterations + // break: any block which is an exit node whose successor is not in loop, + // and this block is not marked as the terminator + // + const std::vector &blocks = L->getBlocks(); + for (std::vector::const_iterator i = blocks.begin(), e = blocks.end(); + i != e; ++i) { + if (L->isLoopExit(*i) && (*i != terminator)) { + for (succ_iterator SI = succ_begin(*i), SE = succ_end(*i); SI != SE; ++SI) { + if (! L->contains(*SI)) { + DEBUG(std::cerr << "break found in loop"); + return NULL; + } + } + } + } + + BranchInst *B = dyn_cast(terminator->getTerminator()); + if (!B) { + // this really should not happen + DEBUG(std::cerr << "no terminator instruction!"); + return NULL; + } + SetCondInst *SCI = dyn_cast(&*B->getCondition()); + + if (SCI && InductionType == Cannonical) { + DEBUG(std::cerr << "sci:" << *SCI); + Value *condVal0 = SCI->getOperand(0); + Value *condVal1 = SCI->getOperand(1); + Value *indVar = 0; + + // the induction variable is the one coming from the backedge + if (L->contains(Phi->getIncomingBlock(0))) { + indVar = Phi->getIncomingValue(0); + } else { + indVar = Phi->getIncomingValue(1); + } + + // check to see if indVar is one of the parameters in SCI + // and if the other is loop-invariant, it is the UB + if (indVar == condVal0) { + if (isLoopInvariant(condVal1, L)) { + End = condVal1; + } else { + DEBUG(std::cerr << "not loop invariant 1\n"); + } + } else if (indVar == condVal1) { + if (isLoopInvariant(condVal0, L)) { + End = condVal0; + } else { + DEBUG(std::cerr << "not loop invariant 0\n"); + } + } + + if (End) { + switch (SCI->getOpcode()) { + case Instruction::SetLT: + case Instruction::SetNE: break; // already done + case Instruction::SetLE: { + // if compared to a constant int N, then predict N+1 iterations + if (ConstantSInt *ubSigned = dyn_cast(End)) { + End = ConstantSInt::get(ubSigned->getType(), ubSigned->getValue()+1); + DEBUG(std::cerr << "signed int constant\n"); + } else if (ConstantUInt *ubUnsigned = dyn_cast(End)) { + End = ConstantUInt::get(ubUnsigned->getType(), ubUnsigned->getValue()+1); + DEBUG(std::cerr << "unsigned int constant\n"); + } else { + DEBUG(std::cerr << "symbolic bound\n"); + //End = NULL; + // new expression N+1 + End = BinaryOperator::create(Instruction::Add, End, + ConstantUInt::get(ubUnsigned->getType(), 1)); + } + break; + } + default: End = NULL; // cannot predict + } + } + return End; + } else { + DEBUG(std::cerr << "SCI null or non-cannonical ind var\n"); + } + return NULL; +} + + void InductionVariable::print(std::ostream &o) const { switch (InductionType) { case InductionVariable::Cannonical: o << "Cannonical "; break; @@ -171,5 +294,8 @@ o << " Start = "; WriteAsOperand(o, Start); o << " Step = " ; WriteAsOperand(o, Step); + if (End) { + o << " End = " ; WriteAsOperand(o, End); + } o << "\n"; } From brukman at cs.uiuc.edu Fri Oct 11 00:35:06 2002 From: brukman at cs.uiuc.edu (Michael Brukman) Date: Fri Oct 11 00:35:06 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/InductionVariable.h Message-ID: <200210110534.AAA19217@trinity.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: InductionVariable.h updated: 1.4 -> 1.5 --- Log message: Added capability to get execution count of a loop if it is a predictable number of iterations. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/InductionVariable.h diff -u llvm/include/llvm/Analysis/InductionVariable.h:1.4 llvm/include/llvm/Analysis/InductionVariable.h:1.5 --- llvm/include/llvm/Analysis/InductionVariable.h:1.4 Fri Jul 26 20:11:59 2002 +++ llvm/include/llvm/Analysis/InductionVariable.h Fri Oct 11 00:34:32 2002 @@ -34,7 +34,7 @@ Unknown, // Unknown type. Start & Step are null } InductionType; - Value *Start, *Step; // Start and step expressions for this indvar + Value *Start, *Step, *End; // Start, step, and end expressions for this indvar PHINode *Phi; // The PHI node that corresponds to this indvar public: @@ -46,6 +46,9 @@ // Classify Induction static enum iType Classify(const Value *Start, const Value *Step, const Loop *L = 0); + + // Get number of times this loop will execute. Returns NULL if unpredictable. + Value* getExecutionCount(LoopInfo *LoopInfo); void print(std::ostream &OS) const; }; From vadve at cs.uiuc.edu Fri Oct 11 11:09:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Oct 11 11:09:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/Makefile Message-ID: <200210111608.LAA09008@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: Makefile updated: 1.5 -> 1.6 --- Log message: Use PARALLEL_DIRS. --- Diffs of the changes: Index: llvm/lib/Analysis/Makefile diff -u llvm/lib/Analysis/Makefile:1.5 llvm/lib/Analysis/Makefile:1.6 --- llvm/lib/Analysis/Makefile:1.5 Tue Jul 23 12:52:24 2002 +++ llvm/lib/Analysis/Makefile Fri Oct 11 11:08:17 2002 @@ -1,6 +1,6 @@ LEVEL = ../.. LIBRARYNAME = analysis -DIRS = LiveVar IPA DataStructure +PARALLEL_DIRS = LiveVar IPA DataStructure BUILD_ARCHIVE = 1 include $(LEVEL)/Makefile.common From vadve at cs.uiuc.edu Fri Oct 11 11:12:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Oct 11 11:12:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSelection/MachineCodeForFunction.cpp Message-ID: <200210111611.LAA09033@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSelection: MachineCodeForFunction.cpp updated: 1.15 -> 1.16 --- Log message: Don't pad variables in stack slots for performance! --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSelection/MachineCodeForFunction.cpp diff -u llvm/lib/CodeGen/InstrSelection/MachineCodeForFunction.cpp:1.15 llvm/lib/CodeGen/InstrSelection/MachineCodeForFunction.cpp:1.16 --- llvm/lib/CodeGen/InstrSelection/MachineCodeForFunction.cpp:1.15 Mon Sep 16 10:18:16 2002 +++ llvm/lib/CodeGen/InstrSelection/MachineCodeForFunction.cpp Fri Oct 11 11:10:53 2002 @@ -85,7 +85,7 @@ "compute MaxOptionalArgsSize"); sizeForThisCall = 0; for (unsigned i = 0; i < numOperands; ++i) - sizeForThisCall += target.findOptimalStorageSize(callInst-> + sizeForThisCall += target.DataLayout.getTypeSize(callInst-> getOperand(i)->getType()); } @@ -190,7 +190,7 @@ "Size of reg spills area has been used to compute an offset so " "no more register spill slots should be allocated!"); - unsigned int size = target.findOptimalStorageSize(type); + unsigned int size = target.DataLayout.getTypeSize(type); unsigned char align = target.DataLayout.getTypeAlignment(type); bool growUp; From vadve at cs.uiuc.edu Fri Oct 11 11:13:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Oct 11 11:13:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Message-ID: <200210111612.LAA09047@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.cpp updated: 1.77 -> 1.78 --- Log message: Major bug fix: spill code for an instruction in a delay slot was merrily being inserted before/after the instruction! --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.77 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.78 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.77 Sat Sep 28 12:02:40 2002 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Fri Oct 11 11:12:40 2002 @@ -419,6 +419,32 @@ // Utility functions used below //----------------------------- inline void +InsertBefore(MachineInstr* newMI, + MachineCodeForBasicBlock& MIVec, + MachineCodeForBasicBlock::iterator& MII) +{ + MII = MIVec.insert(MII, newMI); + ++MII; +} + +inline void +InsertAfter(MachineInstr* newMI, + MachineCodeForBasicBlock& MIVec, + MachineCodeForBasicBlock::iterator& MII) +{ + ++MII; // insert before the next instruction + MII = MIVec.insert(MII, newMI); +} + +inline void +SubstituteInPlace(MachineInstr* newMI, + MachineCodeForBasicBlock& MIVec, + MachineCodeForBasicBlock::iterator MII) +{ + *MII = newMI; +} + +inline void PrependInstructions(vector &IBef, MachineCodeForBasicBlock& MIVec, MachineCodeForBasicBlock::iterator& MII, @@ -434,8 +460,7 @@ if (OrigMI) cerr << "For MInst:\n " << *OrigMI; cerr << msg << "PREPENDed instr:\n " << **AdIt << "\n"; } - MII = MIVec.insert(MII, *AdIt); - ++MII; + InsertBefore(*AdIt, MIVec, MII); } } } @@ -456,8 +481,7 @@ if (OrigMI) cerr << "For MInst:\n " << *OrigMI; cerr << msg << "APPENDed instr:\n " << **AdIt << "\n"; } - ++MII; // insert before the next instruction - MII = MIVec.insert(MII, *AdIt); + InsertAfter(*AdIt, MIVec, MII); } } } @@ -477,7 +501,7 @@ for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end(); BBI != BBE; ++BBI) { - + // iterate over all the machine instructions in BB MachineCodeForBasicBlock &MIVec = MachineCodeForBasicBlock::get(BBI); for (MachineCodeForBasicBlock::iterator MII = MIVec.begin(); @@ -538,13 +562,38 @@ insertCode4SpilledLR(LR, MInst, BBI, OpNum ); } } // for each operand - - + // Now add instructions that the register allocator inserts before/after // this machine instructions (done only for calls/rets/incoming args) // We do this here, to ensure that spill for an instruction is inserted // closest as possible to an instruction (see above insertCode4Spill...) // + // First, if the instruction in the delay slot of a branch needs + // instructions inserted, move it out of the delay slot and before the + // branch because putting code before or after it would be VERY BAD! + // + unsigned bumpIteratorBy = 0; + if (MII != MIVec.begin()) + if (unsigned predDelaySlots = + TM.getInstrInfo().getNumDelaySlots((*(MII-1))->getOpCode())) + { + assert(predDelaySlots==1 && "Not handling multiple delay slots!"); + if (TM.getInstrInfo().isBranch((*(MII-1))->getOpCode()) + && (AddedInstrMap.count(MInst) || + AddedInstrMap[MInst].InstrnsAfter.size() > 0)) + { + // Current instruction is in the delay slot of a branch and it + // needs spill code inserted before or after it. + // Move it before the preceding branch. + InsertBefore(MInst, MIVec, --MII); + MachineInstr* nopI = + new MachineInstr(TM.getInstrInfo().getNOPOpCode()); + SubstituteInPlace(nopI, MIVec, MII+1); // replace orig with NOP + --MII; // point to MInst in new location + bumpIteratorBy = 2; // later skip the branch and the NOP! + } + } + // If there are instructions to be added, *before* this machine // instruction, add them now. // @@ -561,9 +610,18 @@ // added after it must really go after the delayed instruction(s) // So, we move the InstrAfter of the current instruction to the // corresponding delayed instruction - - unsigned delay; - if ((delay=TM.getInstrInfo().getNumDelaySlots(MInst->getOpCode())) >0){ + if (unsigned delay = + TM.getInstrInfo().getNumDelaySlots(MInst->getOpCode())) { + + // Delayed instructions are typically branches or calls. Let's make + // sure this is not a branch, otherwise "insert-after" is meaningless, + // and should never happen for any reason (spill code, register + // restores, etc.). + assert(! TM.getInstrInfo().isBranch(MInst->getOpCode()) && + ! TM.getInstrInfo().isReturn(MInst->getOpCode()) && + "INTERNAL ERROR: Register allocator should not be inserting " + "any code after a branch or return!"); + move2DelayedInstr(MInst, *(MII+delay) ); } else { @@ -572,7 +630,11 @@ AppendInstructions(AddedInstrMap[MInst].InstrnsAfter, MIVec, MII,""); } // if not delay } - + + // If we mucked with the instruction order above, adjust the loop iterator + if (bumpIteratorBy) + MII = MII + bumpIteratorBy; + } // for each machine instruction } } From hldnbrnd at cs.uiuc.edu Fri Oct 11 13:42:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Fri Oct 11 13:42:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200210111841.NAA24638@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.61 -> 1.62 --- Log message: Sun requires you to include stdlib to use malloc --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.61 llvm/lib/CWriter/Writer.cpp:1.62 --- llvm/lib/CWriter/Writer.cpp:1.61 Sat Oct 5 18:43:10 2002 +++ llvm/lib/CWriter/Writer.cpp Fri Oct 11 13:41:44 2002 @@ -514,7 +514,7 @@ } // printing stdlib inclusion - // Out << "#include \n"; + Out << "#include \n"; // get declaration for alloca Out << "/* Provide Declarations */\n" From hldnbrnd at cs.uiuc.edu Fri Oct 11 16:41:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Fri Oct 11 16:41:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200210112140.QAA27967@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.62 -> 1.63 --- Log message: Instead of adding stdlib we just prototype malloc correctly. --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.62 llvm/lib/CWriter/Writer.cpp:1.63 --- llvm/lib/CWriter/Writer.cpp:1.62 Fri Oct 11 13:41:44 2002 +++ llvm/lib/CWriter/Writer.cpp Fri Oct 11 16:40:44 2002 @@ -514,7 +514,7 @@ } // printing stdlib inclusion - Out << "#include \n"; + //Out << "#include \n"; // get declaration for alloca Out << "/* Provide Declarations */\n" @@ -541,6 +541,8 @@ // Global variable declarations... if (!M->gempty()) { Out << "\n/* External Global Variable Declarations */\n"; + // Needed for malloc to work on sun. + Out << "extern void * malloc(size_t);\n"; for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) { if (I->hasExternalLinkage()) { Out << "extern "; From hldnbrnd at cs.uiuc.edu Sat Oct 12 10:11:00 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Sat Oct 12 10:11:00 2002 Subject: [llvm-commits] CVS: llvm/www/docs/TestStatus.html Message-ID: <200210121510.KAA06925@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: TestStatus.html updated: 1.1 -> 1.2 --- Log message: --- Diffs of the changes: Index: llvm/www/docs/TestStatus.html diff -u llvm/www/docs/TestStatus.html:1.1 llvm/www/docs/TestStatus.html:1.2 --- llvm/www/docs/TestStatus.html:1.1 Wed Oct 9 16:49:44 2002 +++ llvm/www/docs/TestStatus.html Fri Oct 11 17:22:12 2002 @@ -24,11 +24,11 @@ hashXXX heapsortXXX helloXXX -listsXXO +listsXXX matrixXXX -methcallXXOSeg Fault +methcallXXX nestedloopXXX -objinstXXOSeg Fault +objinstXXX randomXXX sieveXXX @@ -46,7 +46,7 @@ 08-02-CastTest2XXX 08-02-CastTestXXX CodegenBugXXX -ArrayResolutionXXOSeg Fault +ArrayResolutionXXX

MultiSource

From ashukla at cs.uiuc.edu Sat Oct 12 15:34:01 2002 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Sat Oct 12 15:34:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp Message-ID: <200210122033.PAA04387@trinity.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation/ProfilePaths: ProfilePaths.cpp updated: 1.21 -> 1.22 --- Log message: Changed to external global var --- Diffs of the changes: Index: llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp diff -u llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp:1.21 llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp:1.22 --- llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp:1.21 Fri Sep 20 11:43:27 2002 +++ llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp Sat Oct 12 15:33:47 2002 @@ -190,7 +190,7 @@ static bool insertedThreshold = false; if(!insertedThreshold){ - threshold = new GlobalVariable(Type::IntTy, false, true, 0, + threshold = new GlobalVariable(Type::IntTy, false, false, 0, "reopt_threshold"); F.getParent()->getGlobalList().push_back(threshold); From lattner at cs.uiuc.edu Sat Oct 12 15:51:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Oct 12 15:51:01 2002 Subject: [llvm-commits] CVS: llvm/tools/extract/extract.cpp Message-ID: <200210122050.PAA20180@apoc.cs.uiuc.edu> Changes in directory llvm/tools/extract: extract.cpp updated: 1.11 -> 1.12 --- Log message: * Fix extract to work with constant pointer refs correctly * Extract makes all global vars external, so they don't have initializers --- Diffs of the changes: Index: llvm/tools/extract/extract.cpp diff -u llvm/tools/extract/extract.cpp:1.11 llvm/tools/extract/extract.cpp:1.12 --- llvm/tools/extract/extract.cpp:1.11 Mon Oct 7 13:33:53 2002 +++ llvm/tools/extract/extract.cpp Sat Oct 12 15:50:16 2002 @@ -30,14 +30,16 @@ bool run(Module &M) { // Mark all global variables to be internal for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - if (!I->isExternal()) - I->setInternalLinkage(true); + if (!I->isExternal()) { + I->setInitializer(0); // Make all variables external + I->setInternalLinkage(false); // Make sure it's not internal + } Function *Named = 0; // Loop over all of the functions in the module, dropping all references in // functions that are not the named function. - for (Module::iterator I = M.begin(), E = M.end(); I != E;) + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) // Check to see if this is the named function! if (I->getName() == ExtractFunc && !I->isExternal()) { if (Named) { // Two functions, same name? @@ -51,41 +53,59 @@ // Make sure it's globally accessable... Named->setInternalLinkage(false); - - // Remove the named function from the module. - M.getFunctionList().remove(I); - } else { - // Nope it's not the named function, delete the body of the function - I->dropAllReferences(); - ++I; } - - // All of the functions that still have uses now must be used by global - // variables or the named function. Loop through them and create a new, - // external function for the used ones... making all uses point to the new - // functions. + + if (Named == 0) { + std::cerr << "Warning: Function '" << ExtractFunc << "' not found!\n"; + return false; + } + + // All of the functions may be used by global variables or the named + // function. Loop through them and create a new, external functions that + // can be "used", instead of ones with bodies. + // std::vector NewFunctions; - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->use_empty()) { + Function *Last = &M.back(); // Figure out where the last real fn is... + + for (Module::iterator I = M.begin(); ; ++I) { + if (I->getName() != ExtractFunc) { Function *New = new Function(I->getFunctionType(), false, I->getName()); - I->replaceAllUsesWith(New); + I->setName(""); // Remove Old name + + // If it's not the named function, delete the body of the function + I->dropAllReferences(); + + M.getFunctionList().push_back(New); NewFunctions.push_back(New); } + + if (&*I == Last) break; // Stop after processing the last function + } + + // Now that we have replacements all set up, loop through the module, + // deleting the old functions, replacing them with the newly created + // functions. + if (!NewFunctions.empty()) { + unsigned FuncNum = 0; + Module::iterator I = M.begin(); + do { + if (I->getName() != ExtractFunc) { + // Make everything that uses the old function use the new dummy fn + I->replaceAllUsesWith(NewFunctions[FuncNum++]); + + Function *Old = I; + ++I; // Move the iterator to the new function + + // Delete the old function! + M.getFunctionList().erase(Old); + + } else { + ++I; // Skip the function we are extracting + } + } while (&*I != NewFunctions[0]); + } - // Now the module only has unused functions with their references dropped. - // Delete them all now! - M.getFunctionList().clear(); - - // Re-insert the named function... - if (Named) - M.getFunctionList().push_back(Named); - else - std::cerr << "Warning: Function '" << ExtractFunc << "' not found!\n"; - - // Insert all of the function stubs... - M.getFunctionList().insert(M.end(), NewFunctions.begin(), - NewFunctions.end()); return true; } }; @@ -109,6 +129,7 @@ PassManager Passes; Passes.add(new FunctionExtractorPass()); Passes.add(createGlobalDCEPass()); // Delete unreachable globals + Passes.add(createFunctionResolvingPass()); // Delete prototypes Passes.add(createConstantMergePass()); // Merge dup global constants Passes.add(createDeadTypeEliminationPass()); // Remove dead types... Passes.add(new WriteBytecodePass(&std::cout)); // Write bytecode to file... From lattner at cs.uiuc.edu Sat Oct 12 16:17:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Oct 12 16:17:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2002-10-12-StructureArgs.c Message-ID: <200210122116.QAA21355@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/UnitTests: 2002-10-12-StructureArgs.c added (r1.1) --- Log message: New testcase distilled out of voronoi --- Diffs of the changes: From lattner at cs.uiuc.edu Sat Oct 12 16:30:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Oct 12 16:30:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2002-10-12-StructureArgsSimple.c Message-ID: <200210122129.QAA21532@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/UnitTests: 2002-10-12-StructureArgsSimple.c added (r1.1) --- Log message: Simplified version of previous testcase --- Diffs of the changes: From lattner at cs.uiuc.edu Sat Oct 12 18:38:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Oct 12 18:38:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2002-10-12-TooManyArguments.c Message-ID: <200210122337.SAA31194@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2002-10-12-TooManyArguments.c added (r1.1) --- Log message: New testcase that causes invalid llvm to be emitted by cfe --- Diffs of the changes: From vadve at cs.uiuc.edu Sat Oct 12 18:48:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 18:48:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/LLC/globalrefs.c Message-ID: <200210122347.SAA17164@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/LLC: globalrefs.c updated: 1.1 -> 1.2 --- Log message: Added inline constant expressions, including uses in binary subtract. --- Diffs of the changes: Index: llvm/test/Regression/LLC/globalrefs.c diff -u llvm/test/Regression/LLC/globalrefs.c:1.1 llvm/test/Regression/LLC/globalrefs.c:1.2 --- llvm/test/Regression/LLC/globalrefs.c:1.1 Fri Sep 27 08:27:14 2002 +++ llvm/test/Regression/LLC/globalrefs.c Sat Oct 12 18:47:36 2002 @@ -1,5 +1,6 @@ -/* globalrefs.c - Test constant expressions constructed from global - * addresses and index expressions into global addresses. +/* globalrefs.c - Test symbolic constant expressions constructed from + * global addresses and index expressions into global addresses. + * Do this both with global constants and with inline constant. * Instead of printing absolute addresses, print out the differences in * memory addresses to get output that matches that of the native compiler. */ @@ -18,23 +19,51 @@ struct test TestArray[10]; struct test Test1; -struct test* TestArrayPtr = TestArray; +/* Create global symbolic constants from the addresses of the above globals */ + +struct test* TestArrayPtr = &TestArray[3]; long* Aptr = &Test1.A; -unsigned* Xptr = &Test1.S.X; +unsigned* Yptr = &Test1.S.Y; +struct test** NextPtr = &Test1.next; + +void +printdiff(void* p1, void* p2) +{ + printf(" 0x%lx", (unsigned long) p1 - (unsigned long) p2); +} int main(int argc, char** argv) { - void* a1 = (void*) TestArrayPtr; - void* a2 = (void*) Aptr; - void* a3 = (void*) Xptr; - -#ifdef WANT_ABSOLUTE_ADDRESSES - printf("Aptr = 0x%lx, Xptr = 0x%lx, TestArrayPtr = 0x%lx\n", - Aptr, Xptr, TestArrayPtr); -#endif + unsigned long diff1, diff2, diff3, diff4; + + printf("sizeof(struct Test) = %llu\n\n", sizeof(struct test)); + + printdiff(&TestArray[3], TestArray); + printdiff(&Test1.A, &TestArray[3]); + printdiff(&Test1.S.Y, &Test1.A); + printdiff(&Test1.next, &Test1.S.Y); + printf("\n"); + + diff1 = (unsigned long) &TestArray[3] - (unsigned long) TestArray; + diff2 = (unsigned long) &Test1.A - (unsigned long) &TestArray[3]; + diff3 = (unsigned long) &Test1.S.Y - (unsigned long) &Test1.A; + diff4 = (unsigned long) &Test1.next - (unsigned long) &Test1.S.Y; + + printf("&TestArray[3] - TestArray = 0x%lx\n", diff1); + printf("Aptr - &TestArray[3] = 0x%lx\n", diff2); + printf("Xptr - Aptr = 0x%lx\n", diff3); + printf("NextPtr - Xptr = 0x%lx\n\n", diff4); + + diff1 = (unsigned long) TestArrayPtr - (unsigned long) TestArray; + diff2 = (unsigned long) Aptr - (unsigned long) TestArrayPtr; + diff3 = (unsigned long) Yptr - (unsigned long) Aptr; + diff4 = (unsigned long) NextPtr - (unsigned long) Yptr; + + printf("&TestArray[3] - TestArray = 0x%lx\n", diff1); + printf("Aptr - &TestArray[3] = 0x%lx\n", diff2); + printf("Xptr - Aptr = 0x%lx\n", diff3); + printf("NextPtr - Xptr = 0x%lx\n\n", diff4); - printf("Aptr - TestArrayPtr = 0x%lx, Xptr - Aptr = 0x%lx\n", - (uint64_t) a2 - (uint64_t) a1, (uint64_t) a3 - (uint64_t) a2); return 0; } From vadve at cs.uiuc.edu Sat Oct 12 19:03:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:03:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PreOpts/PreSelection.cpp Message-ID: <200210130002.TAA17349@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/PreOpts: PreSelection.cpp updated: 1.2 -> 1.3 --- Log message: Major fix: extract ConstantExpr nodes and decompose them into symbolic instructions so that (a) constant folding is done automatically before code generation, and (b) selection does not have to deal with them. Also, check for ConstantPointerRefs in additional to GlobalValues when creating a GEP to load a global address. --- Diffs of the changes: Index: llvm/lib/CodeGen/PreOpts/PreSelection.cpp diff -u llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.2 llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.3 --- llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.2 Fri Sep 27 09:24:45 2002 +++ llvm/lib/CodeGen/PreOpts/PreSelection.cpp Sat Oct 12 19:01:57 2002 @@ -23,8 +23,8 @@ #include "llvm/Annotation.h" #include "Support/CommandLine.h" #include "Support/NonCopyable.h" -using std::map; -using std::cerr; +#include +using namespace std; namespace { //===--------------------------------------------------------------------===// @@ -51,7 +51,7 @@ // The pool of constants that must be emitted for a module. // This is a single pool for the entire module and is shared by // all invocations of the PreSelection pass for this module by putting - // this as as annotation on the Module object. + // this as an annotation on the Module object. // A single GlobalVariable is created for each constant in the pool // representing the memory for that constant. // @@ -118,8 +118,6 @@ const TargetMachine ⌖ Function* function; - GetElementPtrInst* getGlobalAddr(Value* ptr, Instruction* insertBefore = 0); - GlobalVariable* getGlobalForConstant(Constant* CV) { Module* M = function->getParent(); return ConstantPoolForModule::get(M).getGlobalForConstant(CV); @@ -162,18 +160,76 @@ "Specialize LLVM code for a target machine", createPreSelectionPass); -// PreSelection::getGlobalAddr: Put address of a global into a v. register. -GetElementPtrInst* -PreSelection::getGlobalAddr(Value* ptr, Instruction* insertBefore) +//------------------------------------------------------------------------------ +// Helper functions used by methods of class PreSelection +//------------------------------------------------------------------------------ + + +// getGlobalAddr(): Put address of a global into a v. register. +static GetElementPtrInst* getGlobalAddr(Value* ptr, Instruction& insertBefore) { + if (isa(ptr)) + ptr = cast(ptr)->getValue(); + return (isa(ptr)) ? new GetElementPtrInst(ptr, std::vector(1, ConstantSInt::get(Type::LongTy, 0U)), - "addrOfGlobal", insertBefore) + "addrOfGlobal", &insertBefore) : NULL; } +// Wrapper on Constant::classof to use in find_if :-( +inline static bool nonConstant(const Use& U) +{ + return ! isa(U); +} + + +static Instruction* DecomposeConstantExpr(ConstantExpr* CE, + Instruction& insertBefore) +{ + Value *getArg1, *getArg2; + + switch(CE->getOpcode()) + { + case Instruction::Cast: + getArg1 = CE->getOperand(0); + if (ConstantExpr* CEarg = dyn_cast(getArg1)) + getArg1 = DecomposeConstantExpr(CEarg, insertBefore); + return new CastInst(getArg1, CE->getType(), "constantCast",&insertBefore); + + case Instruction::GetElementPtr: +# ifndef NDEBUG + assert(find_if(++CE->op_begin(), CE->op_end(),nonConstant) == CE->op_end() + && "All indices in ConstantExpr getelementptr must be constant!"); +# endif + getArg1 = CE->getOperand(0); + if (ConstantExpr* CEarg = dyn_cast(getArg1)) + getArg1 = DecomposeConstantExpr(CEarg, insertBefore); + else if (GetElementPtrInst* gep = getGlobalAddr(getArg1, insertBefore)) + getArg1 = gep; + return new GetElementPtrInst(getArg1, + std::vector(++CE->op_begin(), CE->op_end()), + "constantGEP", &insertBefore); + + default: // must be a binary operator + assert(CE->getOpcode() >= Instruction::FirstBinaryOp && + CE->getOpcode() < Instruction::NumBinaryOps && + "Unrecognized opcode in ConstantExpr"); + getArg1 = CE->getOperand(0); + if (ConstantExpr* CEarg = dyn_cast(getArg1)) + getArg1 = DecomposeConstantExpr(CEarg, insertBefore); + getArg2 = CE->getOperand(1); + if (ConstantExpr* CEarg = dyn_cast(getArg2)) + getArg2 = DecomposeConstantExpr(CEarg, insertBefore); + return BinaryOperator::create((Instruction::BinaryOps) CE->getOpcode(), + getArg1, getArg2, + "constantBinaryOp", &insertBefore); + } +} + + //------------------------------------------------------------------------------ // Instruction visitor methods to perform instruction-specific operations //------------------------------------------------------------------------------ @@ -192,7 +248,7 @@ PreSelection::visitGetElementPtrInst(GetElementPtrInst &I) { // Check for a global and put its address into a register before this instr - if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), &I)) + if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I)) I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand // Decompose multidimensional array references @@ -208,7 +264,7 @@ PreSelection::visitLoadInst(LoadInst &I) { // Check for a global and put its address into a register before this instr - if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), &I)) + if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I)) I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand // Perform other transformations common to all instructions @@ -221,7 +277,7 @@ PreSelection::visitStoreInst(StoreInst &I) { // Check for a global and put its address into a register before this instr - if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), &I)) + if (GetElementPtrInst* gep = getGlobalAddr(I.getPointerOperand(), I)) I.setOperand(I.getPointerOperandIndex(), gep); // replace pointer operand // Perform other transformations common to all instructions @@ -229,12 +285,14 @@ } -// Cast instructions: make multi-step casts explicit -// -- float/double to uint32_t: -// If target does not have a float-to-unsigned instruction, we -// need to convert to uint64_t and then to uint32_t, or we may -// overflow the signed int representation for legal uint32_t -// values. Expand this without checking target. +// Cast instructions: +// -- check if argument is a global +// -- make multi-step casts explicit: +// -- float/double to uint32_t: +// If target does not have a float-to-unsigned instruction, we +// need to convert to uint64_t and then to uint32_t, or we may +// overflow the signed int representation for legal uint32_t +// values. Expand this without checking target. // void PreSelection::visitCastInst(CastInst &I) @@ -242,8 +300,12 @@ CastInst* castI = NULL; // Check for a global and put its address into a register before this instr - if (I.getType() == Type::UIntTy && - I.getOperand(0)->getType()->isFloatingPoint()) + if (GetElementPtrInst* gep = getGlobalAddr(I.getOperand(0), I)) + { + I.setOperand(0, gep); // replace pointer operand + } + else if (I.getType() == Type::UIntTy && + I.getOperand(0)->getType()->isFloatingPoint()) { // insert a cast-fp-to-long before I, and then replace the operand of I castI = new CastInst(I.getOperand(0), Type::LongTy, "fp2Long2Uint", &I); I.setOperand(0, castI); // replace fp operand with long @@ -287,10 +349,15 @@ PreSelection::visitOneOperand(Instruction &I, Constant* CV, unsigned opNum, Instruction& insertBefore) { - if (target.getInstrInfo().ConstantTypeMustBeLoaded(CV)) + if (ConstantExpr* CE = dyn_cast(CV)) + { // load-time constant: factor it out so we optimize as best we can + Instruction* computeConst = DecomposeConstantExpr(CE, insertBefore); + I.setOperand(opNum, computeConst); // replace expr operand with result + } + else if (target.getInstrInfo().ConstantTypeMustBeLoaded(CV)) { // load address of constant into a register, then load the constant GetElementPtrInst* gep = getGlobalAddr(getGlobalForConstant(CV), - &insertBefore); + insertBefore); LoadInst* ldI = new LoadInst(gep, "loadConst", &insertBefore); I.setOperand(opNum, ldI); // replace operand with copy in v.reg. } @@ -301,6 +368,7 @@ I.setOperand(opNum, castI); // replace operand with copy in v.reg. } } + //===----------------------------------------------------------------------===// // createPreSelectionPass - Public entrypoint for pre-selection pass From vadve at cs.uiuc.edu Sat Oct 12 19:05:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:05:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrInfo.cpp Message-ID: <200210130004.TAA17369@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrInfo.cpp updated: 1.28 -> 1.29 --- Log message: Make sure to handle small negative values hiding as large unsigned longs -- this is a common case created by the front-end. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrInfo.cpp diff -u llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.28 llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.29 --- llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.28 Fri Sep 27 09:29:45 2002 +++ llvm/lib/Target/Sparc/SparcInstrInfo.cpp Sat Oct 12 19:04:26 2002 @@ -266,7 +266,7 @@ // Entry == 0 ==> no immediate constant field exists at all. // Entry > 0 ==> abs(immediate constant) <= Entry // -vector MaxConstantsTable(Instruction::NumOtherOps); +vector MaxConstantsTable(Instruction::NumOtherOps); static int MaxConstantForInstr(unsigned llvmOpCode) @@ -343,13 +343,14 @@ return false; if (const ConstantUInt* U = dyn_cast(CV)) - return (U->getValue() > MaxConstantsTable[I->getOpcode()]); + /* Large unsigned longs may really just be small negative signed longs */ + return (labs((int64_t) U->getValue()) > MaxConstantsTable[I->getOpcode()]); if (const ConstantSInt* S = dyn_cast(CV)) - return (labs(S->getValue()) > (int) MaxConstantsTable[I->getOpcode()]); + return (labs(S->getValue()) > MaxConstantsTable[I->getOpcode()]); if (isa(CV)) - return (1U > MaxConstantsTable[I->getOpcode()]); + return (1 > MaxConstantsTable[I->getOpcode()]); return true; } @@ -380,6 +381,11 @@ // const Type* valType = val->getType(); + // Unfortunate special case: a ConstantPointerRef is just a + // reference to GlobalValue. + if (isa(val)) + val = cast(val)->getValue(); + if (isa(val)) { TmpInstruction* tmpReg = From vadve at cs.uiuc.edu Sat Oct 12 19:06:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:06:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcRegInfo.cpp Message-ID: <200210130005.TAA17382@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcRegInfo.cpp updated: 1.72 -> 1.73 --- Log message: Eliminate duplicate target pointer. Also add a few assertions. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcRegInfo.cpp diff -u llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.72 llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.73 --- llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.72 Sat Sep 28 11:59:05 2002 +++ llvm/lib/Target/Sparc/SparcRegInfo.cpp Sat Oct 12 19:05:30 2002 @@ -26,7 +26,7 @@ using std::vector; UltraSparcRegInfo::UltraSparcRegInfo(const UltraSparc &tgt) - : MachineRegInfo(tgt), UltraSparcInfo(&tgt), NumOfIntArgRegs(6), + : MachineRegInfo(tgt), NumOfIntArgRegs(6), NumOfFloatArgRegs(32), InvalidRegNum(1000) { MachineRegClassArr.push_back(new SparcIntRegClass(IntRegClassID)); @@ -564,7 +564,7 @@ //--------------------------------------------------------------------------- void UltraSparcRegInfo::suggestRegs4CallArgs(MachineInstr *CallMI, LiveRangeInfo& LRI) const { - assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) ); + assert ( (target.getInstrInfo()).isCall(CallMI->getOpCode()) ); CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI); @@ -750,7 +750,7 @@ PhyRegAlloc &PRA, const BasicBlock *BB) const { - assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) ); + assert ( (target.getInstrInfo()).isCall(CallMI->getOpCode()) ); CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI); @@ -955,7 +955,7 @@ void UltraSparcRegInfo::suggestReg4RetValue(MachineInstr *RetMI, LiveRangeInfo &LRI) const { - assert( (UltraSparcInfo->getInstrInfo()).isReturn( RetMI->getOpCode() ) ); + assert( (target.getInstrInfo()).isReturn( RetMI->getOpCode() ) ); suggestReg4RetAddr(RetMI, LRI); @@ -993,7 +993,7 @@ LiveRangeInfo &LRI, AddedInstrns *RetAI) const { - assert((UltraSparcInfo->getInstrInfo()).isReturn( RetMI->getOpCode())); + assert((target.getInstrInfo()).isReturn( RetMI->getOpCode())); // if there is an implicit ref, that has to be the ret value if(RetMI->getNumImplicitRefs() > 0) { @@ -1149,6 +1149,7 @@ MachineInstr * MI = NULL; switch( RegType ) { case IntRegType: + assert(target.getInstrInfo().constantFitsInImmedField(STX, Offset)); MI = new MachineInstr(STX, 3); MI->SetMachineOperandReg(0, SrcReg, false); MI->SetMachineOperandReg(1, DestPtrReg, false); @@ -1158,6 +1159,7 @@ break; case FPSingleRegType: + assert(target.getInstrInfo().constantFitsInImmedField(ST, Offset)); MI = new MachineInstr(ST, 3); MI->SetMachineOperandReg(0, SrcReg, false); MI->SetMachineOperandReg(1, DestPtrReg, false); @@ -1167,6 +1169,7 @@ break; case FPDoubleRegType: + assert(target.getInstrInfo().constantFitsInImmedField(STD, Offset)); MI = new MachineInstr(STD, 3); MI->SetMachineOperandReg(0, SrcReg, false); MI->SetMachineOperandReg(1, DestPtrReg, false); @@ -1188,6 +1191,7 @@ case FloatCCRegType: assert(0 && "Tell Vikram if this assertion fails: we may have to mask out the other bits here"); + assert(target.getInstrInfo().constantFitsInImmedField(STXFSR, Offset)); MI = new MachineInstr(STXFSR, 3); MI->SetMachineOperandReg(0, SrcReg, false); MI->SetMachineOperandReg(1, DestPtrReg, false); @@ -1218,6 +1222,7 @@ MachineInstr * MI = NULL; switch (RegType) { case IntRegType: + assert(target.getInstrInfo().constantFitsInImmedField(LDX, Offset)); MI = new MachineInstr(LDX, 3); MI->SetMachineOperandReg(0, SrcPtrReg, false); MI->SetMachineOperandConst(1, MachineOperand:: MO_SignExtendedImmed, @@ -1227,6 +1232,7 @@ break; case FPSingleRegType: + assert(target.getInstrInfo().constantFitsInImmedField(LD, Offset)); MI = new MachineInstr(LD, 3); MI->SetMachineOperandReg(0, SrcPtrReg, false); MI->SetMachineOperandConst(1, MachineOperand:: MO_SignExtendedImmed, @@ -1236,6 +1242,7 @@ break; case FPDoubleRegType: + assert(target.getInstrInfo().constantFitsInImmedField(LDD, Offset)); MI = new MachineInstr(LDD, 3); MI->SetMachineOperandReg(0, SrcPtrReg, false); MI->SetMachineOperandConst(1, MachineOperand:: MO_SignExtendedImmed, @@ -1257,6 +1264,7 @@ case FloatCCRegType: assert(0 && "Tell Vikram if this assertion fails: we may have to mask out the other bits here"); + assert(target.getInstrInfo().constantFitsInImmedField(LDXFSR, Offset)); MI = new MachineInstr(LDXFSR, 3); MI->SetMachineOperandReg(0, SrcPtrReg, false); MI->SetMachineOperandConst(1, MachineOperand:: MO_SignExtendedImmed, @@ -1342,7 +1350,7 @@ const BasicBlock *BB, PhyRegAlloc &PRA) const { - assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) ); + assert ( (target.getInstrInfo()).isCall(CallMI->getOpCode()) ); // has set to record which registers were saved/restored // From vadve at cs.uiuc.edu Sat Oct 12 19:07:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:07:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInternals.h Message-ID: <200210130006.TAA17398@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInternals.h updated: 1.66 -> 1.67 --- Log message: Eliminate duplicate target pointer in SparcRegInfo. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInternals.h diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.66 llvm/lib/Target/Sparc/SparcInternals.h:1.67 --- llvm/lib/Target/Sparc/SparcInternals.h:1.66 Sat Sep 28 11:56:39 2002 +++ llvm/lib/Target/Sparc/SparcInternals.h Sat Oct 12 19:06:04 2002 @@ -250,10 +250,6 @@ // order for efficiency. - // reverse pointer to get info about the ultra sparc machine - // - const UltraSparc *const UltraSparcInfo; - // Number of registers used for passing int args (usually 6: %o0 - %o5) // unsigned const NumOfIntArgRegs; @@ -328,13 +324,6 @@ public: UltraSparcRegInfo(const UltraSparc &tgt); - - // To get complete machine information structure using the machine register - // information - // - inline const UltraSparc &getUltraSparcInfo() const { - return *UltraSparcInfo; - } // To find the register class used for a specified Type // From vadve at cs.uiuc.edu Sat Oct 12 19:20:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:20:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200210130019.TAA17430@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.74 -> 1.75 --- Log message: (1) Try to evaluate constant when multiplying 2 constants. (2) Use intelligent multiply selection code for array allocas. (3) Don't use cache padding for alloca'd stack slots! (4) Bug fix in handling call arguments: was not copying sixth FP arg to int reg. when calling a function with no prototype. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.74 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.75 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.74 Sat Sep 28 11:55:41 2002 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Sat Oct 12 19:18:57 2002 @@ -20,6 +20,7 @@ #include "llvm/iOther.h" #include "llvm/Function.h" #include "llvm/Constants.h" +#include "llvm/ConstantHandling.h" #include "Support/MathExtras.h" #include using std::vector; @@ -664,18 +665,10 @@ { Value* constOp; if (isa(lval) && isa(rval)) - { // both operands are constant: try both orders! - vector mvec1, mvec2; - unsigned int lcost = CreateMulConstInstruction(target, F, lval, rval, - destVal, mvec1, mcfi); - unsigned int rcost = CreateMulConstInstruction(target, F, rval, lval, - destVal, mvec2, mcfi); - vector& mincostMvec = (lcost <= rcost)? mvec1 : mvec2; - vector& maxcostMvec = (lcost <= rcost)? mvec2 : mvec1; - mvec.insert(mvec.end(), mincostMvec.begin(), mincostMvec.end()); - - for (unsigned int i=0; i < maxcostMvec.size(); ++i) - delete maxcostMvec[i]; + { // both operands are constant: evaluate and "set" in dest + Constant* P = ConstantFoldBinaryInstruction(Instruction::Mul, + cast(lval), cast(rval)); + target.getInstrInfo().CreateCodeToLoadConst(target,F,P,destVal,mvec,mcfi); } else if (isa(rval)) // rval is constant, but not lval CreateMulConstInstruction(target, F, lval, rval, destVal, mvec, mcfi); @@ -841,7 +834,8 @@ vector& getMvec) { MachineInstr* M; - + MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(result); + // Create a Value to hold the (constant) element size Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize); @@ -858,14 +852,11 @@ // Create a temporary value to hold the result of MUL TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal); - MachineCodeForInstruction::get(result).addTemp(tmpProd); + mcfi.addTemp(tmpProd); // Instruction 1: mul numElements, typeSize -> tmpProd - M = new MachineInstr(MULX); - M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, numElementsVal); - M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tsizeVal); - M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, tmpProd); - getMvec.push_back(M); + CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd, getMvec, + mcfi, INVALID_MACHINE_OPCODE); // Instruction 2: sub %sp, tmpProd -> %sp M = new MachineInstr(SUB); @@ -890,6 +881,7 @@ unsigned int numElements, vector& getMvec) { + assert(tsize > 0 && "Illegal (zero) type size for alloca"); assert(result && result->getParent() && "Result value is not part of a function?"); Function *F = result->getParent()->getParent(); @@ -1009,13 +1001,11 @@ target.DataLayout.getTypeSize(eltType)); // CreateMulInstruction() folds constants intelligently enough. - CreateMulInstruction(target, - memInst->getParent()->getParent(), + CreateMulInstruction(target, memInst->getParent()->getParent(), idxVal, /* lval, not likely to be const*/ eltSizeVal, /* rval, likely to be constant */ addr, /* result */ - mulVec, - MachineCodeForInstruction::get(memInst), + mulVec, MachineCodeForInstruction::get(memInst), INVALID_MACHINE_OPCODE); // Insert mulVec[] before *mvecI in mvec[] and update mvecI @@ -1925,18 +1915,18 @@ mvec.push_back(new MachineInstr(ADD)); SetOperandsForMemInstr(mvec, subtreeRoot, target); break; - + case 57: // reg: Alloca: Implement as 1 instruction: { // add %fp, offsetFromFP -> result AllocationInst* instr = cast(subtreeRoot->getInstruction()); unsigned int tsize = - target.findOptimalStorageSize(instr->getAllocatedType()); + target.DataLayout.getTypeSize(instr->getAllocatedType()); assert(tsize != 0); CreateCodeForFixedSizeAlloca(target, instr, tsize, 1, mvec); break; } - + case 58: // reg: Alloca(reg): Implement as 3 instructions: // mul num, typeSz -> tmp // sub %sp, tmp -> %sp @@ -1946,7 +1936,7 @@ const Type* eltType = instr->getAllocatedType(); // If #elements is constant, use simpler code for fixed-size allocas - int tsize = (int) target.findOptimalStorageSize(eltType); + int tsize = (int) target.DataLayout.getTypeSize(eltType); Value* numElementsVal = NULL; bool isArray = instr->isArrayAllocation(); @@ -1963,7 +1953,7 @@ numElementsVal, mvec); break; } - + case 61: // reg: Call { // Generate a direct (CALL) or indirect (JMPL) call. // Mark the return-address register, the indirection @@ -2027,7 +2017,7 @@ // If this arg. is in the first $K$ regs, add a copy // float-to-int instruction to pass the value as an integer. - if (i < target.getRegInfo().GetNumOfIntArgRegs()) + if (i <= target.getRegInfo().GetNumOfIntArgRegs()) { MachineCodeForInstruction &destMCFI = MachineCodeForInstruction::get(callInstr); From vadve at cs.uiuc.edu Sat Oct 12 19:21:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:21:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcOptInfo.cpp Message-ID: <200210130020.TAA17445@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcOptInfo.cpp updated: 1.2 -> 1.3 --- Log message: Test both operands of ADD or OR for zero to find useless copies. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcOptInfo.cpp diff -u llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.2 llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.3 --- llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.2 Fri Sep 27 09:30:49 2002 +++ llvm/lib/Target/Sparc/SparcOptInfo.cpp Sat Oct 12 19:20:15 2002 @@ -29,19 +29,29 @@ } else if (MI->getOpCode() == ADD || MI->getOpCode() == OR) { - return (/* operand 0 are operand 2 are allocated to the same register */ - (MI->getOperand(0).getAllocatedRegNum() == - MI->getOperand(2).getAllocatedRegNum()) && - - (/* and: either operand 1 is register %g0 */ - (MI->getOperand(1).hasAllocatedReg() && - MI->getOperand(1).getAllocatedRegNum() == - target.getRegInfo().getZeroRegNum()) || - - /* or operand 1 == 0 */ - (MI->getOperand(1).getOperandType() - == MachineOperand::MO_SignExtendedImmed && - MI->getOperand(1).getImmedValue() == 0))); + unsigned srcWithDestReg; + + for (srcWithDestReg = 0; srcWithDestReg < 2; ++srcWithDestReg) + if (MI->getOperand(srcWithDestReg).hasAllocatedReg() && + MI->getOperand(srcWithDestReg).getAllocatedRegNum() + == MI->getOperand(2).getAllocatedRegNum()) + break; + + if (srcWithDestReg == 2) + return false; + else + {/* else source and dest are allocated to the same register */ + unsigned otherOp = 1 - srcWithDestReg; + return (/* either operand otherOp is register %g0 */ + (MI->getOperand(otherOp).hasAllocatedReg() && + MI->getOperand(otherOp).getAllocatedRegNum() == + target.getRegInfo().getZeroRegNum()) || + + /* or operand otherOp == 0 */ + (MI->getOperand(otherOp).getOperandType() + == MachineOperand::MO_SignExtendedImmed && + MI->getOperand(otherOp).getImmedValue() == 0)); + } } else return false; From vadve at cs.uiuc.edu Sat Oct 12 19:23:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:23:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstr.def Message-ID: <200210130022.TAA17460@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstr.def updated: 1.11 -> 1.12 --- Log message: Don't mark JMPLCALL and JMPLRET as branches. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstr.def diff -u llvm/lib/Target/Sparc/SparcInstr.def:1.11 llvm/lib/Target/Sparc/SparcInstr.def:1.12 --- llvm/lib/Target/Sparc/SparcInstr.def:1.11 Sat Sep 28 12:00:15 2002 +++ llvm/lib/Target/Sparc/SparcInstr.def Sat Oct 12 19:22:32 2002 @@ -429,10 +429,10 @@ // Call, Return and "Jump and link". Operand (2) for JMPL is marked as // a "result" because JMPL stores the return address for the call in it. // Latency includes the delay slot. -I(CALL , "call", 1, -1, B29, true , 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_CALL_FLAG) -I(JMPLCALL, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_CALL_FLAG ) -I(JMPLRET, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_RET_FLAG) -I(RETURN, "return", 2, -1, 0, false, 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_RET_FLAG) +I(CALL , "call", 1, -1, B29, true , 1, 2, SPARC_CTI, M_CALL_FLAG) +I(JMPLCALL, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_CALL_FLAG) +I(JMPLRET, "jmpl", 3, 2, B12, true , 1, 2, SPARC_CTI, M_RET_FLAG) +I(RETURN, "return", 2, -1, 0, false, 1, 2, SPARC_CTI, M_RET_FLAG) // SAVE and restore instructions I(SAVE , "save", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG) From vadve at cs.uiuc.edu Sat Oct 12 19:25:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:25:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp Message-ID: <200210130024.TAA17474@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: PrologEpilogCodeInserter.cpp updated: 1.13 -> 1.14 --- Log message: Don't use %l0 for large operands to a SAVE since it is needed *before* SAVE! We now use %g1 instead since that is shared and volatile. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp diff -u llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.13 llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.14 --- llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp:1.13 Mon Sep 16 10:39:26 2002 +++ llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp Sat Oct 12 19:24:06 2002 @@ -58,15 +58,14 @@ // The second operand is the stack size. If it does not fit in the // immediate field, we have to use a free register to hold the size. - // We will assume that local register `l0' is unused since the SAVE - // instruction must be the first instruction in each procedure. + // See the comments below for the choice of this register. // MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(&F); unsigned int staticStackSize = mcInfo.getStaticStackSize(); if (staticStackSize < (unsigned) frameInfo.getMinStackFrameSize()) staticStackSize = (unsigned) frameInfo.getMinStackFrameSize(); - + if (unsigned padsz = (staticStackSize % (unsigned) frameInfo.getStackFrameSizeAlignment())) staticStackSize += frameInfo.getStackFrameSizeAlignment() - padsz; @@ -83,13 +82,14 @@ else { // We have to put the stack size value into a register before SAVE. - // Use register %l0 to since it must be unused at function entry. + // Use register %g1 since it is volatile across calls. Note that the + // local (%l) and in (%i) registers cannot be used before the SAVE! // Do this by creating a code sequence equivalent to: - // SETSW -(stackSize), %l0 + // SETSW -(stackSize), %g1 int32_t C = - (int) staticStackSize; int uregNum = Target.getRegInfo().getUnifiedRegNum( Target.getRegInfo().getRegClassIDOfType(Type::IntTy), - SparcIntRegClass::l0); + SparcIntRegClass::g1); M = new MachineInstr(SETHI); M->SetMachineOperandConst(0, MachineOperand::MO_SignExtendedImmed, C); @@ -110,7 +110,7 @@ M->SetMachineOperandReg(2, uregNum); mvec.push_back(M); - // Now generate the SAVE using the value in register %l0 + // Now generate the SAVE using the value in register %g1 M = new MachineInstr(SAVE); M->SetMachineOperandReg(0, Target.getRegInfo().getStackPointer()); M->SetMachineOperandReg(1, uregNum); From vadve at cs.uiuc.edu Sat Oct 12 19:33:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:33:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/EmitAssembly.cpp Message-ID: <200210130032.TAA17498@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: EmitAssembly.cpp updated: 1.60 -> 1.61 --- Log message: Several major fixes, particularly in emitting constant aggregates: (1) Padding bytes between structure fields (for alignment) were never being emitted into the constant pool so the layout did not match! (2) In printing constants, structures containing structures or arrays were never handled. (3) Support new model for external/uninitialized/initialized globals. Uninitialized globals are no longer emitted since they are external. Initialized globals may go either in .bss or in .data. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/EmitAssembly.cpp diff -u llvm/lib/Target/Sparc/EmitAssembly.cpp:1.60 llvm/lib/Target/Sparc/EmitAssembly.cpp:1.61 --- llvm/lib/Target/Sparc/EmitAssembly.cpp:1.60 Mon Sep 16 10:54:02 2002 +++ llvm/lib/Target/Sparc/EmitAssembly.cpp Sat Oct 12 19:32:18 2002 @@ -60,7 +60,7 @@ Text, ReadOnlyData, InitRWData, - UninitRWData, + ZeroInitRWData, } CurSection; AsmPrinter(std::ostream &os, const TargetMachine &T) @@ -105,7 +105,7 @@ case Text: toAsm << "\".text\""; break; case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break; case InitRWData: toAsm << "\".data\",#alloc,#write"; break; - case UninitRWData: toAsm << "\".bss\",#alloc,#write"; break; + case ZeroInitRWData: toAsm << "\".bss\",#alloc,#write"; break; } toAsm << "\n"; } @@ -541,28 +541,29 @@ } private: - void emitGlobalsAndConstants(const Module &M); + void emitGlobalsAndConstants (const Module &M); - void printGlobalVariable(const GlobalVariable *GV); - void printSingleConstant( const Constant* CV); - void printConstantValueOnly(const Constant* CV); - void printConstant( const Constant* CV, std::string valID = ""); + void printGlobalVariable (const GlobalVariable *GV); + void PrintZeroBytesToPad (int numBytes); + void printSingleConstantValue (const Constant* CV); + void printConstantValueOnly (const Constant* CV, int numPadBytes = 0); + void printConstant (const Constant* CV, std::string valID = ""); - static void FoldConstants(const Module &M, - hash_set &moduleConstants); + static void FoldConstants (const Module &M, + hash_set &moduleConstants); }; // Can we treat the specified array as a string? Only if it is an array of // ubytes or non-negative sbytes. // -static bool isStringCompatible(const ConstantArray *CPA) { - const Type *ETy = cast(CPA->getType())->getElementType(); +static bool isStringCompatible(const ConstantArray *CVA) { + const Type *ETy = cast(CVA->getType())->getElementType(); if (ETy == Type::UByteTy) return true; if (ETy != Type::SByteTy) return false; - for (unsigned i = 0; i < CPA->getNumOperands(); ++i) - if (cast(CPA->getOperand(i))->getValue() < 0) + for (unsigned i = 0; i < CVA->getNumOperands(); ++i) + if (cast(CVA->getOperand(i))->getValue() < 0) return false; return true; @@ -576,16 +577,16 @@ // getAsCString - Return the specified array as a C compatible string, only if // the predicate isStringCompatible is true. // -static string getAsCString(const ConstantArray *CPA) { - assert(isStringCompatible(CPA) && "Array is not string compatible!"); +static string getAsCString(const ConstantArray *CVA) { + assert(isStringCompatible(CVA) && "Array is not string compatible!"); string Result; - const Type *ETy = cast(CPA->getType())->getElementType(); + const Type *ETy = cast(CVA->getType())->getElementType(); Result = "\""; - for (unsigned i = 0; i < CPA->getNumOperands(); ++i) { + for (unsigned i = 0; i < CVA->getNumOperands(); ++i) { unsigned char C = (ETy == Type::SByteTy) ? - (unsigned char)cast(CPA->getOperand(i))->getValue() : - (unsigned char)cast(CPA->getOperand(i))->getValue(); + (unsigned char)cast(CVA->getOperand(i))->getValue() : + (unsigned char)cast(CVA->getOperand(i))->getValue(); if (C == '"') { Result += "\\\""; @@ -649,24 +650,30 @@ } } +// Get the size of the type +// +inline unsigned int +TypeToSize(const Type* type, const TargetMachine& target) +{ + return target.findOptimalStorageSize(type); +} + // Get the size of the constant for the given target. // If this is an unsized array, return 0. // inline unsigned int ConstantToSize(const Constant* CV, const TargetMachine& target) { - if (const ConstantArray* CPA = dyn_cast(CV)) + if (const ConstantArray* CVA = dyn_cast(CV)) { - const ArrayType *aty = cast(CPA->getType()); + const ArrayType *aty = cast(CVA->getType()); if (ArrayTypeIsString(aty)) - return 1 + CPA->getNumOperands(); + return 1 + CVA->getNumOperands(); } - return target.findOptimalStorageSize(CV->getType()); + return TypeToSize(CV->getType(), target); } - - // Align data larger than one L1 cache line on L1 cache line boundaries. // Align all smaller data on the next higher 2^x boundary (4, 8, ...). // @@ -687,7 +694,7 @@ inline unsigned int TypeToAlignment(const Type* type, const TargetMachine& target) { - return SizeToAlignment(target.findOptimalStorageSize(type), target); + return SizeToAlignment(TypeToSize(type, target), target); } // Get the size of the constant and then use SizeToAlignment. @@ -695,9 +702,9 @@ inline unsigned int ConstantToAlignment(const Constant* CV, const TargetMachine& target) { - if (const ConstantArray* CPA = dyn_cast(CV)) - if (ArrayTypeIsString(cast(CPA->getType()))) - return SizeToAlignment(1 + CPA->getNumOperands(), target); + if (const ConstantArray* CVA = dyn_cast(CV)) + if (ArrayTypeIsString(cast(CVA->getType()))) + return SizeToAlignment(1 + CVA->getNumOperands(), target); return TypeToAlignment(CV->getType(), target); } @@ -705,7 +712,7 @@ // Print a single constant value. void -SparcModuleAsmPrinter::printSingleConstant(const Constant* CV) +SparcModuleAsmPrinter::printSingleConstantValue(const Constant* CV) { assert(CV->getType() != Type::VoidTy && CV->getType() != Type::TypeTy && @@ -759,31 +766,68 @@ } } +void +SparcModuleAsmPrinter::PrintZeroBytesToPad(int numBytes) +{ + for ( ; numBytes >= 8; numBytes -= 8) + printSingleConstantValue(Constant::getNullValue(Type::ULongTy)); + + if (numBytes >= 4) + { + printSingleConstantValue(Constant::getNullValue(Type::UIntTy)); + numBytes -= 4; + } + + while (numBytes--) + printSingleConstantValue(Constant::getNullValue(Type::UByteTy)); +} + // Print a constant value or values (it may be an aggregate). -// Uses printSingleConstant() to print each individual value. +// Uses printSingleConstantValue() to print each individual value. void -SparcModuleAsmPrinter::printConstantValueOnly(const Constant* CV) +SparcModuleAsmPrinter::printConstantValueOnly(const Constant* CV, + int numPadBytes /* = 0*/) { - const ConstantArray *CPA = dyn_cast(CV); - - if (CPA && isStringCompatible(CPA)) + const ConstantArray *CVA = dyn_cast(CV); + + if (numPadBytes) + PrintZeroBytesToPad(numPadBytes); + + if (CVA && isStringCompatible(CVA)) { // print the string alone and return - toAsm << "\t" << ".ascii" << "\t" << getAsCString(CPA) << "\n"; + toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; } - else if (CPA) + else if (CVA) { // Not a string. Print the values in successive locations - const std::vector &constValues = CPA->getValues(); + const std::vector &constValues = CVA->getValues(); for (unsigned i=0; i < constValues.size(); i++) printConstantValueOnly(cast(constValues[i].get())); } - else if (const ConstantStruct *CPS = dyn_cast(CV)) - { // Print the fields in successive locations - const std::vector& constValues = CPS->getValues(); - for (unsigned i=0; i < constValues.size(); i++) - printConstantValueOnly(cast(constValues[i].get())); + else if (const ConstantStruct *CVS = dyn_cast(CV)) + { // Print the fields in successive locations. Pad to align if needed! + const StructLayout *cvsLayout = + Target.DataLayout.getStructLayout(CVS->getType()); + const std::vector& constValues = CVS->getValues(); + unsigned sizeSoFar = 0; + for (unsigned i=0, N = constValues.size(); i < N; i++) + { + const Constant* field = cast(constValues[i].get()); + + // Check if padding is needed and insert one or more 0s. + unsigned fieldSize = Target.DataLayout.getTypeSize(field->getType()); + int padSize = ((i == N-1? cvsLayout->StructSize + : cvsLayout->MemberOffsets[i+1]) + - cvsLayout->MemberOffsets[i]) - fieldSize; + sizeSoFar += (fieldSize + padSize); + + // Now print the actual field value + printConstantValueOnly(field, padSize); + } + assert(sizeSoFar == cvsLayout->StructSize && + "Layout of constant struct may be incorrect!"); } else - printSingleConstant(CV); + printSingleConstantValue(CV); } // Print a constant (which may be an aggregate) prefixed by all the @@ -798,11 +842,11 @@ toAsm << "\t.align\t" << ConstantToAlignment(CV, Target) << "\n"; // Print .size and .type only if it is not a string. - const ConstantArray *CPA = dyn_cast(CV); - if (CPA && isStringCompatible(CPA)) + const ConstantArray *CVA = dyn_cast(CV); + if (CVA && isStringCompatible(CVA)) { // print it as a string and return toAsm << valID << ":\n"; - toAsm << "\t" << ".ascii" << "\t" << getAsCString(CPA) << "\n"; + toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; return; } @@ -833,14 +877,14 @@ if (GV->hasExternalLinkage()) toAsm << "\t.global\t" << getID(GV) << "\n"; - if (GV->hasInitializer()) + if (GV->hasInitializer() && ! GV->getInitializer()->isNullValue()) printConstant(GV->getInitializer(), getID(GV)); else { toAsm << "\t.align\t" << TypeToAlignment(GV->getType()->getElementType(), Target) << "\n"; toAsm << "\t.type\t" << getID(GV) << ",#object\n"; toAsm << "\t.reserve\t" << getID(GV) << "," - << Target.findOptimalStorageSize(GV->getType()->getElementType()) + << TypeToSize(GV->getType()->getElementType(), Target) << "\n"; } } @@ -863,17 +907,18 @@ printConstant(*I); // Output global variables... - for (Module::const_giterator GI = M.gbegin(), GE = M.gend(); GI != GE; ++GI) { - if (GI->hasInitializer() && GI->isConstant()) { - enterSection(AsmPrinter::ReadOnlyData); // read-only, initialized data - } else if (GI->hasInitializer() && !GI->isConstant()) { // read-write data - enterSection(AsmPrinter::InitRWData); - } else { - assert (!GI->hasInitializer() && "Unexpected global variable type found"); - enterSection(AsmPrinter::UninitRWData); // Uninitialized data + for (Module::const_giterator GI = M.gbegin(), GE = M.gend(); GI != GE; ++GI) + if (! GI->isExternal()) { + assert(GI->hasInitializer()); + if (GI->isConstant()) + enterSection(AsmPrinter::ReadOnlyData); // read-only, initialized data + else if (GI->getInitializer()->isNullValue()) + enterSection(AsmPrinter::ZeroInitRWData); // read-write zero data + else + enterSection(AsmPrinter::InitRWData); // read-write non-zero data + + printGlobalVariable(GI); } - printGlobalVariable(GI); - } toAsm << "\n"; } From vadve at cs.uiuc.edu Sat Oct 12 19:35:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:35:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200210130034.TAA17514@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.11 -> 1.12 --- Log message: Run LICM before GCSE! --- Diffs of the changes: Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.11 llvm/lib/Target/TargetMachine.cpp:1.12 --- llvm/lib/Target/TargetMachine.cpp:1.11 Mon Sep 23 07:55:50 2002 +++ llvm/lib/Target/TargetMachine.cpp Sat Oct 12 19:34:10 2002 @@ -130,8 +130,8 @@ { PM.add(createPreSelectionPass(*this)); /* PM.add(createReassociatePass()); */ - PM.add(createGCSEPass()); PM.add(createLICMPass()); + PM.add(createGCSEPass()); } PM.add(createInstructionSelectionPass(*this)); From vadve at cs.uiuc.edu Sat Oct 12 19:37:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:37:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MachineSchedInfo.h Message-ID: <200210130036.TAA17529@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MachineSchedInfo.h updated: 1.8 -> 1.9 --- Log message: Use vectors instead of hash_maps for issueGaps and conflictLists. These hash lookups were a major sink of time because they happen so often! --- Diffs of the changes: Index: llvm/include/llvm/Target/MachineSchedInfo.h diff -u llvm/include/llvm/Target/MachineSchedInfo.h:1.8 llvm/include/llvm/Target/MachineSchedInfo.h:1.9 --- llvm/include/llvm/Target/MachineSchedInfo.h:1.8 Wed Jul 24 17:20:06 2002 +++ llvm/include/llvm/Target/MachineSchedInfo.h Sat Oct 12 19:36:36 2002 @@ -242,21 +242,20 @@ inline int getLongestIssueConflict () const { return longestIssueConflict; } - + inline int getMinIssueGap (MachineOpCode fromOp, MachineOpCode toOp) const { - hash_map::const_iterator - I = issueGaps.find(OpCodePair(fromOp, toOp)); - return (I == issueGaps.end())? 0 : (*I).second; + assert(fromOp < (int) issueGaps.size()); + const std::vector& toGaps = issueGaps[fromOp]; + return (toOp < (int) toGaps.size())? toGaps[toOp] : 0; } - - inline const std::vector* + + inline const std::vector& getConflictList(MachineOpCode opCode) const { - hash_map >::const_iterator - I = conflictLists.find(opCode); - return (I == conflictLists.end())? NULL : & (*I).second; + assert(opCode < (int) conflictLists.size()); + return conflictLists[opCode]; } - + inline bool isSingleIssue (MachineOpCode opCode) const { return getInstrRUsage(opCode).isSingleIssue; } @@ -276,6 +275,13 @@ void computeInstrResources(const std::vector& instrRUForClasses); void computeIssueGaps(const std::vector& instrRUForClasses); + void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) { + std::vector& toGaps = issueGaps[fromOp]; + if (toOp >= (int) toGaps.size()) + toGaps.resize(toOp+1); + toGaps[toOp] = gap; + } + protected: int numSchedClasses; const MachineInstrInfo* mii; @@ -285,10 +291,10 @@ unsigned numUsageDeltas; unsigned numIssueDeltas; - std::vector instrRUsages; // indexed by opcode - hash_map issueGaps; // indexed by opcode pair - hash_map > - conflictLists; // indexed by opcode + std::vector instrRUsages; // indexed by opcode + std::vector > issueGaps; // indexed by [opcode1][opcode2] + std::vector > + conflictLists; // indexed by [opcode] }; #endif From vadve at cs.uiuc.edu Sat Oct 12 19:38:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:38:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/MachineSchedInfo.cpp Message-ID: <200210130037.TAA17545@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target: MachineSchedInfo.cpp updated: 1.5 -> 1.6 --- Log message: Use vectors instead of hash_maps for issueGaps and conflictLists. These hash lookups were a major sink of time because they happen so often! --- Diffs of the changes: Index: llvm/lib/Target/MachineSchedInfo.cpp diff -u llvm/lib/Target/MachineSchedInfo.cpp:1.5 llvm/lib/Target/MachineSchedInfo.cpp:1.6 --- llvm/lib/Target/MachineSchedInfo.cpp:1.5 Sun Feb 3 23:56:30 2002 +++ llvm/lib/Target/MachineSchedInfo.cpp Sat Oct 12 19:37:46 2002 @@ -151,11 +151,12 @@ instrRUForClasses) { int numOpCodes = mii->getNumRealOpCodes(); - instrRUsages.resize(numOpCodes); - + issueGaps.resize(numOpCodes); + conflictLists.resize(numOpCodes); + assert(numOpCodes < (1 << MAX_OPCODE_SIZE) - 1 && "numOpCodes invalid for implementation of class OpCodePair!"); - + // First, compute issue gaps between pairs of classes based on common // resources usages for each class, because most instruction pairs will // usually behave the same as their class. @@ -168,27 +169,27 @@ instrRUForClasses[toSC]); classPairGaps[fromSC][toSC] = classPairGap; } - + // Now, for each pair of instructions, use the class pair gap if both // instructions have identical resource usage as their respective classes. // If not, recompute the gap for the pair from scratch. - + longestIssueConflict = 0; - + for (MachineOpCode fromOp=0; fromOp < numOpCodes; fromOp++) for (MachineOpCode toOp=0; toOp < numOpCodes; toOp++) { - int instrPairGap = - (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass) - ? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)] - : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]); - - if (instrPairGap > 0) - { - issueGaps[OpCodePair(fromOp,toOp)] = instrPairGap; - conflictLists[fromOp].push_back(toOp); - longestIssueConflict = std::max(longestIssueConflict, instrPairGap); - } + int instrPairGap = + (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass) + ? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)] + : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]); + + if (instrPairGap > 0) + { + this->setGap(instrPairGap, fromOp, toOp); + conflictLists[fromOp].push_back(toOp); + longestIssueConflict=std::max(longestIssueConflict, instrPairGap); + } } } From vadve at cs.uiuc.edu Sat Oct 12 19:40:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:40:00 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Message-ID: <200210130039.TAA17562@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSched: SchedGraph.cpp updated: 1.34 -> 1.35 --- Log message: Major bug fix: was not adding CD edges for RETURNs! --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.34 llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.35 --- llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.34 Fri Aug 9 13:55:18 2002 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Sat Oct 12 19:39:22 2002 @@ -341,15 +341,16 @@ // Find the first branch instr in the sequence of machine instrs for term // unsigned first = 0; - while (!mii.isBranch(termMvec[first]->getOpCode())) + while (! mii.isBranch(termMvec[first]->getOpCode()) && + ! mii.isReturn(termMvec[first]->getOpCode())) ++first; assert(first < termMvec.size() && - "No branch instructions for BR? Ok, but weird! Delete assertion."); + "No branch instructions for terminator? Ok, but weird!"); if (first == termMvec.size()) return; - + SchedGraphNode* firstBrNode = getGraphNodeForInstr(termMvec[first]); - + // Add CD edges from each instruction in the sequence to the // *last preceding* branch instr. in the sequence // Use a latency of 0 because we only need to prevent out-of-order issue. @@ -357,13 +358,14 @@ for (unsigned i = termMvec.size(); i > first+1; --i) { SchedGraphNode* toNode = getGraphNodeForInstr(termMvec[i-1]); - assert(toNode && "No node for instr generated for branch?"); + assert(toNode && "No node for instr generated for branch/ret?"); for (unsigned j = i-1; j != 0; --j) - if (mii.isBranch(termMvec[j-1]->getOpCode())) + if (mii.isBranch(termMvec[j-1]->getOpCode()) || + mii.isReturn(termMvec[j-1]->getOpCode())) { SchedGraphNode* brNode = getGraphNodeForInstr(termMvec[j-1]); - assert(brNode && "No node for instr generated for branch?"); + assert(brNode && "No node for instr generated for branch/ret?"); (void) new SchedGraphEdge(brNode, toNode, SchedGraphEdge::CtrlDep, SchedGraphEdge::NonDataDep, 0); break; // only one incoming edge is enough @@ -388,7 +390,7 @@ const MachineCodeForBasicBlock& mvec = MachineCodeForBasicBlock::get(bb); for (unsigned i=0, N=mvec.size(); i < N; i++) { - if (mvec[i] == termMvec[first]) // reached the first branch + if (mvec[i] == termMvec[first]) // reached the first branch break; SchedGraphNode* fromNode = this->getGraphNodeForInstr(mvec[i]); From vadve at cs.uiuc.edu Sat Oct 12 19:41:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:41:00 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp Message-ID: <200210130040.TAA17589@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSched: InstrScheduling.cpp updated: 1.41 -> 1.42 --- Log message: Use vectors instead of hash_maps for issueGaps and conflictLists. These hash lookups were a major sink of time because they happen so often! Also, add option to disable scheduling. --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp diff -u llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.41 llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.42 --- llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.41 Fri Aug 9 15:07:53 2002 +++ llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp Sat Oct 12 19:40:37 2002 @@ -25,7 +25,6 @@ cl::desc("enable instruction scheduling debugging information"), cl::values( clEnumValN(Sched_NoDebugInfo, "n", "disable debug output"), - clEnumValN(Sched_Disable, "off", "disable instruction scheduling"), clEnumValN(Sched_PrintMachineCode, "y", "print machine code after scheduling"), clEnumValN(Sched_PrintSchedTrace, "t", "print trace of scheduling actions"), clEnumValN(Sched_PrintSchedGraphs, "g", "print scheduling graphs"), @@ -549,19 +548,17 @@ curTime + 1 + schedInfo.numBubblesAfter(node->getOpCode())); } - const vector* + const std::vector& conflictVec = schedInfo.getConflictList(node->getOpCode()); - if (conflictVec != NULL) - for (unsigned i=0; i < conflictVec->size(); i++) - { - MachineOpCode toOp = (*conflictVec)[i]; - cycles_t est = schedTime + schedInfo.getMinIssueGap(node->getOpCode(), - toOp); - assert(toOp < (int) nextEarliestStartTime.size()); - if (nextEarliestStartTime[toOp] < est) - nextEarliestStartTime[toOp] = est; - } + for (unsigned i=0; i < conflictVec.size(); i++) + { + MachineOpCode toOp = conflictVec[i]; + cycles_t est=schedTime + schedInfo.getMinIssueGap(node->getOpCode(),toOp); + assert(toOp < (int) nextEarliestStartTime.size()); + if (nextEarliestStartTime[toOp] < est) + nextEarliestStartTime[toOp] = est; + } } //************************* Internal Functions *****************************/ @@ -1511,9 +1508,6 @@ bool InstructionSchedulingWithSSA::runOnFunction(Function &F) { - if (SchedDebugLevel == Sched_Disable) - return false; - SchedGraphSet graphSet(&F, target); if (SchedDebugLevel >= Sched_PrintSchedGraphs) From vadve at cs.uiuc.edu Sat Oct 12 19:45:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:45:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/LLC/select.ll Message-ID: <200210130044.TAA17628@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/LLC: select.ll updated: 1.6 -> 1.7 --- Log message: Add a test for folding a GEP into a load. --- Diffs of the changes: Index: llvm/test/Regression/LLC/select.ll diff -u llvm/test/Regression/LLC/select.ll:1.6 llvm/test/Regression/LLC/select.ll:1.7 --- llvm/test/Regression/LLC/select.ll:1.6 Thu Sep 19 19:57:37 2002 +++ llvm/test/Regression/LLC/select.ll Sat Oct 12 19:44:00 2002 @@ -1,5 +1,7 @@ %AConst = constant int 123 +%Domain = type { sbyte*, int, int*, int, int, int*, %Domain* } + implementation ; Test setting values of different constants in registers. @@ -192,4 +194,14 @@ %notI2 = xor int -1, %i ;; should become XNOR ret void +end + + +; Test case for folding getelementptr into a load/store +; +int "checkFoldGEP"(%Domain* %D, long %idx) +begin + %reg841 = getelementptr %Domain* %D, long 0, ubyte 2, long %idx + %reg820 = load int* %reg841 + ret int %reg820 end From vadve at cs.uiuc.edu Sat Oct 12 19:47:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Oct 12 19:47:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile Message-ID: <200210130046.TAA17662@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile updated: 1.3 -> 1.4 --- Log message: Re-enable testing both directories. --- Diffs of the changes: Index: llvm/test/Programs/Makefile diff -u llvm/test/Programs/Makefile:1.3 llvm/test/Programs/Makefile:1.4 --- llvm/test/Programs/Makefile:1.3 Tue Feb 12 09:40:33 2002 +++ llvm/test/Programs/Makefile Sat Oct 12 19:46:21 2002 @@ -1,4 +1,4 @@ LEVEL = ../.. -DIRS = SingleSource #MultiSource +DIRS = SingleSource MultiSource include ${LEVEL}/test/Makefile.tests From lattner at cs.uiuc.edu Sun Oct 13 12:13:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 12:13:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/GraphTraits.h Message-ID: <200210131712.MAA20166@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: GraphTraits.h updated: 1.1 -> 1.2 --- Log message: Add dummy entries to document what members can be added --- Diffs of the changes: Index: llvm/include/Support/GraphTraits.h diff -u llvm/include/Support/GraphTraits.h:1.1 llvm/include/Support/GraphTraits.h:1.2 --- llvm/include/Support/GraphTraits.h:1.1 Mon Nov 26 18:02:44 2001 +++ llvm/include/Support/GraphTraits.h Sun Oct 13 12:12:05 2002 @@ -31,6 +31,13 @@ // + // typedef ...iterator nodes_iterator; + // static nodes_iterator nodes_begin(GraphType *G) + // static nodes_iterator nodes_end (GraphType *G) + // + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + + // If anyone tries to use this class without having an appropriate // specialization, make an error. If you get this error, it's because you // need to include the appropriate specialization of GraphTraits<> for your From lattner at cs.uiuc.edu Sun Oct 13 12:13:09 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 12:13:09 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalDCE.cpp Message-ID: <200210131712.MAA20748@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalDCE.cpp updated: 1.22 -> 1.23 --- Log message: Use methods that are more explanatory --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/GlobalDCE.cpp diff -u llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.22 llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.23 --- llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.22 Tue Oct 1 17:38:36 2002 +++ llvm/lib/Transforms/IPO/GlobalDCE.cpp Sun Oct 13 12:12:47 2002 @@ -105,7 +105,7 @@ // Eliminate all global variables that are unused, and that are internal, or // do not have an initializer. // - if (!GVar->hasExternalLinkage() || !GVar->hasInitializer()) { + if (GVar->hasInternalLinkage() || GVar->isExternal()) { Constant *Init = GVar->hasInitializer() ? GVar->getInitializer() : 0; GV->getParent()->getGlobalList().erase(GVar); ++NumVariables; From hldnbrnd at cs.uiuc.edu Sun Oct 13 12:30:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Sun Oct 13 12:30:01 2002 Subject: [llvm-commits] CVS: llvm/www/docs/TestStatus.html Message-ID: <200210131729.MAA14151@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: TestStatus.html updated: 1.2 -> 1.3 --- Log message: --- Diffs of the changes: Index: llvm/www/docs/TestStatus.html diff -u llvm/www/docs/TestStatus.html:1.2 llvm/www/docs/TestStatus.html:1.3 --- llvm/www/docs/TestStatus.html:1.2 Fri Oct 11 17:22:12 2002 +++ llvm/www/docs/TestStatus.html Sat Oct 12 19:20:48 2002 @@ -61,7 +61,7 @@ Olden-perimeterXXX Olden-powerXXOpercision error Olden-treaddXXX -Olden-tspXXOSame except CBE terminates in seg fault +Olden-tspXXX Olden-voronoiXXOSame as above OptimizerEvalXXO sgefaXXXBoth native and cbe seg fault From lattner at cs.uiuc.edu Sun Oct 13 12:31:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 12:31:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionResolution.cpp Message-ID: <200210131730.MAA20823@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionResolution.cpp updated: 1.13 -> 1.14 --- Log message: Account for global variables resolved more accurately. --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.13 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.14 --- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.13 Wed Oct 9 16:10:06 2002 +++ llvm/lib/Transforms/IPO/FunctionResolution.cpp Sun Oct 13 12:30:30 2002 @@ -236,14 +236,16 @@ // later. // if (Globals[i]->isExternal() && Globals[i]->use_empty()) { - if (isFunction) + if (isFunction) { M.getFunctionList().erase(cast(Globals[i])); - else + ++NumResolved; + } else { M.getGlobalList().erase(cast(Globals[i])); + ++NumGlobals; + } Globals.erase(Globals.begin()+i); Changed = true; - ++NumResolved; } else if (isFunction) { // For functions, we look to merge functions definitions of "int (...)" // to 'int (int)' or 'int ()' or whatever else is not completely generic. From lattner at cs.uiuc.edu Sun Oct 13 14:31:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:31:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/STLExtras.h Message-ID: <200210131930.OAA24720@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: STLExtras.h updated: 1.3 -> 1.4 --- Log message: disable the unused "pointer" member --- Diffs of the changes: Index: llvm/include/Support/STLExtras.h diff -u llvm/include/Support/STLExtras.h:1.3 llvm/include/Support/STLExtras.h:1.4 --- llvm/include/Support/STLExtras.h:1.3 Sun Apr 28 11:18:32 2002 +++ llvm/include/Support/STLExtras.h Sun Oct 13 14:30:44 2002 @@ -75,7 +75,9 @@ typedef typename std::iterator_traits::difference_type difference_type; typedef typename UnaryFunc::result_type value_type; - typedef typename UnaryFunc::result_type *pointer; + + typedef void pointer; + //typedef typename UnaryFunc::result_type *pointer; typedef void reference; // Can't modify value returned by fn typedef RootIt iterator_type; From lattner at cs.uiuc.edu Sun Oct 13 14:32:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:32:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraphTraits.h Message-ID: <200210131931.OAA24731@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraphTraits.h updated: 1.6 -> 1.7 --- Log message: First crack at reimplementing graph traits for DSGraphs --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraphTraits.h diff -u llvm/include/llvm/Analysis/DSGraphTraits.h:1.6 llvm/include/llvm/Analysis/DSGraphTraits.h:1.7 --- llvm/include/llvm/Analysis/DSGraphTraits.h:1.6 Thu Oct 10 15:36:37 2002 +++ llvm/include/llvm/Analysis/DSGraphTraits.h Sun Oct 13 14:31:34 2002 @@ -12,8 +12,7 @@ #include "llvm/Analysis/DSGraph.h" #include "Support/GraphTraits.h" #include "Support/iterator" - -#if 0 +#include "Support/STLExtras.h" class DSNodeIterator : public forward_iterator { friend class DSNode; @@ -22,13 +21,9 @@ typedef DSNodeIterator _Self; - DSNodeIterator(DSNode *N) : Node(N), Link(0) { // begin iterator - unsigned NumLinks = Node->getNumLinks(); - while (Link < NumLinks && Node->getLink(Link) == 0) - ++Link; - } + DSNodeIterator(DSNode *N) : Node(N), Link(0) {} // begin iterator DSNodeIterator(DSNode *N, bool) // Create end iterator - : Node(N), Link(N->getNumLinks()) { + : Node(N), Link(N->getSize()) { } public: @@ -36,38 +31,60 @@ return Link == x.Link; } bool operator!=(const _Self& x) const { return !operator==(x); } + + const _Self &operator=(const _Self &I) { + assert(I.Node == Node && "Cannot assign iterators to two different nodes!"); + Link = I.Link; + return *this; + } pointer operator*() const { - return Node->getLink(Link); + DSNodeHandle *NH = Node->getLink(Link); + return NH ? NH->getNode() : 0; } pointer operator->() const { return operator*(); } _Self& operator++() { // Preincrement - unsigned NumLinks = Node->getNumLinks(); - do { - ++Link; - } while (Link < NumLinks && Node->getLink(Link) != 0); + ++Link; return *this; } _Self operator++(int) { // Postincrement _Self tmp = *this; ++*this; return tmp; } + + unsigned getLink() const { return Link; } + DSNode *getNode() const { return Node; } }; +// Provide iterators for DSNode... +inline DSNode::iterator DSNode::begin() { return DSNodeIterator(this); } +inline DSNode::iterator DSNode::end() { return DSNodeIterator(this, false); } template <> struct GraphTraits { typedef DSNode NodeType; typedef DSNode::iterator ChildIteratorType; - static NodeType *getEntryNode(DSNode *N) { return N; } + static NodeType *getEntryNode(NodeType *N) { return N; } static ChildIteratorType child_begin(NodeType *N) { return N->begin(); } static ChildIteratorType child_end(NodeType *N) { return N->end(); } }; -// Provide iterators for DSNode... -inline DSNode::iterator DSNode::begin() { return DSNodeIterator(this); } -inline DSNode::iterator DSNode::end() { return DSNodeIterator(this, false); } +static DSNode &dereference(DSNode *N) { return *N; } + +template <> struct GraphTraits { + typedef DSNode NodeType; + typedef DSNode::iterator ChildIteratorType; -#endif + typedef std::pointer_to_unary_function DerefFun; + + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + typedef mapped_iterator::iterator, + DerefFun> nodes_iterator; + static nodes_iterator nodes_begin(DSGraph *G) { return map_iterator(G->getNodes().begin(), DerefFun(dereference));} + static nodes_iterator nodes_end (DSGraph *G) { return map_iterator(G->getNodes().end(), DerefFun(dereference)); } + + static ChildIteratorType child_begin(NodeType *N) { return N->begin(); } + static ChildIteratorType child_end(NodeType *N) { return N->end(); } +}; #endif From lattner at cs.uiuc.edu Sun Oct 13 14:33:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:33:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Printer.cpp Message-ID: <200210131932.OAA24742@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Printer.cpp updated: 1.12 -> 1.13 --- Log message: Halfway conversion from custom printing to GraphWriter printing --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Printer.cpp diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.12 llvm/lib/Analysis/DataStructure/Printer.cpp:1.13 --- llvm/lib/Analysis/DataStructure/Printer.cpp:1.12 Thu Oct 3 16:55:13 2002 +++ llvm/lib/Analysis/DataStructure/Printer.cpp Sun Oct 13 14:31:57 2002 @@ -6,9 +6,11 @@ #include "llvm/Analysis/DataStructure.h" #include "llvm/Analysis/DSGraph.h" +#include "llvm/Analysis/DSGraphTraits.h" #include "llvm/Module.h" #include "llvm/Assembly/Writer.h" #include "Support/CommandLine.h" +#include "Support/GraphWriter.h" #include #include using std::string; @@ -165,6 +167,36 @@ O << "}\n"; } +template<> +struct DOTGraphTraits : public DefaultDOTGraphTraits { + static std::string getGraphName(DSGraph *G) { + if (G->hasFunction()) + return "Function " + G->getFunction().getName(); + else + return "Non-function graph"; + } + + static const char *getGraphProperties(DSGraph *G) { + return "\tnode [shape=Mrecord];\n" + "\tedge [arrowtail=\"dot\"];\n" + "\tsize=\"10,7.5\";\n" + "\trotate=\"90\";\n"; + } + + static std::string getNodeLabel(DSNode *Node, DSGraph *Graph) { + return getCaption(Node, Graph); + } + + static std::string getNodeAttributes(DSNode *N) { + return "";//fontname=Courier"; + } + + //static int getEdgeSourceLabel(DSNode *Node, node_iterator I) { + // return MergeMap[i]; + // } +}; + + void DSGraph::writeGraphToFile(std::ostream &O, const string &GraphName) { string Filename = GraphName + ".dot"; @@ -172,6 +204,7 @@ std::ofstream F(Filename.c_str()); if (F.good()) { + WriteGraph(F, this); print(F); O << " [" << getGraphSize() << "+" << getFunctionCalls().size() << "]\n"; } else { From lattner at cs.uiuc.edu Sun Oct 13 14:40:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:40:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/InstrTypes.h Instruction.h Message-ID: <200210131939.OAA25349@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: InstrTypes.h updated: 1.29 -> 1.30 Instruction.h updated: 1.34 -> 1.35 --- Log message: - Rename Instruction::First*Op to *OpsBegin, and Num*Ops to *OpsEnd to reflect the fact that it's a range being defined. --- Diffs of the changes: Index: llvm/include/llvm/InstrTypes.h diff -u llvm/include/llvm/InstrTypes.h:1.29 llvm/include/llvm/InstrTypes.h:1.30 --- llvm/include/llvm/InstrTypes.h:1.29 Tue Sep 10 10:36:07 2002 +++ llvm/include/llvm/InstrTypes.h Sun Oct 13 14:39:06 2002 @@ -47,7 +47,7 @@ // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const TerminatorInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() >= FirstTermOp && I->getOpcode() < NumTermOps; + return I->getOpcode() >= TermOpsBegin && I->getOpcode() < TermOpsEnd; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); @@ -120,7 +120,7 @@ // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BinaryOperator *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() >= FirstBinaryOp && I->getOpcode() < NumBinaryOps; + return I->getOpcode() >= BinaryOpsBegin && I->getOpcode() < BinaryOpsEnd; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); Index: llvm/include/llvm/Instruction.h diff -u llvm/include/llvm/Instruction.h:1.34 llvm/include/llvm/Instruction.h:1.35 --- llvm/include/llvm/Instruction.h:1.34 Tue Sep 10 10:36:08 2002 +++ llvm/include/llvm/Instruction.h Sun Oct 13 14:39:07 2002 @@ -68,10 +68,10 @@ static const char* getOpcodeName(unsigned OpCode); inline bool isTerminator() const { // Instance of TerminatorInst? - return iType >= FirstTermOp && iType < NumTermOps; + return iType >= TermOpsBegin && iType < TermOpsEnd; } inline bool isBinaryOp() const { - return iType >= FirstBinaryOp && iType < NumBinaryOps; + return iType >= BinaryOpsBegin && iType < BinaryOpsEnd; } virtual void print(std::ostream &OS) const; @@ -86,30 +86,30 @@ // Exported enumerations... // enum TermOps { // These terminate basic blocks -#define FIRST_TERM_INST(N) FirstTermOp = N, +#define FIRST_TERM_INST(N) TermOpsBegin = N, #define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N, -#define LAST_TERM_INST(N) NumTermOps = N+1, +#define LAST_TERM_INST(N) TermOpsEnd = N+1, #include "llvm/Instruction.def" }; enum BinaryOps { -#define FIRST_BINARY_INST(N) FirstBinaryOp = N, +#define FIRST_BINARY_INST(N) BinaryOpsBegin = N, #define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N, -#define LAST_BINARY_INST(N) NumBinaryOps = N+1, +#define LAST_BINARY_INST(N) BinaryOpsEnd = N+1, #include "llvm/Instruction.def" }; enum MemoryOps { -#define FIRST_MEMORY_INST(N) FirstMemoryOp = N, +#define FIRST_MEMORY_INST(N) MemoryOpsBegin = N, #define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N, -#define LAST_MEMORY_INST(N) NumMemoryOps = N+1, +#define LAST_MEMORY_INST(N) MemoryOpsEnd = N+1, #include "llvm/Instruction.def" }; enum OtherOps { -#define FIRST_OTHER_INST(N) FirstOtherOp = N, +#define FIRST_OTHER_INST(N) OtherOpsBegin = N, #define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N, -#define LAST_OTHER_INST(N) NumOtherOps = N+1, +#define LAST_OTHER_INST(N) OtherOpsEnd = N+1, #include "llvm/Instruction.def" }; }; From lattner at cs.uiuc.edu Sun Oct 13 14:40:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:40:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/ReadInst.cpp Message-ID: <200210131939.OAA25356@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: ReadInst.cpp updated: 1.38 -> 1.39 --- Log message: - Rename Instruction::First*Op to *OpsBegin, and Num*Ops to *OpsEnd to reflect the fact that it's a range being defined. --- Diffs of the changes: Index: llvm/lib/Bytecode/Reader/ReadInst.cpp diff -u llvm/lib/Bytecode/Reader/ReadInst.cpp:1.38 llvm/lib/Bytecode/Reader/ReadInst.cpp:1.39 --- llvm/lib/Bytecode/Reader/ReadInst.cpp:1.38 Fri Sep 13 17:28:43 2002 +++ llvm/lib/Bytecode/Reader/ReadInst.cpp Sun Oct 13 14:39:10 2002 @@ -122,8 +122,8 @@ if (ParseRawInst(Buf, EndBuf, Raw)) return true; - if (Raw.Opcode >= Instruction::FirstBinaryOp && - Raw.Opcode < Instruction::NumBinaryOps && Raw.NumOperands == 2) { + if (Raw.Opcode >= Instruction::BinaryOpsBegin && + Raw.Opcode < Instruction::BinaryOpsEnd && Raw.NumOperands == 2) { Res = BinaryOperator::create((Instruction::BinaryOps)Raw.Opcode, getValue(Raw.Ty, Raw.Arg1), getValue(Raw.Ty, Raw.Arg2)); From lattner at cs.uiuc.edu Sun Oct 13 14:40:09 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:40:09 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PreOpts/PreSelection.cpp Message-ID: <200210131939.OAA25363@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/PreOpts: PreSelection.cpp updated: 1.3 -> 1.4 --- Log message: - Rename Instruction::First*Op to *OpsBegin, and Num*Ops to *OpsEnd to reflect the fact that it's a range being defined. --- Diffs of the changes: Index: llvm/lib/CodeGen/PreOpts/PreSelection.cpp diff -u llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.3 llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.4 --- llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.3 Sat Oct 12 19:01:57 2002 +++ llvm/lib/CodeGen/PreOpts/PreSelection.cpp Sun Oct 13 14:39:11 2002 @@ -214,8 +214,8 @@ "constantGEP", &insertBefore); default: // must be a binary operator - assert(CE->getOpcode() >= Instruction::FirstBinaryOp && - CE->getOpcode() < Instruction::NumBinaryOps && + assert(CE->getOpcode() >= Instruction::BinaryOpsBegin && + CE->getOpcode() < Instruction::BinaryOpsEnd && "Unrecognized opcode in ConstantExpr"); getArg1 = CE->getOperand(0); if (ConstantExpr* CEarg = dyn_cast(getArg1)) From lattner at cs.uiuc.edu Sun Oct 13 14:40:13 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:40:13 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrInfo.cpp Message-ID: <200210131939.OAA25370@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrInfo.cpp updated: 1.29 -> 1.30 --- Log message: - Rename Instruction::First*Op to *OpsBegin, and Num*Ops to *OpsEnd to reflect the fact that it's a range being defined. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrInfo.cpp diff -u llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.29 llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.30 --- llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.29 Sat Oct 12 19:04:26 2002 +++ llvm/lib/Target/Sparc/SparcInstrInfo.cpp Sun Oct 13 14:39:13 2002 @@ -266,15 +266,15 @@ // Entry == 0 ==> no immediate constant field exists at all. // Entry > 0 ==> abs(immediate constant) <= Entry // -vector MaxConstantsTable(Instruction::NumOtherOps); +vector MaxConstantsTable(Instruction::OtherOpsEnd); static int MaxConstantForInstr(unsigned llvmOpCode) { int modelOpCode = -1; - if (llvmOpCode >= Instruction::FirstBinaryOp && - llvmOpCode < Instruction::NumBinaryOps) + if (llvmOpCode >= Instruction::BinaryOpsBegin && + llvmOpCode < Instruction::BinaryOpsEnd) modelOpCode = ADD; else switch(llvmOpCode) { @@ -300,15 +300,15 @@ InitializeMaxConstantsTable() { unsigned op; - assert(MaxConstantsTable.size() == Instruction::NumOtherOps && + assert(MaxConstantsTable.size() == Instruction::OtherOpsEnd && "assignments below will be illegal!"); - for (op = Instruction::FirstTermOp; op < Instruction::NumTermOps; ++op) + for (op = Instruction::TermOpsBegin; op < Instruction::TermOpsEnd; ++op) MaxConstantsTable[op] = MaxConstantForInstr(op); - for (op = Instruction::FirstBinaryOp; op < Instruction::NumBinaryOps; ++op) + for (op = Instruction::BinaryOpsBegin; op < Instruction::BinaryOpsEnd; ++op) MaxConstantsTable[op] = MaxConstantForInstr(op); - for (op = Instruction::FirstMemoryOp; op < Instruction::NumMemoryOps; ++op) + for (op = Instruction::MemoryOpsBegin; op < Instruction::MemoryOpsEnd; ++op) MaxConstantsTable[op] = MaxConstantForInstr(op); - for (op = Instruction::FirstOtherOp; op < Instruction::NumOtherOps; ++op) + for (op = Instruction::OtherOpsBegin; op < Instruction::OtherOpsEnd; ++op) MaxConstantsTable[op] = MaxConstantForInstr(op); } From lattner at cs.uiuc.edu Sun Oct 13 14:40:17 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:40:17 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/TraceValues.cpp Message-ID: <200210131939.OAA25377@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: TraceValues.cpp updated: 1.48 -> 1.49 --- Log message: - Rename Instruction::First*Op to *OpsBegin, and Num*Ops to *OpsEnd to reflect the fact that it's a range being defined. --- Diffs of the changes: Index: llvm/lib/Transforms/Instrumentation/TraceValues.cpp diff -u llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.48 llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.49 --- llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.48 Tue Sep 10 20:21:26 2002 +++ llvm/lib/Transforms/Instrumentation/TraceValues.cpp Sun Oct 13 14:39:15 2002 @@ -179,7 +179,7 @@ // Explicitly test for opCodes *not* to trace so that any new opcodes will // be traced by default (VoidTy's are already excluded) // - return (opCode < Instruction::FirstOtherOp && + return (opCode < Instruction::OtherOpsBegin && opCode != Instruction::Alloca && opCode != Instruction::PHINode && opCode != Instruction::Cast); From lattner at cs.uiuc.edu Sun Oct 13 14:40:22 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 14:40:22 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/BasicBlock.cpp Constants.cpp Message-ID: <200210131939.OAA25386@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: BasicBlock.cpp updated: 1.27 -> 1.28 Constants.cpp updated: 1.30 -> 1.31 --- Log message: - Rename Instruction::First*Op to *OpsBegin, and Num*Ops to *OpsEnd to reflect the fact that it's a range being defined. --- Diffs of the changes: Index: llvm/lib/VMCore/BasicBlock.cpp diff -u llvm/lib/VMCore/BasicBlock.cpp:1.27 llvm/lib/VMCore/BasicBlock.cpp:1.28 --- llvm/lib/VMCore/BasicBlock.cpp:1.27 Tue Oct 8 16:36:34 2002 +++ llvm/lib/VMCore/BasicBlock.cpp Sun Oct 13 14:39:16 2002 @@ -19,7 +19,7 @@ // instruction list. This is not a real instruction. // struct DummyInst : public Instruction { - DummyInst() : Instruction(Type::VoidTy, NumOtherOps) { + DummyInst() : Instruction(Type::VoidTy, OtherOpsEnd) { // This should not be garbage monitored. LeakDetector::removeGarbageObject(this); } @@ -33,7 +33,7 @@ // Methods for support type inquiry through isa, cast, and dyn_cast... static inline bool classof(const DummyInst *) { return true; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == NumOtherOps; + return I->getOpcode() == OtherOpsEnd; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.30 llvm/lib/VMCore/Constants.cpp:1.31 --- llvm/lib/VMCore/Constants.cpp:1.30 Wed Oct 9 18:12:25 2002 +++ llvm/lib/VMCore/Constants.cpp Sun Oct 13 14:39:16 2002 @@ -634,8 +634,8 @@ // Its not in the table so create a new one and put it in the table. // Check the operands for consistency first - assert((Opcode >= Instruction::FirstBinaryOp && - Opcode < Instruction::NumBinaryOps) && + assert((Opcode >= Instruction::BinaryOpsBegin && + Opcode < Instruction::BinaryOpsEnd) && "Invalid opcode in binary constant expression"); assert(C1->getType() == C2->getType() && From lattner at cs.uiuc.edu Sun Oct 13 15:48:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 15:48:00 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Fhourstones/Makefile Message-ID: <200210132047.PAA29248@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Fhourstones: Makefile updated: 1.2 -> 1.3 --- Log message: Name the result fhourstones instead of c4 to match directory name --- Diffs of the changes: Index: llvm/test/Programs/MultiSource/Fhourstones/Makefile diff -u llvm/test/Programs/MultiSource/Fhourstones/Makefile:1.2 llvm/test/Programs/MultiSource/Fhourstones/Makefile:1.3 --- llvm/test/Programs/MultiSource/Fhourstones/Makefile:1.2 Wed Oct 2 16:40:31 2002 +++ llvm/test/Programs/MultiSource/Fhourstones/Makefile Sun Oct 13 15:47:21 2002 @@ -1,6 +1,6 @@ LEVEL = ../../../.. -PROG = c4 +PROG = fhourstones CPPFLAGS = -DUNIX -DTRANSIZE=1050011 -DPROBES=8 -DREPORTPLY=8 # Specify which file provides the contents of stdin for the test run From lattner at cs.uiuc.edu Sun Oct 13 15:54:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 15:54:01 2002 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200210132053.PAA30649@apoc.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.95 -> 1.96 --- Log message: - Change Function's so that their argument list is populated when they are constructed. Before, external functions would have an empty argument list, now a Function ALWAYS has a populated argument list. --- Diffs of the changes: Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.95 llvm/lib/AsmParser/llvmAsmParser.y:1.96 --- llvm/lib/AsmParser/llvmAsmParser.y:1.95 Tue Oct 8 19:25:32 2002 +++ llvm/lib/AsmParser/llvmAsmParser.y Sun Oct 13 15:53:08 2002 @@ -602,7 +602,7 @@ %union { Module *ModuleVal; Function *FunctionVal; - std::pair *ArgVal; + std::pair *ArgVal; BasicBlock *BasicBlockVal; TerminatorInst *TermInstVal; Instruction *InstVal; @@ -612,7 +612,7 @@ PATypeHolder *TypeVal; Value *ValueVal; - std::list > *ArgList; + std::vector > *ArgList; std::vector *ValueList; std::list *TypeList; std::list(new Argument(*$1), $2); - delete $1; // Delete the type handle.. + if (*$1 == Type::VoidTy) + ThrowException("void typed arguments are invalid!"); + $$ = new pair($1, $2); }; -ArgListH : ArgVal ',' ArgListH { - $$ = $3; - $3->push_front(*$1); - delete $1; +ArgListH : ArgListH ',' ArgVal { + $$ = $1; + $1->push_back(*$3); + delete $3; } | ArgVal { - $$ = new list >(); - $$->push_front(*$1); + $$ = new vector >(); + $$->push_back(*$1); delete $1; - } - | DOTDOTDOT { - $$ = new list >(); - $$->push_front(pair(new Argument(Type::VoidTy), 0)); }; ArgList : ArgListH { $$ = $1; } + | ArgListH ',' DOTDOTDOT { + $$ = $1; + $$->push_back(pair(new PATypeHolder(Type::VoidTy),0)); + } + | DOTDOTDOT { + $$ = new vector >(); + $$->push_back(pair(new PATypeHolder(Type::VoidTy),0)); + } | /* empty */ { $$ = 0; }; @@ -1208,9 +1213,9 @@ vector ParamTypeList; if ($5) - for (list >::iterator I = $5->begin(); + for (vector >::iterator I = $5->begin(); I != $5->end(); ++I) - ParamTypeList.push_back(I->first->getType()); + ParamTypeList.push_back(I->first->get()); bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; if (isVarArg) ParamTypeList.pop_back(); @@ -1253,25 +1258,25 @@ CurMeth.FunctionStart(M); // Add all of the arguments we parsed to the function... - if ($5 && !CurMeth.isDeclare) { // Is null if empty... - for (list >::iterator I = $5->begin(); - I != $5->end(); ++I) { - if (setValueName(I->first, I->second)) { // Insert into symtab... + if ($5) { // Is null if empty... + if (isVarArg) { // Nuke the last entry + assert($5->back().first->get() == Type::VoidTy && $5->back().second == 0&& + "Not a varargs marker!"); + delete $5->back().first; + $5->pop_back(); // Delete the last entry + } + Function::aiterator ArgIt = M->abegin(); + for (vector >::iterator I = $5->begin(); + I != $5->end(); ++I, ++ArgIt) { + delete I->first; // Delete the typeholder... + + if (setValueName(ArgIt, I->second)) // Insert arg into symtab... assert(0 && "No arg redef allowed!"); - } - InsertValue(I->first); - M->getArgumentList().push_back(I->first); + InsertValue(ArgIt); } + delete $5; // We're now done with the argument list - } else if ($5) { - // If we are a declaration, we should free the memory for the argument list! - for (list >::iterator I = $5->begin(), E = $5->end(); - I != E; ++I) { - if (I->second) free(I->second); // Free the memory for the name... - delete I->first; // Free the unused function argument - } - delete $5; // Free the memory for the list itself } }; From lattner at cs.uiuc.edu Sun Oct 13 15:54:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 15:54:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp Message-ID: <200210132053.PAA30656@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.36 -> 1.37 --- Log message: - Change Function's so that their argument list is populated when they are constructed. Before, external functions would have an empty argument list, now a Function ALWAYS has a populated argument list. --- Diffs of the changes: Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.36 llvm/lib/Bytecode/Reader/Reader.cpp:1.37 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.36 Fri Sep 20 15:57:54 2002 +++ llvm/lib/Bytecode/Reader/Reader.cpp Sun Oct 13 15:53:09 2002 @@ -270,14 +270,13 @@ BCR_TRACE(2, "METHOD TYPE: " << MTy << "\n"); const FunctionType::ParamTypes &Params = MTy->getParamTypes(); + Function::aiterator AI = M->abegin(); for (FunctionType::ParamTypes::const_iterator It = Params.begin(); - It != Params.end(); ++It) { - Argument *FA = new Argument(*It); - if (insertValue(FA, Values) == -1) { + It != Params.end(); ++It, ++AI) { + if (insertValue(AI, Values) == -1) { Error = "Error reading method arguments!\n"; delete M; return true; } - M->getArgumentList().push_back(FA); } while (Buf < EndBuf) { @@ -357,10 +356,6 @@ // We don't need the placeholder anymore! delete FunctionPHolder; - - // If the method is empty, we don't need the method argument entries... - if (M->isExternal()) - M->getArgumentList().clear(); ResolveReferencesToValue(M, MethSlot); From lattner at cs.uiuc.edu Sun Oct 13 15:54:09 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 15:54:09 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/MutateStructTypes.cpp Message-ID: <200210132053.PAA30663@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: MutateStructTypes.cpp updated: 1.31 -> 1.32 --- Log message: - Change Function's so that their argument list is populated when they are constructed. Before, external functions would have an empty argument list, now a Function ALWAYS has a populated argument list. --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/MutateStructTypes.cpp diff -u llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.31 llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.32 --- llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.31 Tue Oct 1 17:38:36 2002 +++ llvm/lib/Transforms/IPO/MutateStructTypes.cpp Sun Oct 13 15:53:11 2002 @@ -317,10 +317,10 @@ Function *NewMeth = cast(GMI->second); // Okay, first order of business, create the arguments... - for (Function::aiterator I = m->abegin(), E = m->aend(); I != E; ++I) { - Argument *NFA = new Argument(ConvertType(I->getType()), I->getName()); - NewMeth->getArgumentList().push_back(NFA); - LocalValueMap[I] = NFA; // Keep track of value mapping + for (Function::aiterator I = m->abegin(), E = m->aend(), + DI = NewMeth->abegin(); I != E; ++I, ++DI) { + DI->setName(I->getName()); + LocalValueMap[I] = DI; // Keep track of value mapping } From lattner at cs.uiuc.edu Sun Oct 13 15:54:14 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 15:54:14 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Linker.cpp Message-ID: <200210132053.PAA30670@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Linker.cpp updated: 1.32 -> 1.33 --- Log message: - Change Function's so that their argument list is populated when they are constructed. Before, external functions would have an empty argument list, now a Function ALWAYS has a populated argument list. --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/Linker.cpp diff -u llvm/lib/Transforms/Utils/Linker.cpp:1.32 llvm/lib/Transforms/Utils/Linker.cpp:1.33 --- llvm/lib/Transforms/Utils/Linker.cpp:1.32 Mon Sep 23 13:14:15 2002 +++ llvm/lib/Transforms/Utils/Linker.cpp Sun Oct 13 15:53:12 2002 @@ -323,14 +323,13 @@ map LocalMap; // Map for function local values // Go through and convert function arguments over... + Function::aiterator DI = Dest->abegin(); for (Function::const_aiterator I = Src->abegin(), E = Src->aend(); - I != E; ++I) { - // Create the new function argument and add to the dest function... - Argument *DFA = new Argument(I->getType(), I->getName()); - Dest->getArgumentList().push_back(DFA); + I != E; ++I, ++DI) { + DI->setName(I->getName()); // Copy the name information over... // Add a mapping to our local map - LocalMap.insert(std::make_pair(I, DFA)); + LocalMap.insert(std::make_pair(I, DI)); } // Loop over all of the basic blocks, copying the instructions over... From lattner at cs.uiuc.edu Sun Oct 13 15:54:18 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 15:54:18 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Verifier.cpp Message-ID: <200210132053.PAA30679@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.32 -> 1.33 Verifier.cpp updated: 1.40 -> 1.41 --- Log message: - Change Function's so that their argument list is populated when they are constructed. Before, external functions would have an empty argument list, now a Function ALWAYS has a populated argument list. --- Diffs of the changes: Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.32 llvm/lib/VMCore/Function.cpp:1.33 --- llvm/lib/VMCore/Function.cpp:1.32 Mon Sep 16 20:17:57 2002 +++ llvm/lib/VMCore/Function.cpp Sun Oct 13 15:53:14 2002 @@ -61,7 +61,7 @@ "Invalid symtab argument!"); if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this); Value::setName(name); - if (P && hasName()) P->getSymbolTable()->insert(this); + if (P && hasName()) P->getSymbolTableSure()->insert(this); } void Argument::setParent(Function *parent) { @@ -85,6 +85,13 @@ ArgumentList.setItemParent(this); ArgumentList.setParent(this); ParentSymTab = SymTab = 0; + + // Create the arguments vector, all arguments start out unnamed. + for (unsigned i = 0, e = Ty->getNumParams(); i != e; ++i) { + assert(Ty->getParamType(i) != Type::VoidTy && + "Cannot have void typed arguments!"); + ArgumentList.push_back(new Argument(Ty->getParamType(i))); + } // Make sure that we get added to a function LeakDetector::addGarbageObject(this); Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.40 llvm/lib/VMCore/Verifier.cpp:1.41 --- llvm/lib/VMCore/Verifier.cpp:1.40 Sun Oct 6 17:47:32 2002 +++ llvm/lib/VMCore/Verifier.cpp Sun Oct 13 15:53:14 2002 @@ -193,32 +193,30 @@ // visitFunction - Verify that a function is ok. // void Verifier::visitFunction(Function &F) { - if (F.isExternal()) return; - - verifySymbolTable(F.getSymbolTable()); - // Check function arguments... const FunctionType *FT = F.getFunctionType(); unsigned NumArgs = F.getArgumentList().size(); Assert2(!FT->isVarArg(), "Cannot define varargs functions in LLVM!", &F, FT); - Assert2(FT->getParamTypes().size() == NumArgs, + Assert2(FT->getNumParams() == NumArgs, "# formal arguments must match # of arguments for function type!", &F, FT); // Check that the argument values match the function type for this function... - if (FT->getParamTypes().size() == NumArgs) { - unsigned i = 0; - for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I, ++i) - Assert2(I->getType() == FT->getParamType(i), - "Argument value does not match function argument type!", - I, FT->getParamType(i)); - } + unsigned i = 0; + for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I, ++i) + Assert2(I->getType() == FT->getParamType(i), + "Argument value does not match function argument type!", + I, FT->getParamType(i)); - // Check the entry node - BasicBlock *Entry = &F.getEntryNode(); - Assert1(pred_begin(Entry) == pred_end(Entry), - "Entry block to function must not have predecessors!", Entry); + if (!F.isExternal()) { + verifySymbolTable(F.getSymbolTable()); + + // Check the entry node + BasicBlock *Entry = &F.getEntryNode(); + Assert1(pred_begin(Entry) == pred_end(Entry), + "Entry block to function must not have predecessors!", Entry); + } } From lattner at cs.uiuc.edu Sun Oct 13 15:58:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 15:58:01 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200210132057.PAA30968@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.78 -> 1.79 --- Log message: - Change Function's so that their argument list is populated when they are constructed. Before, external functions would have an empty argument list, now a Function ALWAYS has a populated argument list. --- Diffs of the changes: Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.78 llvm/lib/VMCore/AsmWriter.cpp:1.79 --- llvm/lib/VMCore/AsmWriter.cpp:1.78 Sun Oct 6 17:48:09 2002 +++ llvm/lib/VMCore/AsmWriter.cpp Sun Oct 13 15:57:00 2002 @@ -607,17 +607,8 @@ // Loop over the arguments, printing them... const FunctionType *FT = F->getFunctionType(); - if (!F->isExternal()) { - for(Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I) - printArgument(I); - } else { - // Loop over the arguments, printing them... - for (FunctionType::ParamTypes::const_iterator I = FT->getParamTypes().begin(), - E = FT->getParamTypes().end(); I != E; ++I) { - if (I != FT->getParamTypes().begin()) Out << ", "; - printType(*I); - } - } + for(Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I) + printArgument(I); // Finish printing arguments... if (FT->isVarArg()) { From lattner at cs.uiuc.edu Sun Oct 13 16:39:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 16:39:00 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.ll Message-ID: <200210132138.QAA31636@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2002-10-13-ConstantEncodingProblem.ll added (r1.1) --- Log message: Checking testcase for bytecode reader/writer that is causing the SPEC parser benchmark to not build. --- Diffs of the changes: From lattner at cs.uiuc.edu Sun Oct 13 16:45:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 16:45:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx 2002-10-13-ConstantEncodingProblem.ll Message-ID: <200210132144.QAA32147@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2002-10-13-ConstantEncodingProblem.llx added (r1.1) 2002-10-13-ConstantEncodingProblem.ll (r1.1) removed --- Log message: Rename test so that we can run the disassembler on it. --- Diffs of the changes: From lattner at cs.uiuc.edu Sun Oct 13 16:48:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 16:48:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx Message-ID: <200210132147.QAA32379@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2002-10-13-ConstantEncodingProblem.llx updated: 1.1 -> 1.2 --- Log message: Simplify testcase --- Diffs of the changes: Index: llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx diff -u llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx:1.1 llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx:1.2 --- llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx:1.1 Sun Oct 13 16:43:56 2002 +++ llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx Sun Oct 13 16:47:43 2002 @@ -1,10 +1,9 @@ ; RUN: as < %s | dis -%Domain = type { sbyte*, %List_o_links*, %D_tree_leaf*, %Domain* } -%List_o_links = type { int, int, int, %List_o_links* } -%D_tree_leaf = type { %Domain*, int, %D_tree_leaf* } +%Domain = type { %D_tree_leaf*, %Domain* } +%D_tree_leaf = type %Domain* -%D = global %Domain { sbyte* null, %List_o_links* null, %D_tree_leaf* null, %Domain* null } +%D = global %Domain { %D_tree_leaf* null, %Domain* null } implementation From vadve at cs.uiuc.edu Sun Oct 13 16:48:05 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Oct 13 16:48:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetData.cpp Message-ID: <200210132147.QAA30199@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetData.cpp updated: 1.23 -> 1.24 --- Log message: Don't try to compute the size of an "array" element if the index is 0: the size may be unknown, and is not needed. --- Diffs of the changes: Index: llvm/lib/Target/TargetData.cpp diff -u llvm/lib/Target/TargetData.cpp:1.23 llvm/lib/Target/TargetData.cpp:1.24 --- llvm/lib/Target/TargetData.cpp:1.23 Wed Sep 25 18:46:55 2002 +++ llvm/lib/Target/TargetData.cpp Sun Oct 13 16:47:44 2002 @@ -170,11 +170,10 @@ Ty = cast(Ty)->getElementType(); // Get the array index and the size of each array element. - // Both must be known constants, or this will fail. - // Also, the product needs to be sign-extended from 32 to 64 bits. - int64_t elementSize = (int64_t)getTypeSize(Ty); + // Both must be known constants, or the index shd be 0; else this fails. int64_t arrayIdx = cast(Idx[CurIDX])->getValue(); - Result += (uint64_t)(arrayIdx * elementSize); + Result += arrayIdx == 0? 0 + : (uint64_t) (arrayIdx * (int64_t) getTypeSize(Ty)); } else if (const StructType *STy = dyn_cast(Ty)) { assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx"); From lattner at cs.uiuc.edu Sun Oct 13 16:53:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 16:53:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx Message-ID: <200210132152.QAA32441@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2002-10-13-ConstantEncodingProblem.llx updated: 1.2 -> 1.3 --- Log message: Simplify again --- Diffs of the changes: Index: llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx diff -u llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx:1.2 llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx:1.3 --- llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx:1.2 Sun Oct 13 16:47:43 2002 +++ llvm/test/Regression/Assembler/2002-10-13-ConstantEncodingProblem.llx Sun Oct 13 16:51:55 2002 @@ -1,9 +1,8 @@ ; RUN: as < %s | dis -%Domain = type { %D_tree_leaf*, %Domain* } -%D_tree_leaf = type %Domain* +%Domain = type { %Domain**, %Domain* } -%D = global %Domain { %D_tree_leaf* null, %Domain* null } +%D = global %Domain { %Domain** null, %Domain* null } implementation From hldnbrnd at cs.uiuc.edu Sun Oct 13 17:11:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Sun Oct 13 17:11:01 2002 Subject: [llvm-commits] CVS: llvm/www/docs/TestStatus.html Message-ID: <200210132210.RAA14812@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: TestStatus.html updated: 1.3 -> 1.4 --- Log message: New Results --- Diffs of the changes: Index: llvm/www/docs/TestStatus.html diff -u llvm/www/docs/TestStatus.html:1.3 llvm/www/docs/TestStatus.html:1.4 --- llvm/www/docs/TestStatus.html:1.3 Sat Oct 12 19:20:48 2002 +++ llvm/www/docs/TestStatus.html Sun Oct 13 17:10:08 2002 @@ -53,7 +53,7 @@ - + From hldnbrnd at cs.uiuc.edu Sun Oct 13 17:44:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Sun Oct 13 17:44:01 2002 Subject: [llvm-commits] CVS: llvm/www/docs/TestStatus.html Message-ID: <200210132243.RAA14938@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: TestStatus.html updated: 1.4 -> 1.5 --- Log message: More successes --- Diffs of the changes: Index: llvm/www/docs/TestStatus.html diff -u llvm/www/docs/TestStatus.html:1.4 llvm/www/docs/TestStatus.html:1.5 --- llvm/www/docs/TestStatus.html:1.4 Sun Oct 13 17:10:08 2002 +++ llvm/www/docs/TestStatus.html Sun Oct 13 17:43:11 2002 @@ -55,7 +55,7 @@ - + From lattner at cs.uiuc.edu Sun Oct 13 19:50:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 19:50:01 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/SlotCalculator.cpp Message-ID: <200210140049.TAA10070@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: SlotCalculator.cpp updated: 1.23 -> 1.24 --- Log message: Minor cleanups, no changes to functionality --- Diffs of the changes: Index: llvm/lib/VMCore/SlotCalculator.cpp diff -u llvm/lib/VMCore/SlotCalculator.cpp:1.23 llvm/lib/VMCore/SlotCalculator.cpp:1.24 --- llvm/lib/VMCore/SlotCalculator.cpp:1.23 Wed Jul 24 17:08:50 2002 +++ llvm/lib/VMCore/SlotCalculator.cpp Sun Oct 13 19:48:57 2002 @@ -70,10 +70,9 @@ // Add all of the constants that the global variables might refer to first. // for (Module::const_giterator I = TheModule->gbegin(), E = TheModule->gend(); - I != E; ++I) { + I != E; ++I) if (I->hasInitializer()) insertValue(I->getInitializer()); - } // Add all of the global variables to the value table... // @@ -193,7 +192,7 @@ for (unsigned i = 0; i < NumModuleTypes; ++i) { unsigned ModuleSize = ModuleLevel[i]; // Size of plane before function came TypePlane &CurPlane = Table[i]; - //SC_DEBUG("Processing Plane " <op_begin(), E = U->op_end(); I != E; ++I) - if (!isa(*I)) // Don't chain insert global values + if (!isa(*I)) // Don't chain insert global values insertValue(*I); } @@ -262,7 +261,7 @@ if (D->getType() == Type::VoidTy || // Ignore void type nodes (IgnoreNamedNodes && // Ignore named and constants (D->hasName() || isa(D)) && !isa(D))) { - SC_DEBUG("ignored value " << D << endl); + SC_DEBUG("ignored value " << D << "\n"); return -1; // We do need types unconditionally though } @@ -279,7 +278,7 @@ if ((ResultSlot = getValSlot(TheTy)) == -1) { ResultSlot = doInsertVal(TheTy); SC_DEBUG(" Inserted type: " << TheTy->getDescription() << " slot=" << - ResultSlot << endl); + ResultSlot << "\n"); } // Loop over any contained types in the definition... in reverse depth first @@ -293,10 +292,10 @@ // If we haven't seen this sub type before, add it to our type table! const Type *SubTy = *I; if (getValSlot(SubTy) == -1) { - SC_DEBUG(" Inserting subtype: " << SubTy->getDescription() << endl); + SC_DEBUG(" Inserting subtype: " << SubTy->getDescription() << "\n"); int Slot = doInsertVal(SubTy); SC_DEBUG(" Inserted subtype: " << SubTy->getDescription() << - " slot=" << Slot << endl); + " slot=" << Slot << "\n"); } } return ResultSlot; From hldnbrnd at cs.uiuc.edu Sun Oct 13 20:09:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Sun Oct 13 20:09:01 2002 Subject: [llvm-commits] CVS: llvm/www/docs/TestStatus.html Message-ID: <200210140108.UAA16172@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: TestStatus.html updated: 1.5 -> 1.6 --- Log message: More results --- Diffs of the changes: Index: llvm/www/docs/TestStatus.html diff -u llvm/www/docs/TestStatus.html:1.5 llvm/www/docs/TestStatus.html:1.6 --- llvm/www/docs/TestStatus.html:1.5 Sun Oct 13 17:43:11 2002 +++ llvm/www/docs/TestStatus.html Sun Oct 13 20:08:06 2002 @@ -3,7 +3,7 @@

Test Results

-
last updated: 10/09/2002
+
last updated: 10/13/2002

SingleSource

Test NameCBE Compiles?CBE Links?CBE Diff MatchLLI Diff MatchNotes
FhourstonesXXOSeg Fault
Olden-bhOOO(...) issue
Olden-bhXXX
Olden-bisortXXX
Olden-em3dXXOX
Olden-healthXXOX
FhourstonesXXOSeg Fault
Olden-bhXXX
Olden-bisortXXX
Olden-em3dXXOX
Olden-em3dXXXX
Olden-healthXXOX
Olden-mstXXX
Olden-perimeterXXX
@@ -21,7 +21,7 @@ - + @@ -62,7 +62,7 @@ - + From lattner at cs.uiuc.edu Sun Oct 13 22:29:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 22:29:01 2002 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200210140328.WAA21485@apoc.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.96 -> 1.97 --- Log message: This loop executed exactly one time, turn it into straightline code --- Diffs of the changes: Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.96 llvm/lib/AsmParser/llvmAsmParser.y:1.97 --- llvm/lib/AsmParser/llvmAsmParser.y:1.96 Sun Oct 13 15:53:08 2002 +++ llvm/lib/AsmParser/llvmAsmParser.y Sun Oct 13 22:28:42 2002 @@ -117,15 +117,13 @@ // Loop over all of the uses of the GlobalValue. The only thing they are // allowed to be is ConstantPointerRef's. assert(OldGV->use_size() == 1 && "Only one reference should exist!"); - while (!OldGV->use_empty()) { - User *U = OldGV->use_back(); // Must be a ConstantPointerRef... - ConstantPointerRef *CPR = cast(U); - assert(CPR->getValue() == OldGV && "Something isn't happy"); + User *U = OldGV->use_back(); // Must be a ConstantPointerRef... + ConstantPointerRef *CPR = cast(U); - // Change the const pool reference to point to the real global variable - // now. This should drop a use from the OldGV. - CPR->mutateReferences(OldGV, GV); - } + // Change the const pool reference to point to the real global variable + // now. This should drop a use from the OldGV. + CPR->mutateReferences(OldGV, GV); + assert(OldGV->use_empty() && "All uses should be gone now!"); // Remove OldGV from the module... CurrentModule->getGlobalList().remove(OldGV); From lattner at cs.uiuc.edu Sun Oct 13 22:31:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 22:31:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Constants.h Module.h Message-ID: <200210140330.WAA21516@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.5 -> 1.6 Constants.h updated: 1.17 -> 1.18 Module.h updated: 1.26 -> 1.27 --- Log message: - Dramatically simplify the Constant::mutateReferences implementation, allowing it to be called on all constant types (structures/arrays) --- Diffs of the changes: Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.5 llvm/include/llvm/Constant.h:1.6 --- llvm/include/llvm/Constant.h:1.5 Wed Oct 9 18:12:22 2002 +++ llvm/include/llvm/Constant.h Sun Oct 13 22:30:13 2002 @@ -79,7 +79,7 @@ // WARNING: Only to be used by Bytecode & Assembly Parsers! USER CODE SHOULD // NOT USE THIS!! // Returns the number of uses of OldV that were replaced. - virtual unsigned mutateReferences(Value* OldV, Value *NewV) { return 0; } + unsigned mutateReferences(Value* OldV, Value *NewV); // END WARNING!! }; Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.17 llvm/include/llvm/Constants.h:1.18 --- llvm/include/llvm/Constants.h:1.17 Wed Oct 9 18:12:22 2002 +++ llvm/include/llvm/Constants.h Sun Oct 13 22:30:13 2002 @@ -439,12 +439,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - - // WARNING: Only to be used by Bytecode & Assembly Parsers! USER CODE SHOULD - // NOT USE THIS!! - // Returns the number of uses of OldV that were replaced. - virtual unsigned mutateReferences(Value* OldV, Value *NewV); - // END WARNING!! }; @@ -502,14 +496,6 @@ static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } - -public: - // WARNING: Only to be used by Bytecode & Assembly Parsers! USER CODE SHOULD - // NOT USE THIS!! - // Returns the number of uses of OldV that were replaced. - virtual unsigned mutateReferences(Value* OldV, Value *NewV); - // END WARNING!! }; - #endif Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.26 llvm/include/llvm/Module.h:1.27 --- llvm/include/llvm/Module.h:1.26 Sun Aug 25 17:54:55 2002 +++ llvm/include/llvm/Module.h Sun Oct 13 22:30:13 2002 @@ -59,7 +59,8 @@ SymbolTable *SymTab; // Accessor for the underlying GlobalValRefMap... only through the - // ConstantPointerRef class... + // Constant class... + friend class Constant; friend class ConstantPointerRef; void mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV); ConstantPointerRef *getConstantPointerRef(GlobalValue *GV); From lattner at cs.uiuc.edu Sun Oct 13 22:31:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 22:31:05 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200210140330.WAA21523@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.31 -> 1.32 --- Log message: - Dramatically simplify the Constant::mutateReferences implementation, allowing it to be called on all constant types (structures/arrays) --- Diffs of the changes: Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.31 llvm/lib/VMCore/Constants.cpp:1.32 --- llvm/lib/VMCore/Constants.cpp:1.31 Sun Oct 13 14:39:16 2002 +++ llvm/lib/VMCore/Constants.cpp Sun Oct 13 22:30:23 2002 @@ -685,27 +685,25 @@ return Instruction::getOpcodeName(getOpcode()); } +unsigned Constant::mutateReferences(Value *OldV, Value *NewV) { + // Uses of constant pointer refs are global values, not constants! + if (ConstantPointerRef *CPR = dyn_cast(this)) { + GlobalValue *NewGV = cast(NewV); + GlobalValue *OldGV = CPR->getValue(); -//---- ConstantPointerRef::mutateReferences() implementation... -// -unsigned ConstantPointerRef::mutateReferences(Value *OldV, Value *NewV) { - assert(getValue() == OldV && "Cannot mutate old value if I'm not using it!"); - GlobalValue *NewGV = cast(NewV); - getValue()->getParent()->mutateConstantPointerRef(getValue(), NewGV); - Operands[0] = NewGV; - return 1; -} + assert(OldGV == OldV && "Cannot mutate old value if I'm not using it!"); - -//---- ConstantPointerExpr::mutateReferences() implementation... -// -unsigned ConstantExpr::mutateReferences(Value* OldV, Value *NewV) { - unsigned NumReplaced = 0; - Constant *NewC = cast(NewV); - for (unsigned i = 0, N = getNumOperands(); i != N; ++i) - if (Operands[i] == OldV) { - ++NumReplaced; - Operands[i] = NewC; - } - return NumReplaced; + OldGV->getParent()->mutateConstantPointerRef(OldGV, NewGV); + Operands[0] = NewGV; + return 1; + } else { + Constant *NewC = cast(NewV); + unsigned NumReplaced = 0; + for (unsigned i = 0, N = getNumOperands(); i != N; ++i) + if (Operands[i] == OldV) { + ++NumReplaced; + Operands[i] = NewC; + } + return NumReplaced; + } } From lattner at cs.uiuc.edu Sun Oct 13 22:34:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 22:34:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/ReadConst.cpp Reader.cpp ReaderInternals.h Message-ID: <200210140333.WAA21543@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: ReadConst.cpp updated: 1.39 -> 1.40 Reader.cpp updated: 1.37 -> 1.38 ReaderInternals.h updated: 1.28 -> 1.29 --- Log message: There is no way to guarantee that constants are not forward referenced. Handle forward referenced constants in a general way. This fixes bug: Assembler/2002-10-13-ConstantEncodingProblem.llx and allows the SPEC 197.parser benchmark to be built --- Diffs of the changes: Index: llvm/lib/Bytecode/Reader/ReadConst.cpp diff -u llvm/lib/Bytecode/Reader/ReadConst.cpp:1.39 llvm/lib/Bytecode/Reader/ReadConst.cpp:1.40 --- llvm/lib/Bytecode/Reader/ReadConst.cpp:1.39 Mon Aug 19 11:48:21 2002 +++ llvm/lib/Bytecode/Reader/ReadConst.cpp Sun Oct 13 22:33:02 2002 @@ -202,28 +202,8 @@ << ArgValSlot << "\n"); // Get the arg value from its slot if it exists, otherwise a placeholder - Value *Val = getValue(ArgTy, ArgValSlot, false); - Constant *C; - if (Val) { - if (!(C = dyn_cast(Val))) return true; - BCR_TRACE(5, "Constant Found in ValueTable!\n"); - } else { // Nope... find or create a forward ref. for it - GlobalRefsType::iterator I = - GlobalRefs.find(make_pair(ArgTy, ArgValSlot)); - - if (I != GlobalRefs.end()) { - BCR_TRACE(5, "Previous forward ref found!\n"); - C = cast(I->second); - } else { - // Create a placeholder for the constant reference and - // keep track of the fact that we have a forward ref to recycle it - BCR_TRACE(5, "Creating new forward ref to a constant!\n"); - C = new ConstPHolder(ArgTy, ArgValSlot); - - // Keep track of the fact that we have a forward ref to recycle it - GlobalRefs.insert(make_pair(make_pair(ArgTy, ArgValSlot), C)); - } - } + Constant *C = getConstantValue(ArgTy, ArgValSlot); + if (C == 0) return true; ArgVec.push_back(C); } @@ -310,9 +290,9 @@ while (NumElements--) { // Read all of the elements of the constant. unsigned Slot; if (read_vbr(Buf, EndBuf, Slot)) return true; - Value *V = getValue(AT->getElementType(), Slot, false); - if (!V || !isa(V)) return true; - Elements.push_back(cast(V)); + Constant *C = getConstantValue(AT->getElementType(), Slot); + if (!C) return true; + Elements.push_back(C); } V = ConstantArray::get(AT, Elements); break; @@ -326,10 +306,9 @@ for (unsigned i = 0; i < ET.size(); ++i) { unsigned Slot; if (read_vbr(Buf, EndBuf, Slot)) return true; - Value *V = getValue(ET[i], Slot, false); - if (!V || !isa(V)) - return true; - Elements.push_back(cast(V)); + Constant *C = getConstantValue(ET[i], Slot); + if (!C) return true; + Elements.push_back(C); } V = ConstantStruct::get(ST, Elements); Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.37 llvm/lib/Bytecode/Reader/Reader.cpp:1.38 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.37 Sun Oct 13 15:53:09 2002 +++ llvm/lib/Bytecode/Reader/Reader.cpp Sun Oct 13 22:33:02 2002 @@ -132,6 +132,34 @@ return d; } +/// getConstantValue - Just like getValue, except that it returns a null pointer +/// only on error. It always returns a constant (meaning that if the value is +/// defined, but is not a constant, that is an error). If the specified +/// constant hasn't been parsed yet, a placeholder is defined and used. Later, +/// after the real value is parsed, the placeholder is eliminated. +/// +Constant *BytecodeParser::getConstantValue(const Type *Ty, unsigned Slot) { + if (Value *V = getValue(Ty, Slot, false)) + return dyn_cast(V); // If we already have the value parsed... + + GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, Slot)); + if (I != GlobalRefs.end()) { + BCR_TRACE(5, "Previous forward ref found!\n"); + return cast(I->second); + } else { + // Create a placeholder for the constant reference and + // keep track of the fact that we have a forward ref to recycle it + BCR_TRACE(5, "Creating new forward ref to a constant!\n"); + Constant *C = new ConstPHolder(Ty, Slot); + + // Keep track of the fact that we have a forward ref to recycle it + GlobalRefs.insert(make_pair(make_pair(Ty, Slot), C)); + return C; + } +} + + + bool BytecodeParser::postResolveValues(ValueTable &ValTab) { bool Error = false; for (unsigned ty = 0; ty < ValTab.size(); ++ty) { Index: llvm/lib/Bytecode/Reader/ReaderInternals.h diff -u llvm/lib/Bytecode/Reader/ReaderInternals.h:1.28 llvm/lib/Bytecode/Reader/ReaderInternals.h:1.29 --- llvm/lib/Bytecode/Reader/ReaderInternals.h:1.28 Wed Aug 21 17:55:27 2002 +++ llvm/lib/Bytecode/Reader/ReaderInternals.h Sun Oct 13 22:33:02 2002 @@ -108,6 +108,7 @@ Value *getValue(const Type *Ty, unsigned num, bool Create = true); const Type *getType(unsigned ID); + Constant *getConstantValue(const Type *Ty, unsigned num); int insertValue(Value *D, std::vector &D); // -1 = Failure bool postResolveValues(ValueTable &ValTab); From lattner at cs.uiuc.edu Sun Oct 13 22:35:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 22:35:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Writer/Writer.cpp Message-ID: <200210140334.WAA21558@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Writer: Writer.cpp updated: 1.28 -> 1.29 --- Log message: Clean up code a bit, no functionality changes. --- Diffs of the changes: Index: llvm/lib/Bytecode/Writer/Writer.cpp diff -u llvm/lib/Bytecode/Writer/Writer.cpp:1.28 llvm/lib/Bytecode/Writer/Writer.cpp:1.29 --- llvm/lib/Bytecode/Writer/Writer.cpp:1.28 Tue Oct 1 17:38:32 2002 +++ llvm/lib/Bytecode/Writer/Writer.cpp Sun Oct 13 22:34:17 2002 @@ -120,17 +120,17 @@ outputConstantsInPlane(Plane, ValNo); // Write out the types } - for (unsigned pno = 0; pno < NumPlanes; pno++) { + for (unsigned pno = 0; pno != NumPlanes; pno++) { const std::vector &Plane = Table.getPlane(pno); - if (Plane.empty()) continue; // Skip empty type planes... - - unsigned ValNo = 0; - if (isFunction) // Don't reemit module constants - ValNo = Table.getModuleLevel(pno); - else if (pno == Type::TypeTyID) - continue; // Type plane was written out above - - outputConstantsInPlane(Plane, ValNo); // Write out constants in the plane + if (!Plane.empty()) { // Skip empty type planes... + unsigned ValNo = 0; + if (isFunction) // Don't reemit module constants + ValNo = Table.getModuleLevel(pno); + else if (pno == Type::TypeTyID) // If type plane wasn't written out above + continue; + + outputConstantsInPlane(Plane, ValNo); // Write out constants in the plane + } } } From lattner at cs.uiuc.edu Sun Oct 13 23:06:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Oct 13 23:06:01 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/UnitTests/2002-10-13-BadLoad.c Message-ID: <200210140405.XAA21722@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/UnitTests: 2002-10-13-BadLoad.c added (r1.1) --- Log message: New testcase from gzip benchmark --- Diffs of the changes:
Test NameCBE Compiles?CBE Links?CBE Diff MatchLLI Diff MatchNotes
ackermanXXX
ary3XXX
fib2XXX
hashXXX
hashXXO
heapsortXXX
helloXXX
listsXXX
Olden-powerXXOpercision error
Olden-treaddXXX
Olden-tspXXX
Olden-voronoiXXOSame as above
Olden-voronoiXXOInfinite loop
OptimizerEvalXXO
sgefaXXXBoth native and cbe seg fault
simXXO