From vadve at psmith.cs.uiuc.edu Mon Sep 23 07:56:01 2002 From: vadve at psmith.cs.uiuc.edu (Vikram Adve) Date: Mon Sep 23 07:56:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200209231255.g8NCtrs25916@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.10 -> 1.11 --- Log message: Disable reassociation pass in LLC until it is fixed. --- Diffs of the changes: Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.10 llvm/lib/Target/TargetMachine.cpp:1.11 --- llvm/lib/Target/TargetMachine.cpp:1.10 Sat Sep 21 00:01:21 2002 +++ llvm/lib/Target/TargetMachine.cpp Mon Sep 23 07:55:50 2002 @@ -129,7 +129,7 @@ if (!DisablePreSelect) { PM.add(createPreSelectionPass(*this)); - PM.add(createReassociatePass()); + /* PM.add(createReassociatePass()); */ PM.add(createGCSEPass()); PM.add(createLICMPass()); } From vadve at psmith.cs.uiuc.edu Mon Sep 23 08:13:01 2002 From: vadve at psmith.cs.uiuc.edu (Vikram Adve) Date: Mon Sep 23 08:13:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Makefile Message-ID: <200209231312.g8NDCVL26472@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: Makefile updated: 1.12 -> 1.13 --- Log message: Put intermediate source files in a subdirectory here instead of with object files. Also, --- Diffs of the changes: Index: llvm/lib/Target/Sparc/Makefile diff -u llvm/lib/Target/Sparc/Makefile:1.12 llvm/lib/Target/Sparc/Makefile:1.13 --- llvm/lib/Target/Sparc/Makefile:1.12 Mon Aug 12 17:09:44 2002 +++ llvm/lib/Target/Sparc/Makefile Mon Sep 23 08:12:28 2002 @@ -1,20 +1,33 @@ LEVEL = ../../.. LIBRARYNAME = sparc + ExtraSource = Debug/Sparc.burm.cpp include $(LEVEL)/Makefile.common -Debug/Sparc.burm.cpp: $(BUILD_ROOT)/Debug/Sparc.burm Debug/.dir +ifdef ENABLE_OPTIMIZED + DEBUG_FLAG = +else + DEBUG_FLAG = -D_DEBUG +endif + +Debug/Sparc.burm.cpp: Debug/Sparc.burm Debug/.dir $(RunBurg) $< -o $@ $(BUILD_ROOT)/Debug/Sparc.burm.o: Debug/Sparc.burm.cpp $(CompileG) $< -o $@ -$(BUILD_ROOT)/Debug/Sparc.burg.in1 : Sparc.burg.in $(BUILD_ROOT)/Debug/.dir - g++ -E -I$(LEVEL)/include -D_DEBUG -x c++ $< | sed '/^# /d' | sed 's/Ydefine/#define/' > $@ +$(BUILD_ROOT)/Release/Sparc.burm.o: Debug/Sparc.burm.cpp + $(CompileO) $< -o $@ + +$(BUILD_ROOT)/Profile/Sparc.burm.o: Debug/Sparc.burm.cpp + $(CompileP) $< -o $@ + +Debug/Sparc.burg.in1 : Sparc.burg.in Debug/.dir + $(CXX) -E -I$(LEVEL)/include $(DEBUG_FLAG) -x c++ $< | sed '/^# /d' | sed 's/Ydefine/#define/' > $@ -$(BUILD_ROOT)/Debug/Sparc.burm : $(BUILD_ROOT)/Debug/Sparc.burg.in1 $(BUILD_ROOT)/Debug/.dir - g++ -E -I$(LEVEL)/include -D_DEBUG -x c++ $< | sed '/^# /d' | sed 's/Xinclude/#include/g' | sed 's/Xdefine/#define/g' > $@ +Debug/Sparc.burm : Debug/Sparc.burg.in1 + $(CXX) -E -I$(LEVEL)/include $(DEBUG_FLAG) -x c++ $< | sed '/^# /d' | sed 's/Xinclude/#include/g' | sed 's/Xdefine/#define/g' > $@ $(BUILD_ROOT)/Depend/Sparc.burm.d: $(BUILD_ROOT)/Depend/.dir touch $@ From vadve at psmith.cs.uiuc.edu Mon Sep 23 09:24:01 2002 From: vadve at psmith.cs.uiuc.edu (Vikram Adve) Date: Mon Sep 23 09:24:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/LLC/Makefile Message-ID: <200209231423.g8NENID27383@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/LLC: Makefile updated: 1.3 -> 1.4 --- Log message: C tests are run via Makefile.singlesrc so don't run them twice. --- Diffs of the changes: Index: llvm/test/Regression/LLC/Makefile diff -u llvm/test/Regression/LLC/Makefile:1.3 llvm/test/Regression/LLC/Makefile:1.4 --- llvm/test/Regression/LLC/Makefile:1.3 Thu Aug 1 15:50:54 2002 +++ llvm/test/Regression/LLC/Makefile Mon Sep 23 09:23:15 2002 @@ -5,7 +5,9 @@ LEVEL = ../../.. include $(LEVEL)/test/Programs/SingleSource/Makefile.singlesrc -TESTS := $(wildcard *.ll) $(wildcard *.c) +# Only .ll tests here. C tests are run via Makefile.singlesrc above. +# +TESTS := $(wildcard *.ll) all:: $(addprefix Output/, $(filter-out %.c, $(TESTS:%.ll=%.ts))) From vadve at psmith.cs.uiuc.edu Mon Sep 23 09:25:00 2002 From: vadve at psmith.cs.uiuc.edu (Vikram Adve) Date: Mon Sep 23 09:25:00 2002 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200209231423.g8NENuk27397@psmith.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.13 -> 1.14 --- Log message: Allow LLC to be executed on Linux; only the LLC output should not be executed. --- Diffs of the changes: Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.13 llvm/test/Programs/Makefile.programs:1.14 --- llvm/test/Programs/Makefile.programs:1.13 Thu Sep 19 13:23:14 2002 +++ llvm/test/Programs/Makefile.programs Mon Sep 23 09:23:52 2002 @@ -41,6 +41,9 @@ # We will be working in the Output directory... PREFIXED_PROGRAMS_TO_TEST := $(addprefix Output/,$(PROGRAMS_TO_TEST)) +# Generated code for llc (which does not require the target platform) +LLCCODEGEN := $(addsuffix .llc.s, $(PREFIXED_PROGRAMS_TO_TEST)) + # Output produced by programs run GCCOUTPUT := $(addsuffix .ll, $(addprefix Output/,$(Source:.c=))) NATOUTPUT := $(addsuffix .out-nat, $(PREFIXED_PROGRAMS_TO_TEST)) @@ -67,7 +70,7 @@ endif ifndef DISABLE_LLC -all:: $(LLCOUTPUT) +all:: $(LLCCODEGEN) else DISABLE_LLC_DIFFS = 1 endif From vadve at psmith.cs.uiuc.edu Mon Sep 23 09:25:01 2002 From: vadve at psmith.cs.uiuc.edu (Vikram Adve) Date: Mon Sep 23 09:25:01 2002 Subject: [llvm-commits] CVS: llvm/Makefile.Linux Message-ID: <200209231424.g8NEOMG27412@psmith.cs.uiuc.edu> Changes in directory llvm: Makefile.Linux updated: 1.3 -> 1.4 --- Log message: Allow LLC to be executed on Linux; only the LLC output should not be executed. --- Diffs of the changes: Index: llvm/Makefile.Linux diff -u llvm/Makefile.Linux:1.3 llvm/Makefile.Linux:1.4 --- llvm/Makefile.Linux:1.3 Thu Sep 19 16:32:44 2002 +++ llvm/Makefile.Linux Mon Sep 23 09:24:19 2002 @@ -22,6 +22,7 @@ LLVMGCCDIR := /home/vadve/lattner/cvs/gcc_install_x86 endif -# For now we disable all LLC tests, because LLC does not generate x86 code -# -DISABLE_LLC := 1 \ No newline at end of file +# For now we disable running LLC output, because LLC does not generate x86 code +# LLC itself can be run so disable the diffs, not LLC itself. +# +DISABLE_LLC_DIFFS := 1 From lattner at cs.uiuc.edu Mon Sep 23 12:46:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 12:46:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Value.h Message-ID: <200209231745.MAA04705@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Value.h updated: 1.36 -> 1.37 --- Log message: Group #includes better --- Diffs of the changes: Index: llvm/include/llvm/Value.h diff -u llvm/include/llvm/Value.h:1.36 llvm/include/llvm/Value.h:1.37 --- llvm/include/llvm/Value.h:1.36 Tue Sep 10 10:26:27 2002 +++ llvm/include/llvm/Value.h Mon Sep 23 12:45:52 2002 @@ -10,11 +10,11 @@ #ifndef LLVM_VALUE_H #define LLVM_VALUE_H -#include #include "llvm/Annotation.h" #include "llvm/AbstractTypeUser.h" #include "Support/Casting.h" #include +#include class User; class Type; From lattner at cs.uiuc.edu Mon Sep 23 13:14:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 13:14:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Linker.cpp Message-ID: <200209231814.NAA04924@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Linker.cpp updated: 1.31 -> 1.32 --- Log message: Insert resolved constants into the global map so they are reused correctly. This bug was exposed linking the SPEC benchmark suite. --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/Linker.cpp diff -u llvm/lib/Transforms/Utils/Linker.cpp:1.31 llvm/lib/Transforms/Utils/Linker.cpp:1.32 --- llvm/lib/Transforms/Utils/Linker.cpp:1.31 Tue Aug 20 14:35:11 2002 +++ llvm/lib/Transforms/Utils/Linker.cpp Mon Sep 23 13:14:15 2002 @@ -81,7 +81,7 @@ // automatically handle constant references correctly as well... // static Value *RemapOperand(const Value *In, map &LocalMap, - const map *GlobalMap = 0) { + map *GlobalMap = 0) { map::const_iterator I = LocalMap.find(In); if (I != LocalMap.end()) return I->second; @@ -148,7 +148,10 @@ } // Cache the mapping in our local map structure... - LocalMap.insert(std::make_pair(In, Result)); + if (GlobalMap) + GlobalMap->insert(std::make_pair(In, Result)); + else + LocalMap.insert(std::make_pair(In, Result)); return Result; } @@ -314,7 +317,7 @@ // function, and that Src is not. // static bool LinkFunctionBody(Function *Dest, const Function *Src, - const map &GlobalMap, + map &GlobalMap, string *Err = 0) { assert(Src && Dest && Dest->isExternal() && !Src->isExternal()); map LocalMap; // Map for function local values From lattner at cs.uiuc.edu Mon Sep 23 14:54:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 14:54:05 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CorrelatedExprs/2002-09-23-PHIUpdateBug.ll Message-ID: <200209231954.OAA13977@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CorrelatedExprs: 2002-09-23-PHIUpdateBug.ll added (r1.1) --- Log message: New testcase distilled from SPEC MCF benchmark --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Sep 23 15:05:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 15:05:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CorrelatedExprs/2002-09-23-PHIUpdateBug.ll Message-ID: <200209232004.PAA14722@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CorrelatedExprs: 2002-09-23-PHIUpdateBug.ll updated: 1.1 -> 1.2 --- Log message: Fix testcase to accurately expose bug --- Diffs of the changes: Index: llvm/test/Regression/Transforms/CorrelatedExprs/2002-09-23-PHIUpdateBug.ll diff -u llvm/test/Regression/Transforms/CorrelatedExprs/2002-09-23-PHIUpdateBug.ll:1.1 llvm/test/Regression/Transforms/CorrelatedExprs/2002-09-23-PHIUpdateBug.ll:1.2 --- llvm/test/Regression/Transforms/CorrelatedExprs/2002-09-23-PHIUpdateBug.ll:1.1 Mon Sep 23 14:54:06 2002 +++ llvm/test/Regression/Transforms/CorrelatedExprs/2002-09-23-PHIUpdateBug.ll Mon Sep 23 15:04:54 2002 @@ -5,17 +5,21 @@ declare void %foo(int) void %test(int %A, bool %C) { - br bool %C, label %bb3, label %bb1 + br bool %C, label %bb0, label %bb1 +bb0: + br label %bb3 +Unreachable: + br label %bb2 bb1: ;[#uses=0] %cond212 = setgt int %A, 9 ; [#uses=1] - br bool %cond212, label %bb2, label %bb3 + br bool %cond212, label %bb2, label %bb7 bb2: ;[#uses=1] %cond = setgt int %A, 7 br bool %cond, label %bb3, label %bb7 bb3: ;[#uses=1] - %X = phi int [ 0, %0], [ 12, %bb1] + %X = phi int [ 0, %bb0], [ 12, %bb2] call void %foo( int %X ) br label %bb7 From lattner at cs.uiuc.edu Mon Sep 23 15:07:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 15:07:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp Message-ID: <200209232006.PAA14736@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: CorrelatedExprs.cpp updated: 1.2 -> 1.3 --- Log message: * Fix bug: CorrelatedExprs/2002-09-23-PHIUpdateBug.ll * Make sure "Changed" is updated correctly --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp diff -u llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.2 llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.3 --- llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.2 Sun Sep 8 13:55:04 2002 +++ llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp Mon Sep 23 15:06:22 2002 @@ -23,6 +23,7 @@ #include "llvm/Pass.h" #include "llvm/Function.h" #include "llvm/iTerminators.h" +#include "llvm/iPHINode.h" #include "llvm/iOperators.h" #include "llvm/ConstantHandling.h" #include "llvm/Assembly/Writer.h" @@ -349,19 +350,33 @@ // another conditional branch, one whose outcome is known inside of this // region, then vector this outgoing edge directly to the known destination. // - for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { + 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); ++BranchRevectors; + Changed = true; } - } // Now that all of our successors have information, recursively process them. for (unsigned i = 0, e = BBN->getChildren().size(); i != e; ++i) Changed |= TransformRegion(BBN->getChildren()[i]->getNode(), VisitedBlocks); - - // for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) - //Changed |= TransformRegion(TI->getSuccessor(i), VisitedBlocks); return Changed; } From hldnbrnd at cs.uiuc.edu Mon Sep 23 16:03:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Mon Sep 23 16:03:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200209232102.QAA08364@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.52 -> 1.53 --- Log message: Parenthesis are now added to casts of type array. --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.52 llvm/lib/CWriter/Writer.cpp:1.53 --- llvm/lib/CWriter/Writer.cpp:1.52 Fri Sep 20 18:26:33 2002 +++ llvm/lib/CWriter/Writer.cpp Mon Sep 23 16:02:50 2002 @@ -244,7 +244,8 @@ // Do not need parens around "* NameSoFar" if NameSoFar consists only // of zero or more '*' chars *and* this is not an unnamed pointer type // such as the result type in a cast statement. Otherwise, enclose in ( ). - if (ptrTypeNameNeedsParens(NameSoFar) || !namedContext) + if (ptrTypeNameNeedsParens(NameSoFar) || !namedContext || + PTy->getElementType()->getPrimitiveID() == Type::ArrayTyID) ptrName = "(" + ptrName + ")"; // return printType(PTy->getElementType(), ptrName); From lattner at cs.uiuc.edu Mon Sep 23 17:26:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 17:26:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ConstantMerge/ Message-ID: <200209232225.RAA16453@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ConstantMerge: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Regression/Transforms/ConstantMerge added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Sep 23 17:27:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 17:27:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Makefile Message-ID: <200209232226.RAA16468@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms: Makefile updated: 1.16 -> 1.17 --- Log message: Run constantmerge tests too --- Diffs of the changes: Index: llvm/test/Regression/Transforms/Makefile diff -u llvm/test/Regression/Transforms/Makefile:1.16 llvm/test/Regression/Transforms/Makefile:1.17 --- llvm/test/Regression/Transforms/Makefile:1.16 Mon Sep 16 14:09:11 2002 +++ llvm/test/Regression/Transforms/Makefile Mon Sep 23 17:26:23 2002 @@ -1,6 +1,6 @@ LEVEL = ../../.. -DIRS = ADCE CFGSimplify ConstProp CorrelatedExprs DecomposeMultiDimRefs \ - FunctionResolve GCSE \ +DIRS = ADCE CFGSimplify ConstProp ConstantMerge CorrelatedExprs \ + DecomposeMultiDimRefs FunctionResolve GCSE \ GlobalDCE IndVarSimplify Inline InstCombine LevelRaise LICM Mem2Reg \ PiNodeInserter ProfilePaths Reassociate SCCP SimplifyCFG include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Mon Sep 23 17:31:07 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 17:31:07 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ConstantMerge/2002-09-23-CPR-Update.ll Makefile Message-ID: <200209232231.RAA16601@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ConstantMerge: 2002-09-23-CPR-Update.ll added (r1.1) Makefile added (r1.1) --- Log message: New testcase distilled from SPEC vortex benchmark --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Sep 23 18:01:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 18:01:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/ConstantMerge.cpp Message-ID: <200209232300.SAA17488@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: ConstantMerge.cpp updated: 1.15 -> 1.16 --- Log message: Fix: ConstantMerge/2002-09-23-CPR-Update.ll Basically, this bug boiled down to calling replaceUsesOfWith on a constant, which changed it's shape in an illegal way. This pass now goes through all of the trouble neccesary to do the replacement on constants. --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/ConstantMerge.cpp diff -u llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.15 llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.16 --- llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.15 Fri Jul 26 16:12:33 2002 +++ llvm/lib/Transforms/IPO/ConstantMerge.cpp Mon Sep 23 18:00:46 2002 @@ -3,19 +3,16 @@ // This file defines the interface to a pass that merges duplicate global // constants together into a single constant that is shared. This is useful // because some passes (ie TraceValues) insert a lot of string constants into -// the program, regardless of whether or not they duplicate an existing string. +// the program, regardless of whether or not an existing string is available. // // Algorithm: ConstantMerge is designed to build up a map of available constants -// and elminate duplicates when it is initialized. -// -// The DynamicConstantMerge method is a superset of the ConstantMerge algorithm -// that checks for each function to see if constants have been added to the -// constant pool since it was last run... if so, it processes them. +// and eliminate duplicates when it is initialized. // //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" #include "llvm/Module.h" +#include "llvm/Constants.h" #include "llvm/Pass.h" #include "Support/StatisticReporter.h" @@ -26,9 +23,9 @@ // bool run(Module &M); - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.preservesCFG(); - } + private: + void replaceUsesOfWith(GlobalVariable *Old, GlobalVariable *New); + void replaceConstantWith(Constant *Old, Constant *New); }; Statistic<> NumMerged("constmerge\t\t- Number of global constants merged"); @@ -38,10 +35,6 @@ Pass *createConstantMergePass() { return new ConstantMerge(); } -// ConstantMerge::run - Workhorse for the pass. This eliminates duplicate -// constants, starting at global ConstantNo, and adds vars to the map if they -// are new and unique. -// bool ConstantMerge::run(Module &M) { std::map CMap; bool MadeChanges = false; @@ -58,7 +51,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... - GV->replaceAllUsesWith(I->second); + replaceUsesOfWith(GV, I->second); // Delete the global value from the module... and back up iterator to // not skip the next global... @@ -70,4 +63,99 @@ } 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 Mon Sep 23 18:39:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 18:39:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/cast.ll Message-ID: <200209232339.SAA19690@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: cast.ll updated: 1.5 -> 1.6 --- Log message: Add some more testcases for things to get optimized away --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/cast.ll diff -u llvm/test/Regression/Transforms/InstCombine/cast.ll:1.5 llvm/test/Regression/Transforms/InstCombine/cast.ll:1.6 --- llvm/test/Regression/Transforms/InstCombine/cast.ll:1.5 Thu Aug 15 11:13:29 2002 +++ llvm/test/Regression/Transforms/InstCombine/cast.ll Mon Sep 23 18:39:17 2002 @@ -57,3 +57,14 @@ ret long %res } +short %test9(short %A) { + %c1 = cast short %A to int + %c2 = cast int %c1 to short + ret short %c2 +} + +short %test10(short %A) { + %c1 = cast short %A to uint + %c2 = cast uint %c1 to short + ret short %c2 +} From lattner at cs.uiuc.edu Mon Sep 23 18:40:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 18:40:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200209232339.SAA19702@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.57 -> 1.58 --- Log message: Optimize away cases like: %cast109 = cast uint %cast212 to short ; [#uses=1] %cast214 = cast short %cast109 to uint ; [#uses=1] %cast215 = cast uint %cast214 to short ; [#uses=1] --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.57 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.58 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.57 Tue Sep 17 16:05:42 2002 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Sep 23 18:39:43 2002 @@ -536,6 +536,12 @@ if (SrcSize >= MidSize && MidSize >= DstSize) return true; + // Cases where the source and destination type are the same, but the middle + // type is bigger are noops. + // + if (SrcSize == DstSize && MidSize > SrcSize) + return true; + // If we are monotonically growing, things are more complex. // if (SrcSize <= MidSize && MidSize <= DstSize) { From lattner at cs.uiuc.edu Mon Sep 23 18:42:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 18:42:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2002-05-14-TouchDeletedInst.ll Message-ID: <200209232341.SAA19762@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2002-05-14-TouchDeletedInst.ll updated: 1.3 -> 1.4 --- Log message: Convert to using long indexes instead of uint --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/2002-05-14-TouchDeletedInst.ll diff -u llvm/test/Regression/Transforms/InstCombine/2002-05-14-TouchDeletedInst.ll:1.3 llvm/test/Regression/Transforms/InstCombine/2002-05-14-TouchDeletedInst.ll:1.4 --- llvm/test/Regression/Transforms/InstCombine/2002-05-14-TouchDeletedInst.ll:1.3 Sun Sep 8 22:42:14 2002 +++ llvm/test/Regression/Transforms/InstCombine/2002-05-14-TouchDeletedInst.ll Mon Sep 23 18:41:53 2002 @@ -6,12 +6,13 @@ ; ; RUN: as < %s | opt -instcombine ; - %.LC0 = internal global [21 x sbyte] c"hbMakeCodeLengths(1)\00" ; <[21 x sbyte]*> [#uses=1] %.LC1 = internal global [21 x sbyte] c"hbMakeCodeLengths(2)\00" ; <[21 x sbyte]*> [#uses=1] -void "hbMakeCodeLengths"(ubyte* %len, int* %freq, int %alphaSize, int %maxLen) { +implementation ; Functions: + +void %hbMakeCodeLengths(ubyte* %len, int* %freq, int %alphaSize, int %maxLen) { bb0: ;[#uses=0] %len = alloca ubyte* ; [#uses=2] store ubyte* %len, ubyte** %len @@ -38,9 +39,10 @@ %reg591 = phi int [ %reg594, %bb5 ], [ 0, %bb1 ] ; [#uses=3] %reg591-idxcast1 = cast int %reg591 to uint ; [#uses=1] %reg591-idxcast1-offset = add uint %reg591-idxcast1, 1 ; [#uses=1] - %reg126 = getelementptr int* %weight, uint %reg591-idxcast1-offset ; [#uses=1] - %reg591-idxcast = cast int %reg591 to uint ; [#uses=1] - %reg132 = getelementptr int* %reg108, uint %reg591-idxcast ; [#uses=1] + %reg591-idxcast1-offset = cast uint %reg591-idxcast1-offset to long ; [#uses=1] + %reg126 = getelementptr int* %weight, long %reg591-idxcast1-offset ; [#uses=1] + %reg591-idxcast = cast int %reg591 to long ; [#uses=1] + %reg132 = getelementptr int* %reg108, long %reg591-idxcast ; [#uses=1] %reg133 = load int* %reg132 ; [#uses=2] %cond748 = seteq int %reg133, 0 ; [#uses=1] br bool %cond748, label %bb4, label %bb3 @@ -71,16 +73,19 @@ %reg597-casted = cast uint %reg597 to int ; [#uses=1] %reg596 = add int %reg597-casted, 1 ; [#uses=3] %reg597-offset = add uint %reg597, 1 ; [#uses=1] - %reg149 = getelementptr int* %parent, uint %reg597-offset ; [#uses=1] + %reg597-offset = cast uint %reg597-offset to long ; [#uses=1] + %reg149 = getelementptr int* %parent, long %reg597-offset ; [#uses=1] store int -1, int* %reg149 %reg598 = add uint %reg597, 1 ; [#uses=3] %reg597-offset1 = add uint %reg597, 1 ; [#uses=1] - %reg157 = getelementptr int* %heap, uint %reg597-offset1 ; [#uses=1] + %reg597-offset1 = cast uint %reg597-offset1 to long ; [#uses=1] + %reg157 = getelementptr int* %heap, long %reg597-offset1 ; [#uses=1] store int %reg596, int* %reg157 br label %bb9 bb8: ;[#uses=2] - %reg198 = getelementptr int* %heap, uint %reg599 ; [#uses=1] + %reg599 = cast uint %reg599 to long ; [#uses=1] + %reg198 = getelementptr int* %heap, long %reg599 ; [#uses=1] store int %reg182, int* %reg198 %cast938 = cast int %reg174 to uint ; [#uses=1] br label %bb9 @@ -89,20 +94,24 @@ %reg599 = phi uint [ %cast938, %bb8 ], [ %reg598, %bb7 ] ; [#uses=3] %cast807 = cast uint %reg599 to int ; [#uses=1] %reg597-offset2 = add uint %reg597, 1 ; [#uses=1] - %reg173 = getelementptr int* %weight, uint %reg597-offset2 ; [#uses=1] + %reg597-offset2 = cast uint %reg597-offset2 to long ; [#uses=1] + %reg173 = getelementptr int* %weight, long %reg597-offset2 ; [#uses=1] %reg174 = shr int %cast807, ubyte 1 ; [#uses=2] %reg174-idxcast = cast int %reg174 to uint ; [#uses=1] - %reg181 = getelementptr int* %heap, uint %reg174-idxcast ; [#uses=1] + cast uint %reg174-idxcast to long ; :0 [#uses=1] + %reg181 = getelementptr int* %heap, long %0 ; [#uses=1] %reg182 = load int* %reg181 ; [#uses=2] %reg182-idxcast = cast int %reg182 to uint ; [#uses=1] - %reg189 = getelementptr int* %weight, uint %reg182-idxcast ; [#uses=1] + cast uint %reg182-idxcast to long ; :1 [#uses=1] + %reg189 = getelementptr int* %weight, long %1 ; [#uses=1] %reg190 = load int* %reg173 ; [#uses=1] %reg191 = load int* %reg189 ; [#uses=1] %cond751 = setlt int %reg190, %reg191 ; [#uses=1] br bool %cond751, label %bb8, label %bb10 bb10: ;[#uses=3] - %reg214 = getelementptr int* %heap, uint %reg599 ; [#uses=1] + cast uint %reg599 to long ; :2 [#uses=1] + %reg214 = getelementptr int* %heap, long %2 ; [#uses=1] store int %reg596, int* %reg214 %reg601 = add int %reg596, 1 ; [#uses=1] %cond752 = setle int %reg601, %reg109 ; [#uses=1] @@ -116,7 +125,9 @@ br bool %cond753, label %bb13, label %bb12 bb12: ;[#uses=1] - %cast784 = getelementptr [21 x sbyte]* %.LC0, uint 0, uint 0 ; [#uses=1] + cast uint 0 to long ; :3 [#uses=1] + cast uint 0 to long ; :4 [#uses=1] + %cast784 = getelementptr [21 x sbyte]* %.LC0, long %3, long %4 ; [#uses=1] call void %panic( sbyte* %cast784 ) br label %bb13 @@ -134,15 +145,19 @@ %reg603 = add int %reg603-scale, %cast940 ; [#uses=4] %reg604 = add uint %cann-indvar1, %cast942 ; [#uses=4] %add1-indvar1 = add uint %cann-indvar1, 1 ; [#uses=1] - %reg7551 = getelementptr int* %heap, uint 1 ; [#uses=1] + cast uint 1 to long ; :5 [#uses=1] + %reg7551 = getelementptr int* %heap, long %5 ; [#uses=1] %reg113 = load int* %reg7551 ; [#uses=2] %reg603-idxcast = cast int %reg603 to uint ; [#uses=1] - %reg222 = getelementptr int* %heap, uint %reg603-idxcast ; [#uses=1] + cast uint %reg603-idxcast to long ; :6 [#uses=1] + %reg222 = getelementptr int* %heap, long %6 ; [#uses=1] %reg223 = load int* %reg222 ; [#uses=1] - %reg7561 = getelementptr int* %heap, uint 1 ; [#uses=1] + cast uint 1 to long ; :7 [#uses=1] + %reg7561 = getelementptr int* %heap, long %7 ; [#uses=1] store int %reg223, int* %reg7561 %reg605 = add int %reg603, -1 ; [#uses=4] - %reg757 = getelementptr int* %heap, uint 1 ; [#uses=1] + cast uint 1 to long ; :8 [#uses=1] + %reg757 = getelementptr int* %heap, long %8 ; [#uses=1] %reg226 = load int* %reg757 ; [#uses=2] %cond758 = setgt int 2, %reg605 ; [#uses=1] br bool %cond758, label %bb20, label %bb15 @@ -156,15 +171,19 @@ bb16: ;[#uses=2] %reg606-idxcast = cast int %reg606 to uint ; [#uses=1] %reg606-idxcast-offset = add uint %reg606-idxcast, 1 ; [#uses=1] - %reg241 = getelementptr int* %heap, uint %reg606-idxcast-offset ; [#uses=1] + cast uint %reg606-idxcast-offset to long ; :9 [#uses=1] + %reg241 = getelementptr int* %heap, long %9 ; [#uses=1] %reg242 = load int* %reg241 ; [#uses=1] %reg242-idxcast = cast int %reg242 to uint ; [#uses=1] - %reg249 = getelementptr int* %weight, uint %reg242-idxcast ; [#uses=1] + cast uint %reg242-idxcast to long ; :10 [#uses=1] + %reg249 = getelementptr int* %weight, long %10 ; [#uses=1] %reg606-idxcast1 = cast int %reg606 to uint ; [#uses=1] - %reg256 = getelementptr int* %heap, uint %reg606-idxcast1 ; [#uses=1] + cast uint %reg606-idxcast1 to long ; :11 [#uses=1] + %reg256 = getelementptr int* %heap, long %11 ; [#uses=1] %reg257 = load int* %reg256 ; [#uses=1] %reg257-idxcast = cast int %reg257 to uint ; [#uses=1] - %reg264 = getelementptr int* %weight, uint %reg257-idxcast ; [#uses=1] + cast uint %reg257-idxcast to long ; :12 [#uses=1] + %reg264 = getelementptr int* %weight, long %12 ; [#uses=1] %reg265 = load int* %reg249 ; [#uses=1] %reg266 = load int* %reg264 ; [#uses=1] %cond760 = setge int %reg265, %reg266 ; [#uses=1] @@ -177,12 +196,15 @@ bb18: ;[#uses=4] %reg609 = phi int [ %reg608, %bb17 ], [ %reg606, %bb16 ], [ %reg606, %bb15 ] ; [#uses=4] %reg226-idxcast = cast int %reg226 to uint ; [#uses=1] - %reg273 = getelementptr int* %weight, uint %reg226-idxcast ; [#uses=1] + cast uint %reg226-idxcast to long ; :13 [#uses=1] + %reg273 = getelementptr int* %weight, long %13 ; [#uses=1] %reg609-idxcast = cast int %reg609 to uint ; [#uses=1] - %reg280 = getelementptr int* %heap, uint %reg609-idxcast ; [#uses=1] + cast uint %reg609-idxcast to long ; :14 [#uses=1] + %reg280 = getelementptr int* %heap, long %14 ; [#uses=1] %reg281 = load int* %reg280 ; [#uses=2] %reg281-idxcast = cast int %reg281 to uint ; [#uses=1] - %reg288 = getelementptr int* %weight, uint %reg281-idxcast ; [#uses=1] + cast uint %reg281-idxcast to long ; :15 [#uses=1] + %reg288 = getelementptr int* %weight, long %15 ; [#uses=1] %reg289 = load int* %reg273 ; [#uses=1] %reg290 = load int* %reg288 ; [#uses=1] %cond761 = setlt int %reg289, %reg290 ; [#uses=1] @@ -190,7 +212,8 @@ bb19: ;[#uses=4] %reg607-idxcast = cast int %reg607 to uint ; [#uses=1] - %reg297 = getelementptr int* %heap, uint %reg607-idxcast ; [#uses=1] + cast uint %reg607-idxcast to long ; :16 [#uses=1] + %reg297 = getelementptr int* %heap, long %16 ; [#uses=1] store int %reg281, int* %reg297 %reg611 = shl int %reg609, ubyte 1 ; [#uses=2] %cond762 = setle int %reg611, %reg605 ; [#uses=1] @@ -199,18 +222,23 @@ bb20: ;[#uses=6] %reg612 = phi int [ %reg609, %bb19 ], [ %reg607, %bb18 ], [ 1, %bb14 ] ; [#uses=1] %reg612-idxcast = cast int %reg612 to uint ; [#uses=1] - %reg312 = getelementptr int* %heap, uint %reg612-idxcast ; [#uses=1] + cast uint %reg612-idxcast to long ; :17 [#uses=1] + %reg312 = getelementptr int* %heap, long %17 ; [#uses=1] store int %reg226, int* %reg312 - %reg7631 = getelementptr int* %heap, uint 1 ; [#uses=1] + cast uint 1 to long ; :18 [#uses=1] + %reg7631 = getelementptr int* %heap, long %18 ; [#uses=1] %reg114 = load int* %reg7631 ; [#uses=2] %reg603-idxcast1 = cast int %reg603 to uint ; [#uses=1] %reg603-idxcast1-offset = add uint %reg603-idxcast1, 1073741823 ; [#uses=1] - %reg319 = getelementptr int* %heap, uint %reg603-idxcast1-offset ; [#uses=1] + cast uint %reg603-idxcast1-offset to long ; :19 [#uses=1] + %reg319 = getelementptr int* %heap, long %19 ; [#uses=1] %reg320 = load int* %reg319 ; [#uses=1] - %reg7641 = getelementptr int* %heap, uint 1 ; [#uses=1] + cast uint 1 to long ; :20 [#uses=1] + %reg7641 = getelementptr int* %heap, long %20 ; [#uses=1] store int %reg320, int* %reg7641 %reg613 = add int %reg605, -1 ; [#uses=4] - %reg765 = getelementptr int* %heap, uint 1 ; [#uses=1] + cast uint 1 to long ; :21 [#uses=1] + %reg765 = getelementptr int* %heap, long %21 ; [#uses=1] %reg323 = load int* %reg765 ; [#uses=2] %cond766 = setgt int 2, %reg613 ; [#uses=1] br bool %cond766, label %bb26, label %bb21 @@ -224,15 +252,19 @@ bb22: ;[#uses=2] %reg614-idxcast = cast int %reg614 to uint ; [#uses=1] %reg614-idxcast-offset = add uint %reg614-idxcast, 1 ; [#uses=1] - %reg338 = getelementptr int* %heap, uint %reg614-idxcast-offset ; [#uses=1] + cast uint %reg614-idxcast-offset to long ; :22 [#uses=1] + %reg338 = getelementptr int* %heap, long %22 ; [#uses=1] %reg339 = load int* %reg338 ; [#uses=1] %reg339-idxcast = cast int %reg339 to uint ; [#uses=1] - %reg346 = getelementptr int* %weight, uint %reg339-idxcast ; [#uses=1] + cast uint %reg339-idxcast to long ; :23 [#uses=1] + %reg346 = getelementptr int* %weight, long %23 ; [#uses=1] %reg614-idxcast1 = cast int %reg614 to uint ; [#uses=1] - %reg353 = getelementptr int* %heap, uint %reg614-idxcast1 ; [#uses=1] + cast uint %reg614-idxcast1 to long ; :24 [#uses=1] + %reg353 = getelementptr int* %heap, long %24 ; [#uses=1] %reg354 = load int* %reg353 ; [#uses=1] %reg354-idxcast = cast int %reg354 to uint ; [#uses=1] - %reg361 = getelementptr int* %weight, uint %reg354-idxcast ; [#uses=1] + cast uint %reg354-idxcast to long ; :25 [#uses=1] + %reg361 = getelementptr int* %weight, long %25 ; [#uses=1] %reg362 = load int* %reg346 ; [#uses=1] %reg363 = load int* %reg361 ; [#uses=1] %cond768 = setge int %reg362, %reg363 ; [#uses=1] @@ -245,12 +277,15 @@ bb24: ;[#uses=4] %reg617 = phi int [ %reg616, %bb23 ], [ %reg614, %bb22 ], [ %reg614, %bb21 ] ; [#uses=4] %reg323-idxcast = cast int %reg323 to uint ; [#uses=1] - %reg370 = getelementptr int* %weight, uint %reg323-idxcast ; [#uses=1] + cast uint %reg323-idxcast to long ; :26 [#uses=1] + %reg370 = getelementptr int* %weight, long %26 ; [#uses=1] %reg617-idxcast = cast int %reg617 to uint ; [#uses=1] - %reg377 = getelementptr int* %heap, uint %reg617-idxcast ; [#uses=1] + cast uint %reg617-idxcast to long ; :27 [#uses=1] + %reg377 = getelementptr int* %heap, long %27 ; [#uses=1] %reg378 = load int* %reg377 ; [#uses=2] %reg378-idxcast = cast int %reg378 to uint ; [#uses=1] - %reg385 = getelementptr int* %weight, uint %reg378-idxcast ; [#uses=1] + cast uint %reg378-idxcast to long ; :28 [#uses=1] + %reg385 = getelementptr int* %weight, long %28 ; [#uses=1] %reg386 = load int* %reg370 ; [#uses=1] %reg387 = load int* %reg385 ; [#uses=1] %cond769 = setlt int %reg386, %reg387 ; [#uses=1] @@ -258,7 +293,8 @@ bb25: ;[#uses=4] %reg615-idxcast = cast int %reg615 to uint ; [#uses=1] - %reg394 = getelementptr int* %heap, uint %reg615-idxcast ; [#uses=1] + cast uint %reg615-idxcast to long ; :29 [#uses=1] + %reg394 = getelementptr int* %heap, long %29 ; [#uses=1] store int %reg378, int* %reg394 %reg619 = shl int %reg617, ubyte 1 ; [#uses=2] %cond770 = setle int %reg619, %reg613 ; [#uses=1] @@ -267,25 +303,31 @@ bb26: ;[#uses=4] %reg620 = phi int [ %reg617, %bb25 ], [ %reg615, %bb24 ], [ 1, %bb20 ] ; [#uses=1] %reg620-idxcast = cast int %reg620 to uint ; [#uses=1] - %reg409 = getelementptr int* %heap, uint %reg620-idxcast ; [#uses=1] + cast uint %reg620-idxcast to long ; :30 [#uses=1] + %reg409 = getelementptr int* %heap, long %30 ; [#uses=1] store int %reg323, int* %reg409 %reg621 = add uint %reg604, 1 ; [#uses=5] %reg113-idxcast = cast int %reg113 to uint ; [#uses=1] - %reg416 = getelementptr int* %parent, uint %reg113-idxcast ; [#uses=1] + cast uint %reg113-idxcast to long ; :31 [#uses=1] + %reg416 = getelementptr int* %parent, long %31 ; [#uses=1] %reg114-idxcast = cast int %reg114 to uint ; [#uses=1] - %reg423 = getelementptr int* %parent, uint %reg114-idxcast ; [#uses=1] + cast uint %reg114-idxcast to long ; :32 [#uses=1] + %reg423 = getelementptr int* %parent, long %32 ; [#uses=1] %cast889 = cast uint %reg621 to int ; [#uses=1] store int %cast889, int* %reg423 %cast890 = cast uint %reg621 to int ; [#uses=1] store int %cast890, int* %reg416 %reg604-offset = add uint %reg604, 1 ; [#uses=1] - %reg431 = getelementptr int* %weight, uint %reg604-offset ; [#uses=1] + cast uint %reg604-offset to long ; :33 [#uses=1] + %reg431 = getelementptr int* %weight, long %33 ; [#uses=1] %reg113-idxcast2 = cast int %reg113 to uint ; [#uses=1] - %reg4381 = getelementptr int* %weight, uint %reg113-idxcast2 ; [#uses=1] + cast uint %reg113-idxcast2 to long ; :34 [#uses=1] + %reg4381 = getelementptr int* %weight, long %34 ; [#uses=1] %reg439 = load int* %reg4381 ; [#uses=2] %reg440 = and int %reg439, -256 ; [#uses=1] %reg114-idxcast2 = cast int %reg114 to uint ; [#uses=1] - %reg4471 = getelementptr int* %weight, uint %reg114-idxcast2 ; [#uses=1] + cast uint %reg114-idxcast2 to long ; :35 [#uses=1] + %reg4471 = getelementptr int* %weight, long %35 ; [#uses=1] %reg448 = load int* %reg4471 ; [#uses=2] %reg449 = and int %reg448, -256 ; [#uses=1] %reg450 = add int %reg440, %reg449 ; [#uses=1] @@ -303,32 +345,38 @@ %reg470 = or int %reg450, %reg469 ; [#uses=1] store int %reg470, int* %reg431 %reg604-offset1 = add uint %reg604, 1 ; [#uses=1] - %reg4771 = getelementptr int* %parent, uint %reg604-offset1 ; [#uses=1] + cast uint %reg604-offset1 to long ; :36 [#uses=1] + %reg4771 = getelementptr int* %parent, long %36 ; [#uses=1] store int -1, int* %reg4771 %reg624 = add int %reg613, 1 ; [#uses=2] %reg603-idxcast2 = cast int %reg603 to uint ; [#uses=1] %reg603-idxcast2-offset = add uint %reg603-idxcast2, 1073741823 ; [#uses=1] - %reg485 = getelementptr int* %heap, uint %reg603-idxcast2-offset ; [#uses=1] + cast uint %reg603-idxcast2-offset to long ; :37 [#uses=1] + %reg485 = getelementptr int* %heap, long %37 ; [#uses=1] %cast902 = cast uint %reg621 to int ; [#uses=1] store int %cast902, int* %reg485 br label %bb30 bb29: ;[#uses=2] %reg625-idxcast = cast int %reg625 to uint ; [#uses=1] - %reg526 = getelementptr int* %heap, uint %reg625-idxcast ; [#uses=1] + cast uint %reg625-idxcast to long ; :38 [#uses=1] + %reg526 = getelementptr int* %heap, long %38 ; [#uses=1] store int %reg510, int* %reg526 br label %bb30 bb30: ;[#uses=2] %reg625 = phi int [ %reg502, %bb29 ], [ %reg624, %bb28 ] ; [#uses=3] %reg604-offset2 = add uint %reg604, 1 ; [#uses=1] - %reg501 = getelementptr int* %weight, uint %reg604-offset2 ; [#uses=1] + cast uint %reg604-offset2 to long ; :39 [#uses=1] + %reg501 = getelementptr int* %weight, long %39 ; [#uses=1] %reg502 = shr int %reg625, ubyte 1 ; [#uses=2] %reg502-idxcast = cast int %reg502 to uint ; [#uses=1] - %reg509 = getelementptr int* %heap, uint %reg502-idxcast ; [#uses=1] + cast uint %reg502-idxcast to long ; :40 [#uses=1] + %reg509 = getelementptr int* %heap, long %40 ; [#uses=1] %reg510 = load int* %reg509 ; [#uses=2] %reg510-idxcast = cast int %reg510 to uint ; [#uses=1] - %reg517 = getelementptr int* %weight, uint %reg510-idxcast ; [#uses=1] + cast uint %reg510-idxcast to long ; :41 [#uses=1] + %reg517 = getelementptr int* %weight, long %41 ; [#uses=1] %reg518 = load int* %reg501 ; [#uses=1] %reg519 = load int* %reg517 ; [#uses=1] %cond772 = setlt int %reg518, %reg519 ; [#uses=1] @@ -336,7 +384,8 @@ bb31: ;[#uses=3] %reg625-idxcast1 = cast int %reg625 to uint ; [#uses=1] - %reg542 = getelementptr int* %heap, uint %reg625-idxcast1 ; [#uses=1] + cast uint %reg625-idxcast1 to long ; :42 [#uses=1] + %reg542 = getelementptr int* %heap, long %42 ; [#uses=1] %cast916 = cast uint %reg621 to int ; [#uses=1] store int %cast916, int* %reg542 %cond773 = setgt int %reg624, 1 ; [#uses=1] @@ -349,7 +398,9 @@ br bool %cond774, label %bb34, label %bb33 bb33: ;[#uses=1] - %cast785 = getelementptr [21 x sbyte]* %.LC1, uint 0, uint 0 ; [#uses=1] + cast uint 0 to long ; :43 [#uses=1] + cast uint 0 to long ; :44 [#uses=1] + %cast785 = getelementptr [21 x sbyte]* %.LC1, long %43, long %44 ; [#uses=1] call void %panic( sbyte* %cast785 ) br label %bb34 @@ -364,7 +415,8 @@ %reg630 = add int %cann-indvar-casted, 1 ; [#uses=2] %add1-indvar = add uint %cann-indvar, 1 ; [#uses=1] %cann-indvar-offset1 = add uint %cann-indvar, 1 ; [#uses=1] - %reg589 = getelementptr int* %parent, uint %cann-indvar-offset1 ; [#uses=1] + cast uint %cann-indvar-offset1 to long ; :45 [#uses=1] + %reg589 = getelementptr int* %parent, long %45 ; [#uses=1] %reg590 = load int* %reg589 ; [#uses=1] %cond776 = setlt int %reg590, 0 ; [#uses=1] %parent-idxcast = cast int* %parent to uint ; [#uses=1] @@ -373,18 +425,21 @@ bb36: ;[#uses=5] %reg632 = phi uint [ %reg634, %bb36 ], [ %cast948, %bb35 ] ; [#uses=1] - %reg633 = phi uint [ %reg635, %bb36 ], [ 0, %bb35 ] ; [#uses=2] - %reg633-casted = cast uint %reg633 to sbyte* ; [#uses=1] - %reg631-scale = mul uint %reg633, 0 ; [#uses=1] - %reg631-scale = cast uint %reg631-scale to sbyte* - %reg6311 = getelementptr sbyte* %reg631-scale, uint %parent-idxcast ; [#uses=2] + %reg633 = phi uint [ %reg635, %bb36 ], [ 0, %bb35 ] ; [#uses=3] + %reg633-casted = cast uint %reg633 to sbyte* ; [#uses=0] + %reg631-scale = mul uint %reg633, 0 ; [#uses=1] + %reg631-scale = cast uint %reg631-scale to sbyte* ; [#uses=1] + cast uint %parent-idxcast to long ; :46 [#uses=1] + %reg6311 = getelementptr sbyte* %reg631-scale, long %46 ; [#uses=2] %reg632-scale = mul uint %reg632, 4 ; [#uses=1] - %reg5581 = getelementptr sbyte* %reg6311, uint %reg632-scale ; [#uses=1] + cast uint %reg632-scale to long ; :47 [#uses=1] + %reg5581 = getelementptr sbyte* %reg6311, long %47 ; [#uses=1] %cast924 = cast sbyte* %reg5581 to uint* ; [#uses=1] %reg634 = load uint* %cast924 ; [#uses=2] %reg635 = add uint %reg633, 1 ; [#uses=2] %reg634-scale = mul uint %reg634, 4 ; [#uses=1] - %reg5501 = getelementptr sbyte* %reg6311, uint %reg634-scale ; [#uses=1] + cast uint %reg634-scale to long ; :48 [#uses=1] + %reg5501 = getelementptr sbyte* %reg6311, long %48 ; [#uses=1] %cast925 = cast sbyte* %reg5501 to int* ; [#uses=1] %reg551 = load int* %cast925 ; [#uses=1] %cond777 = setge int %reg551, 0 ; [#uses=1] @@ -394,8 +449,10 @@ %reg637 = phi uint [ %reg635, %bb36 ], [ 0, %bb35 ] ; [#uses=2] %cast928 = cast uint %reg637 to int ; [#uses=1] %cann-indvar-offset = add uint %cann-indvar, 1 ; [#uses=1] - %reg561 = getelementptr ubyte* %reg107, uint %cann-indvar-offset ; [#uses=1] - %reg778 = getelementptr ubyte* %reg561, uint 4294967295 ; [#uses=1] + cast uint %cann-indvar-offset to long ; :49 [#uses=1] + %reg561 = getelementptr ubyte* %reg107, long %49 ; [#uses=1] + cast uint 4294967295 to long ; :50 [#uses=1] + %reg778 = getelementptr ubyte* %reg561, long %50 ; [#uses=1] %cast788 = cast uint %reg637 to ubyte ; [#uses=1] store ubyte %cast788, ubyte* %reg778 %cond779 = setle int %cast928, %reg110 ; [#uses=1] @@ -425,7 +482,8 @@ %add1-indvar2 = add int %cann-indvar2, 1 ; [#uses=1] %cann-indvar2-idxcast = cast int %cann-indvar2 to uint ; [#uses=1] %cann-indvar2-idxcast-offset = add uint %cann-indvar2-idxcast, 1 ; [#uses=1] - %reg569 = getelementptr int* %weight, uint %cann-indvar2-idxcast-offset ; [#uses=2] + cast uint %cann-indvar2-idxcast-offset to long ; :51 [#uses=1] + %reg569 = getelementptr int* %weight, long %51 ; [#uses=2] %reg570 = load int* %reg569 ; [#uses=2] %reg644 = shr int %reg570, ubyte 8 ; [#uses=1] %reg572 = shr int %reg570, ubyte 31 ; [#uses=1] @@ -448,4 +506,4 @@ ret void } -declare void "panic"(sbyte*) +declare void %panic(sbyte*) From lattner at cs.uiuc.edu Mon Sep 23 19:08:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 19:08:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/FindUsedTypes.cpp Message-ID: <200209240007.TAA20979@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: FindUsedTypes.cpp updated: 1.16 -> 1.17 --- Log message: Make users of FindUsedTypes not have problems with linkage. This fixes Cwriter. --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/FindUsedTypes.cpp diff -u llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.16 llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.17 --- llvm/lib/Analysis/IPA/FindUsedTypes.cpp:1.16 Wed Aug 21 12:09:41 2002 +++ llvm/lib/Analysis/IPA/FindUsedTypes.cpp Mon Sep 23 19:07:21 2002 @@ -14,6 +14,9 @@ static RegisterAnalysis X("printusedtypes", "Find Used Types"); +// stub to help linkage +void FindUsedTypes::stub() {} + // IncorporateType - Incorporate one type and all of its subtypes into the // collection of used types. // From lattner at cs.uiuc.edu Mon Sep 23 19:08:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 19:08:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/FindUsedTypes.h Message-ID: <200209240007.TAA20987@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: FindUsedTypes.h updated: 1.15 -> 1.16 --- Log message: Make users of FindUsedTypes not have problems with linkage. This fixes cwriter. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/FindUsedTypes.h diff -u llvm/include/llvm/Analysis/FindUsedTypes.h:1.15 llvm/include/llvm/Analysis/FindUsedTypes.h:1.16 --- llvm/include/llvm/Analysis/FindUsedTypes.h:1.15 Wed Aug 21 12:09:18 2002 +++ llvm/include/llvm/Analysis/FindUsedTypes.h Mon Sep 23 19:07:17 2002 @@ -15,33 +15,38 @@ class FindUsedTypes : public Pass { std::set UsedTypes; public: - // getTypes - After the pass has been run, return the set containing all of - // the types used in the module. - // + /// getTypes - After the pass has been run, return the set containing all of + /// the types used in the module. + /// const std::set &getTypes() const { return UsedTypes; } - // Print the types found in the module. If the optional Module parameter is - // passed in, then the types are printed symbolically if possible, using the - // symbol table from the module. - // + /// Print the types found in the module. If the optional Module parameter is + /// passed in, then the types are printed symbolically if possible, using the + /// symbol table from the module. + /// void print(std::ostream &o, const Module *M) const; private: - // IncorporateType - Incorporate one type and all of its subtypes into the - // collection of used types. - // + /// IncorporateType - Incorporate one type and all of its subtypes into the + /// collection of used types. + /// void IncorporateType(const Type *Ty); public: - // run - This incorporates all types used by the specified module - // + /// run - This incorporates all types used by the specified module bool run(Module &M); - // getAnalysisUsage - Of course, we provide ourself... - // + /// getAnalysisUsage - We do not modify anything. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } + + // stub - dummy function, just ignore it + static void stub(); }; + +// Make sure that any clients of this file link in PostDominators.cpp +static IncludeFile +FIND_USED_TYPES_INCLUDE_FILE((void*)&FindUsedTypes::stub); #endif From lattner at cs.uiuc.edu Mon Sep 23 19:08:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 19:08:03 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetData.h Message-ID: <200209240008.TAA20997@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetData.h updated: 1.8 -> 1.9 --- Log message: There are no implicit gep forms of load and store anymore --- Diffs of the changes: Index: llvm/include/llvm/Target/TargetData.h diff -u llvm/include/llvm/Target/TargetData.h:1.8 llvm/include/llvm/Target/TargetData.h:1.9 --- llvm/include/llvm/Target/TargetData.h:1.8 Mon Sep 16 15:44:19 2002 +++ llvm/include/llvm/Target/TargetData.h Mon Sep 23 19:08:01 2002 @@ -64,8 +64,7 @@ unsigned char getTypeAlignment(const Type *Ty) const; // getIndexOffset - return the offset from the beginning of the type for the - // specified indices. This is used to implement getElementPtr and load and - // stores that include the implicit form of getelementptr. + // specified indices. This is used to implement getelementptr. // uint64_t getIndexedOffset(const Type *Ty, const std::vector &Indices) const; From lattner at cs.uiuc.edu Mon Sep 23 19:09:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 19:09:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Scalar.h Message-ID: <200209240008.TAA21015@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: Scalar.h updated: 1.9 -> 1.10 --- Log message: Add new BreakCriticalEdges pass --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.9 llvm/include/llvm/Transforms/Scalar.h:1.10 --- llvm/include/llvm/Transforms/Scalar.h:1.9 Mon Sep 16 11:07:19 2002 +++ llvm/include/llvm/Transforms/Scalar.h Mon Sep 23 19:08:37 2002 @@ -175,6 +175,16 @@ // Pass *createCFGSimplificationPass(); +//===----------------------------------------------------------------------===// +// +// BreakCriticalEdges pass - Break all of the critical edges in the CFG by +// inserting a dummy basic block. This pass may be "required" by passes that +// cannot deal with critical edges. For this usage, the structure type is +// forward declared. This pass obviously invalidates the CFG, but can update +// forward dominator (set, immediate dominators, and tree) information. +// +class BreakCriticalEdges; +Pass *createBreakCriticalEdgesPass(); //===----------------------------------------------------------------------===// // These two passes convert malloc and free instructions to and from %malloc & From lattner at cs.uiuc.edu Mon Sep 23 19:09:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 19:09:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Message-ID: <200209240008.TAA21020@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: BreakCriticalEdges.cpp added (r1.1) --- Log message: Add new BreakCriticalEdges pass --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Sep 23 19:10:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 19:10:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200209240009.TAA21032@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: SimplifyCFG.cpp updated: 1.3 -> 1.4 --- Log message: Minor cleanups --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp diff -u llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.3 llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.4 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.3 Mon Jul 29 16:26:30 2002 +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp Mon Sep 23 19:09:26 2002 @@ -28,7 +28,9 @@ // static bool PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) { assert(*succ_begin(BB) == Succ && "Succ is not successor of BB!"); - assert(isa(Succ->front()) && "Only works on PHId BBs!"); + + if (!isa(Succ->front())) + return false; // We can make the transformation, no problem. // If there is more than one predecessor, and there are PHI nodes in // the successor, then we need to add incoming edges for the PHI nodes @@ -39,10 +41,9 @@ // Succ. If so, we cannot do the transformation! // for (pred_iterator PI = pred_begin(Succ), PE = pred_end(Succ); - PI != PE; ++PI) { + PI != PE; ++PI) if (find(BBPreds.begin(), BBPreds.end(), *PI) != BBPreds.end()) return true; - } // Loop over all of the PHI nodes in the successor BB for (BasicBlock::iterator I = Succ->begin(); @@ -118,11 +119,8 @@ // Be careful though, if this transformation fails (returns true) then // we cannot do this transformation! // - if (!isa(Succ->front()) || - !PropogatePredecessorsForPHIs(BB, Succ)) { - + if (!PropogatePredecessorsForPHIs(BB, Succ)) { //cerr << "Killing Trivial BB: \n" << BB; - BB->replaceAllUsesWith(Succ); std::string OldName = BB->getName(); From lattner at cs.uiuc.edu Mon Sep 23 19:10:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Sep 23 19:10:03 2002 Subject: [llvm-commits] CVS: llvm/tools/dis/dis.cpp Message-ID: <200209240009.TAA21044@apoc.cs.uiuc.edu> Changes in directory llvm/tools/dis: dis.cpp updated: 1.27 -> 1.28 --- Log message: Make sure to close the file before deleting it --- Diffs of the changes: Index: llvm/tools/dis/dis.cpp diff -u llvm/tools/dis/dis.cpp:1.27 llvm/tools/dis/dis.cpp:1.28 --- llvm/tools/dis/dis.cpp:1.27 Thu Sep 19 15:48:48 2002 +++ llvm/tools/dis/dis.cpp Mon Sep 23 19:09:48 2002 @@ -115,7 +115,10 @@ Passes.run(*M.get()); - if (Out != &std::cout) delete Out; + if (Out != &std::cout) { + ((std::ofstream*)Out)->close(); + delete Out; + } return 0; } From lattner at cs.uiuc.edu Tue Sep 24 10:43:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 10:43:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Scalar.h Message-ID: <200209241542.KAA23688@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: Scalar.h updated: 1.10 -> 1.11 --- Log message: Expose passinfo from BreakCriticalEdges pass so that it may be "Required" by other passes --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.10 llvm/include/llvm/Transforms/Scalar.h:1.11 --- llvm/include/llvm/Transforms/Scalar.h:1.10 Mon Sep 23 19:08:37 2002 +++ llvm/include/llvm/Transforms/Scalar.h Tue Sep 24 10:42:27 2002 @@ -10,8 +10,8 @@ class Pass; class TargetData; -class BasicBlock; class GetElementPtrInst; +class PassInfo; //===----------------------------------------------------------------------===// // @@ -162,7 +162,7 @@ // // This pass eliminates correlated conditions, such as these: // if (X == 0) -// if (X > 2) // Known false +// if (X > 2) ; // Known false // else // Y = X * Z; // = 0 // @@ -179,12 +179,15 @@ // // BreakCriticalEdges pass - Break all of the critical edges in the CFG by // inserting a dummy basic block. This pass may be "required" by passes that -// cannot deal with critical edges. For this usage, the structure type is -// forward declared. This pass obviously invalidates the CFG, but can update -// forward dominator (set, immediate dominators, and tree) information. +// cannot deal with critical edges. For this usage, a pass must call: +// +// AU.addRequiredID(BreakCriticalEdgesID); +// +// This pass obviously invalidates the CFG, but can update forward dominator +// (set, immediate dominators, and tree) information. // -class BreakCriticalEdges; Pass *createBreakCriticalEdgesPass(); +extern const PassInfo *BreakCriticalEdgesID; //===----------------------------------------------------------------------===// // These two passes convert malloc and free instructions to and from %malloc & From lattner at cs.uiuc.edu Tue Sep 24 10:43:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 10:43:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Message-ID: <200209241543.KAA23700@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: BreakCriticalEdges.cpp updated: 1.1 -> 1.2 --- Log message: - Expose passinfo from BreakCriticalEdges pass so that it may be "Required" by other passes. Make BCE pass be in anonymous namespace now. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp diff -u llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.1 llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.2 --- llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.1 Mon Sep 23 19:08:39 2002 +++ llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Tue Sep 24 10:43:12 2002 @@ -15,21 +15,24 @@ #include "llvm/InstrTypes.h" #include "Support/StatisticReporter.h" -static Statistic<> NumBroken("break-crit-edges\t- Number of blocks inserted"); +namespace { + Statistic<> NumBroken("break-crit-edges\t- Number of blocks inserted"); -class BreakCriticalEdges : public FunctionPass { -public: - virtual bool runOnFunction(Function &F); + struct BreakCriticalEdges : public FunctionPass { + virtual bool runOnFunction(Function &F); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + } + }; - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - } -}; + RegisterOpt X("break-crit-edges", + "Break critical edges in CFG"); +} -static RegisterOpt X("break-crit-edges", - "Break critical edges in CFG"); +const PassInfo *BreakCriticalEdgesID = X.getPassInfo(); Pass *createBreakCriticalEdgesPass() { return new BreakCriticalEdges(); } From lattner at cs.uiuc.edu Tue Sep 24 10:44:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 10:44:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp Message-ID: <200209241543.KAA23714@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: CorrelatedExprs.cpp updated: 1.3 -> 1.4 --- Log message: Correlated Exprs pass now requires BCE pass instead of doing it manually --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp diff -u llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.3 llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.4 --- llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp:1.3 Mon Sep 23 15:06:22 2002 +++ llvm/lib/Transforms/Scalar/CorrelatedExprs.cpp Tue Sep 24 10:43:56 2002 @@ -204,9 +204,9 @@ // We don't modify the program, so we preserve all analyses virtual void getAnalysisUsage(AnalysisUsage &AU) const { - //AU.preservesCFG(); AU.addRequired(); AU.addRequired(); + AU.addRequiredID(BreakCriticalEdgesID); }; // print - Implement the standard print form to print out analysis @@ -306,25 +306,6 @@ // Get the terminator of this basic block... TerminatorInst *TI = BB->getTerminator(); - - // If this is a conditional branch, make sure that there is a branch target - // for each successor that can hold any information gleaned from the branch, - // by breaking any critical edges that may be laying about. - // - if (TI->getNumSuccessors() > 1) { - // If any of the successors has multiple incoming branches, add a new dummy - // destination branch that only contains an unconditional branch to the real - // target. - for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { - BasicBlock *Succ = TI->getSuccessor(i); - // If there is more than one predecessor of the destination block, break - // this critical edge by inserting a new block. This updates dominatorset - // and dominatortree information. - // - if (isCriticalEdge(TI, i)) - SplitCriticalEdge(TI, i, this); - } - } // Loop over all of the blocks that this block is the immediate dominator for. // Because all information known in this region is also known in all of the From lattner at cs.uiuc.edu Tue Sep 24 10:52:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 10:52:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CriticalEdge.cpp Message-ID: <200209241552.KAA24392@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CriticalEdge.cpp (r1.3) removed --- Log message: - Do not expose Critical Edge breaking mechanics outside the BCE pass, thus removing it from Transforms/Local.h and from Transforms/Utils/* --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Sep 24 10:53:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 10:53:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Local.h Message-ID: <200209241552.KAA24397@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Local.h updated: 1.7 -> 1.8 --- Log message: - Do not expose Critical Edge breaking mechanics outside the BCE pass, thus removing it from Transforms/Local.h and from Transforms/Utils/* --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Utils/Local.h diff -u llvm/include/llvm/Transforms/Utils/Local.h:1.7 llvm/include/llvm/Transforms/Utils/Local.h:1.8 --- llvm/include/llvm/Transforms/Utils/Local.h:1.7 Thu Sep 5 21:35:11 2002 +++ llvm/include/llvm/Transforms/Utils/Local.h Tue Sep 24 10:51:54 2002 @@ -60,19 +60,4 @@ /// bool SimplifyCFG(BasicBlock *BB); - -/// 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 it is available, thus calling this pass will not invalidate either of -/// them. -/// -void SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P = 0); - #endif From lattner at cs.uiuc.edu Tue Sep 24 10:53:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 10:53:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Message-ID: <200209241552.KAA24402@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: BreakCriticalEdges.cpp updated: 1.2 -> 1.3 --- Log message: - Do not expose Critical Edge breaking mechanics outside the BCE pass, thus removing it from Transforms/Local.h and from Transforms/Utils/* --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp diff -u llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.2 llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.3 --- llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.2 Tue Sep 24 10:43:12 2002 +++ llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Tue Sep 24 10:51:56 2002 @@ -9,10 +9,11 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Function.h" -#include "llvm/InstrTypes.h" +#include "llvm/iTerminators.h" +#include "llvm/iPHINode.h" +#include "llvm/Support/CFG.h" #include "Support/StatisticReporter.h" namespace { @@ -32,10 +33,93 @@ "Break critical edges in CFG"); } +// Publically exposed interface to pass... const PassInfo *BreakCriticalEdgesID = X.getPassInfo(); - Pass *createBreakCriticalEdgesPass() { return new BreakCriticalEdges(); } + +// 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. +// +static bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum) { + assert(SuccNum < TI->getNumSuccessors() && "Illegal edge specification!"); + assert (TI->getNumSuccessors() > 1); + + const BasicBlock *Dest = TI->getSuccessor(SuccNum); + pred_const_iterator I = pred_begin(Dest), E = pred_end(Dest); + + // If there is more than one predecessor, this is a critical edge... + assert(I != E && "No preds, but we have an edge to the block?"); + ++I; // Skip one edge due to the incoming arc from TI. + return I != E; +} + +// SplitCriticalEdge - Insert a new node node to split the critical edge. This +// will update DominatorSet, ImmediateDominator and DominatorTree information if +// it is available, thus calling this pass will not invalidate either of them. +// +static 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(); + + // Create a new basic block, linking it into the CFG. + BasicBlock *NewBB = new BasicBlock(TIBB->getName()+"_crit_edge"); + BasicBlock *DestBB = TI->getSuccessor(SuccNum); + // Create our unconditional branch... + BranchInst *BI = new BranchInst(DestBB); + NewBB->getInstList().push_back(BI); + + // Branch to the new block, breaking the edge... + TI->setSuccessor(SuccNum, NewBB); + + // Insert the block into the function... right after the block TI lives in. + Function &F = *TIBB->getParent(); + F.getBasicBlockList().insert(TIBB->getNext(), NewBB); + + // If there are any PHI nodes in DestBB, we need to update them so that they + // merge incoming values from NewBB instead of from TIBB. + // + for (BasicBlock::iterator I = DestBB->begin(); + PHINode *PN = dyn_cast(&*I); ++I) { + // We no longer enter through TIBB, now we come in through NewBB. + PN->replaceUsesOfWith(TIBB, NewBB); + } + + // Now if we have a pass object, update analysis information. Currently we + // update DominatorSet and DominatorTree information if it's available. + // + if (P) { + // Should we update DominatorSet information? + 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); + DomSet.insert(NewBB); // A block always dominates itself. + DS->addBasicBlock(NewBB, DomSet); + } + + // Should we update ImmdediateDominator information? + 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 = P->getAnalysisToUpdate()) { + DominatorTree::Node *TINode = DT->getNode(TIBB); + + // 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); + } + } +} + // runOnFunction - Loop over all of the edges in the CFG, breaking critical // edges as they are found. // @@ -43,12 +127,13 @@ bool Changed = false; for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { TerminatorInst *TI = I->getTerminator(); - for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) - if (isCriticalEdge(TI, i)) { - SplitCriticalEdge(TI, i, this); - ++NumBroken; - Changed = true; - } + if (TI->getNumSuccessors() > 1) + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) + if (isCriticalEdge(TI, i)) { + SplitCriticalEdge(TI, i, this); + ++NumBroken; + Changed = true; + } } return Changed; From lattner at cs.uiuc.edu Tue Sep 24 11:03:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 11:03:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SimplifyCFG/2002-09-24-PHIAssertion.ll Message-ID: <200209241602.LAA24526@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SimplifyCFG: 2002-09-24-PHIAssertion.ll added (r1.1) --- Log message: New testcase that causes SimplifyCFG to assert out. --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Sep 24 11:10:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 11:10:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/SimplifyCFG.cpp Message-ID: <200209241609.LAA24839@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: SimplifyCFG.cpp updated: 1.4 -> 1.5 --- Log message: Fix bug: SimplifyCFG/2002-09-24-PHIAssertion.ll --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp diff -u llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.4 llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.5 --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.4 Mon Sep 23 19:09:26 2002 +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp Tue Sep 24 11:09:17 2002 @@ -167,14 +167,15 @@ TerminatorInst *Term = OnlyPred->getTerminator(); // Resolve any PHI nodes at the start of the block. They are all - // guaranteed to have exactly one entry if they exist. + // guaranteed to have exactly one entry if they exist, unless there are + // multiple duplicate (but guaranteed to be equal) entries for the + // incoming edges. This occurs when there are multiple edges from + // OnlyPred to OnlySucc. // while (PHINode *PN = dyn_cast(&BB->front())) { - assert(PN->getNumIncomingValues() == 1 && "Only one pred!"); PN->replaceAllUsesWith(PN->getIncomingValue(0)); BB->getInstList().pop_front(); // Delete the phi node... } - // Delete the unconditional branch from the predecessor... OnlyPred->getInstList().pop_back(); From lattner at cs.uiuc.edu Tue Sep 24 11:14:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 11:14:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SimplifyCFG/branch-fold-test.ll Message-ID: <200209241613.LAA24907@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SimplifyCFG: branch-fold-test.ll added (r1.1) --- Log message: New feature test for something we have done for a long time --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Sep 24 11:16:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 11:16:00 2002 Subject: [llvm-commits] CVS: llvm/www/docs/ChrisNotes.txt Message-ID: <200209241615.LAA24963@apoc.cs.uiuc.edu> Changes in directory llvm/www/docs: ChrisNotes.txt updated: 1.27 -> 1.28 --- Log message: A lot of this stuff has been done. Remove the done items --- Diffs of the changes: Index: llvm/www/docs/ChrisNotes.txt diff -u llvm/www/docs/ChrisNotes.txt:1.27 llvm/www/docs/ChrisNotes.txt:1.28 --- llvm/www/docs/ChrisNotes.txt:1.27 Fri Jun 28 17:06:39 2002 +++ llvm/www/docs/ChrisNotes.txt Tue Sep 24 11:15:36 2002 @@ -1,13 +1,6 @@ * Rewrite the llvm parser/lexer in http://www.antlr.org when time permits. They actually do C++. Imagine that. -* Fix DCE to elminate br , %L1, %L1 so that it can optimize the main of - fib.ll better. Currently I have to do this to get best results: - as < fib.ll | opt -inline -sccp -dce -sccp -dce |dis -* fix the constprop br case. Must handle PHI nodes correctly -* Think about whether edge split SSA form would be useful to do. -* The dropAllReferences code can be a noop when NDEBUG!!! * pred/succ iterators on basic blocks don't handle switch statements correctly -* Provide a pass that eliminates critical edges from the CFG * Need a way to attach bytecode block info at various levels of asm code. * Recognize and save comments in assembly and bytecode format * Encode line number table in bytecode (like #line), optional table From lattner at cs.uiuc.edu Tue Sep 24 16:19:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 16:19:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SimplifyCFG.cpp Message-ID: <200209242118.QAA28487@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SimplifyCFG.cpp updated: 1.4 -> 1.5 --- Log message: Eliminate extraneous #include --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/SimplifyCFG.cpp diff -u llvm/lib/Transforms/Scalar/SimplifyCFG.cpp:1.4 llvm/lib/Transforms/Scalar/SimplifyCFG.cpp:1.5 --- llvm/lib/Transforms/Scalar/SimplifyCFG.cpp:1.4 Fri Jul 26 16:12:42 2002 +++ llvm/lib/Transforms/Scalar/SimplifyCFG.cpp Tue Sep 24 16:18:40 2002 @@ -14,7 +14,6 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Module.h" -#include "llvm/GlobalVariable.h" #include "llvm/Support/CFG.h" #include "llvm/Pass.h" #include "Support/StatisticReporter.h" From lattner at cs.uiuc.edu Tue Sep 24 16:20:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Sep 24 16:20:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/PromoteMemoryToRegister.cpp Message-ID: <200209242119.QAA28503@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: PromoteMemoryToRegister.cpp updated: 1.30 -> 1.31 --- Log message: - Fix bug: Mem2Reg/2002-05-01-ShouldNotPromoteThisAlloca.ll --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/PromoteMemoryToRegister.cpp diff -u llvm/lib/Transforms/Scalar/PromoteMemoryToRegister.cpp:1.30 llvm/lib/Transforms/Scalar/PromoteMemoryToRegister.cpp:1.31 --- llvm/lib/Transforms/Scalar/PromoteMemoryToRegister.cpp:1.30 Tue Sep 10 17:38:47 2002 +++ llvm/lib/Transforms/Scalar/PromoteMemoryToRegister.cpp Tue Sep 24 16:19:41 2002 @@ -79,8 +79,13 @@ // Only allow direct loads and stores... for (Value::use_const_iterator UI = AI->use_begin(), UE = AI->use_end(); UI != UE; ++UI) // Loop over all of the uses of the alloca - if (!isa(*UI) && !isa(*UI)) - return false; // Not a load or store? + if (!isa(*UI)) + if (const StoreInst *SI = dyn_cast(*UI)) { + if (SI->getOperand(0) == AI) + return false; // Don't allow a store of the AI, only INTO the AI. + } else { + return false; // Not a load or store? + } return true; } From lattner at cs.uiuc.edu Wed Sep 25 12:16:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 12:16:01 2002 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200209251716.MAA03668@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.59 -> 1.60 --- Log message: Make sure to print message when linking a debug .o file --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.59 llvm/Makefile.common:1.60 --- llvm/Makefile.common:1.59 Sat Sep 21 21:47:15 2002 +++ llvm/Makefile.common Wed Sep 25 12:15:22 2002 @@ -333,6 +333,7 @@ $(VERB) $(Relink) -o $@ $(ObjectsP) $(LibSubDirs) $(LIBNAME_OBJG): $(ObjectsG) $(LibSubDirs) $(LIBDEBUG)/.dir + @echo "Linking $@" $(VERB) $(Relink) -o $@ $(ObjectsG) $(LibSubDirs) endif From lattner at cs.uiuc.edu Wed Sep 25 14:10:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 14:10:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/LoopInfo.h Message-ID: <200209251910.OAA04891@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: LoopInfo.h updated: 1.16 -> 1.17 --- Log message: Checkin stub for Misha to implement --- Diffs of the changes: Index: llvm/include/llvm/Analysis/LoopInfo.h diff -u llvm/include/llvm/Analysis/LoopInfo.h:1.16 llvm/include/llvm/Analysis/LoopInfo.h:1.17 --- llvm/include/llvm/Analysis/LoopInfo.h:1.16 Mon Aug 26 11:45:19 2002 +++ llvm/include/llvm/Analysis/LoopInfo.h Wed Sep 25 14:10:06 2002 @@ -40,6 +40,10 @@ inline const std::vector &getSubLoops() const { return SubLoops; } inline const std::vector &getBlocks() const { return Blocks; } + // isLoopExit - True if terminator in the block can branch to another block + // that is outside of the current loop. + bool isLoopExit(BasicBlock *BB) const; + void print(std::ostream &O) const; private: friend class LoopInfo; @@ -96,8 +100,6 @@ } // isLoopEnd - True if block jumps to loop entry bool isLoopEnd(BasicBlock *BB) const; - // isLoopExit - True if block is the loop exit - bool isLoopExit(BasicBlock *BB) const; #endif // runOnFunction - Pass framework implementation From hldnbrnd at cs.uiuc.edu Wed Sep 25 15:30:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Wed Sep 25 15:30:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200209252029.PAA10438@trinity.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.53 -> 1.54 --- Log message: Strings now handled correctly. --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.53 llvm/lib/CWriter/Writer.cpp:1.54 --- llvm/lib/CWriter/Writer.cpp:1.53 Mon Sep 23 16:02:50 2002 +++ llvm/lib/CWriter/Writer.cpp Wed Sep 25 15:29:26 2002 @@ -985,18 +985,23 @@ writeOperandInternal(Ptr); - if (HasImplicitAddress && (!CI || !CI->isNullValue())) + if (HasImplicitAddress && (!CI || !CI->isNullValue())) { Out << ")"; + HasImplicitAddress = false; // HIA is only true if we haven't addressed yet + } + + assert(!HasImplicitAddress || (CI && CI->isNullValue()) && + "Can only have implicit address with direct accessing"); - // Print out the -> operator if possible... - if (CI && CI->isNullValue() && I+1 != E) { + if (HasImplicitAddress) { + ++I; + } else if (CI && CI->isNullValue() && I+1 != E) { + // Print out the -> operator if possible... if ((*(I+1))->getType() == Type::UByteTy) { Out << (HasImplicitAddress ? "." : "->"); Out << "field" << cast(*(I+1))->getValue(); I += 2; - } else { // First array index of 0: Just skip it - ++I; - } + } } for (; I != E; ++I) @@ -1015,14 +1020,14 @@ } void CWriter::visitStoreInst(StoreInst &I) { - Out << "*"; + //Out << "*"; writeOperand(I.getPointerOperand()); Out << " = "; writeOperand(I.getOperand(0)); } void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) { - Out << "&"; + //Out << "&"; printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end()); } From lattner at cs.uiuc.edu Wed Sep 25 16:59:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 16:59:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Pass.h PassAnalysisSupport.h Message-ID: <200209252159.QAA12497@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Pass.h updated: 1.28 -> 1.29 PassAnalysisSupport.h updated: 1.9 -> 1.10 --- Log message: Add support for ImmutablePasses, which are not run, and cannot be invalidated. --- Diffs of the changes: Index: llvm/include/llvm/Pass.h diff -u llvm/include/llvm/Pass.h:1.28 llvm/include/llvm/Pass.h:1.29 --- llvm/include/llvm/Pass.h:1.28 Tue Sep 17 06:09:59 2002 +++ llvm/include/llvm/Pass.h Wed Sep 25 16:59:09 2002 @@ -32,6 +32,7 @@ class Module; class AnalysisUsage; class PassInfo; +class ImmutablePass; template class PassManagerT; struct AnalysisResolver; @@ -193,6 +194,24 @@ inline std::ostream &operator<<(std::ostream &OS, const Pass &P) { P.print(OS, 0); return OS; } + + + +//===----------------------------------------------------------------------===// +/// ImmutablePass class - This class is used to provide information that does +/// not need to be run. This is useful for things like target information and +/// "basic" versions of AnalysisGroups. +/// +struct ImmutablePass : public Pass { + + // ImmutablePasses are never run. + virtual bool run(Module &M) { return false; } + +private: + friend class PassManagerT; + virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); +}; + //===----------------------------------------------------------------------===// /// FunctionPass class - This class is used to implement most global Index: llvm/include/llvm/PassAnalysisSupport.h diff -u llvm/include/llvm/PassAnalysisSupport.h:1.9 llvm/include/llvm/PassAnalysisSupport.h:1.10 --- llvm/include/llvm/PassAnalysisSupport.h:1.9 Thu Aug 29 15:07:59 2002 +++ llvm/include/llvm/PassAnalysisSupport.h Wed Sep 25 16:59:09 2002 @@ -86,6 +86,7 @@ struct AnalysisResolver { virtual Pass *getAnalysisOrNullUp(AnalysisID ID) const = 0; virtual Pass *getAnalysisOrNullDown(AnalysisID ID) const = 0; + virtual void addPass(ImmutablePass *IP, AnalysisUsage &AU) = 0; Pass *getAnalysis(AnalysisID ID) const { Pass *Result = getAnalysisOrNullUp(ID); assert(Result && "Pass has an incorrect analysis uses set!"); From lattner at cs.uiuc.edu Wed Sep 25 16:59:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 16:59:03 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Pass.cpp PassManagerT.h Message-ID: <200209252159.QAA12504@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Pass.cpp updated: 1.37 -> 1.38 PassManagerT.h updated: 1.27 -> 1.28 --- Log message: Add support for ImmutablePasses, which are not run, and cannot be invalidated. --- Diffs of the changes: Index: llvm/lib/VMCore/Pass.cpp diff -u llvm/lib/VMCore/Pass.cpp:1.37 llvm/lib/VMCore/Pass.cpp:1.38 --- llvm/lib/VMCore/Pass.cpp:1.37 Fri Sep 13 09:47:12 2002 +++ llvm/lib/VMCore/Pass.cpp Wed Sep 25 16:59:11 2002 @@ -299,6 +299,15 @@ } //===----------------------------------------------------------------------===// +// ImmutablePass Implementation +// +void ImmutablePass::addToPassManager(PassManagerT *PM, + AnalysisUsage &AU) { + PM->addPass(this, AU); +} + + +//===----------------------------------------------------------------------===// // FunctionPass Implementation // Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.27 llvm/lib/VMCore/PassManagerT.h:1.28 --- llvm/lib/VMCore/PassManagerT.h:1.27 Thu Sep 12 12:06:40 2002 +++ llvm/lib/VMCore/PassManagerT.h Wed Sep 25 16:59:11 2002 @@ -129,8 +129,10 @@ friend typename Traits::PassClass; friend typename Traits::SubPassClass; friend class Traits; + friend class ImmutablePass; std::vector Passes; // List of passes to run + std::vector ImmutablePasses; // List of immutable passes // The parent of this pass manager... ParentClass * const Parent; @@ -157,6 +159,10 @@ for (typename std::vector::iterator I = Passes.begin(), E = Passes.end(); I != E; ++I) delete *I; + + for (std::vector::iterator + I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + delete *I; } // run - Run all of the queued passes on the specified module in an optimal @@ -166,6 +172,17 @@ closeBatcher(); CurrentAnalyses.clear(); + // Add any immutable passes to the CurrentAnalyses set... + for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) + if (const PassInfo *PI = ImmutablePasses[i]->getPassInfo()) { + CurrentAnalyses[PI] = ImmutablePasses[i]; + + const std::vector &II = PI->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) + CurrentAnalyses[II[i]] = ImmutablePasses[i]; + } + + // LastUserOf - This contains the inverted LastUseOfMap... std::map > LastUserOf; for (std::map::iterator I = LastUseOf.begin(), @@ -238,13 +255,17 @@ PreservedSet.end()) ++I; // This analysis is preserved, leave it in the available set... else { + if (!dynamic_cast(I->second)) { #if MAP_DOESNT_HAVE_BROKEN_ERASE_MEMBER - I = CurrentAnalyses.erase(I); // Analysis not preserved! + I = CurrentAnalyses.erase(I); // Analysis not preserved! #else - // GCC 2.95.3 STL doesn't have correct erase member! - CurrentAnalyses.erase(I); - I = CurrentAnalyses.begin(); + // GCC 2.95.3 STL doesn't have correct erase member! + CurrentAnalyses.erase(I); + I = CurrentAnalyses.begin(); #endif + } else { + ++I; + } } } @@ -345,11 +366,15 @@ // parent that we (the passmanager) are using the analysis so that it // frees the analysis AFTER this pass manager runs. // - assert(Parent != 0 && "Pass available but not found!"); - Parent->markPassUsed(P, this); + if (Parent) { + Parent->markPassUsed(P, this); + } else { + assert(0 && "Pass available but not found! " + "Perhaps this is a module pass requiring a function pass?"); + } } } - + // Return the number of parent PassManagers that exist virtual unsigned getDepth() const { if (Parent == 0) return 0; @@ -428,18 +453,15 @@ if (!AnUsage.preservesAll()) { const std::vector &PreservedSet = AnUsage.getPreservedSet(); for (std::map::iterator I = CurrentAnalyses.begin(), - E = CurrentAnalyses.end(); I != E; ) - if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) != - PreservedSet.end()) - ++I; // This analysis is preserved, leave it in the available set... - else { -#if MAP_DOESNT_HAVE_BROKEN_ERASE_MEMBER - I = CurrentAnalyses.erase(I); // Analysis not preserved! -#else - CurrentAnalyses.erase(I);// GCC 2.95.3 STL doesn't have correct erase! + E = CurrentAnalyses.end(); I != E; ) { + if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) == + PreservedSet.end()) { // Analysis not preserved! + CurrentAnalyses.erase(I); // Remove from available analyses I = CurrentAnalyses.begin(); -#endif + } else { + ++I; } + } } // Add this pass to the currently available set... @@ -474,6 +496,34 @@ if (Batcher) { Passes.push_back(Batcher); Batcher = 0; + } + } + +public: + // When an ImmutablePass is added, it gets added to the top level pass + // manager. + void addPass(ImmutablePass *IP, AnalysisUsage &AU) { + if (Parent) { // Make sure this request goes to the top level passmanager... + Parent->addPass(IP, AU); + return; + } + + // Set the Resolver instance variable in the Pass so that it knows where to + // find this object... + // + setAnalysisResolver(IP, this); + ImmutablePasses.push_back(IP); + + // Add this pass to the currently available set... + if (const PassInfo *PI = IP->getPassInfo()) { + CurrentAnalyses[PI] = IP; + + // This pass is the current implementation of all of the interfaces it + // implements as well. + // + const std::vector &II = PI->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) + CurrentAnalyses[II[i]] = IP; } } }; From lattner at cs.uiuc.edu Wed Sep 25 17:01:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 17:01:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/BasicAliasAnalysis.h Message-ID: <200209252200.RAA12523@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: BasicAliasAnalysis.h updated: 1.3 -> 1.4 --- Log message: Convert BasicAA to be an immutable pass instead of a FunctionPass --- Diffs of the changes: Index: llvm/include/llvm/Analysis/BasicAliasAnalysis.h diff -u llvm/include/llvm/Analysis/BasicAliasAnalysis.h:1.3 llvm/include/llvm/Analysis/BasicAliasAnalysis.h:1.4 --- llvm/include/llvm/Analysis/BasicAliasAnalysis.h:1.3 Thu Aug 29 15:08:39 2002 +++ llvm/include/llvm/Analysis/BasicAliasAnalysis.h Wed Sep 25 17:00:18 2002 @@ -12,7 +12,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Pass.h" -struct BasicAliasAnalysis : public FunctionPass, public AliasAnalysis { +struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis { // Pass Implementation stuff. This isn't much of a pass. // From lattner at cs.uiuc.edu Wed Sep 25 17:27:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 17:27:01 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/PassManagerT.h Message-ID: <200209252226.RAA13717@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.28 -> 1.29 --- Log message: * Fix ugly bug in previous checkin where I reused the name 'i' one too many times * Print out immutable passes in the -debug-pass=Structure report. --- Diffs of the changes: Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.28 llvm/lib/VMCore/PassManagerT.h:1.29 --- llvm/lib/VMCore/PassManagerT.h:1.28 Wed Sep 25 16:59:11 2002 +++ llvm/lib/VMCore/PassManagerT.h Wed Sep 25 17:26:52 2002 @@ -173,15 +173,16 @@ CurrentAnalyses.clear(); // Add any immutable passes to the CurrentAnalyses set... - for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) - if (const PassInfo *PI = ImmutablePasses[i]->getPassInfo()) { - CurrentAnalyses[PI] = ImmutablePasses[i]; + for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { + ImmutablePass *IPass = ImmutablePasses[i]; + if (const PassInfo *PI = IPass->getPassInfo()) { + CurrentAnalyses[PI] = IPass; const std::vector &II = PI->getInterfacesImplemented(); for (unsigned i = 0, e = II.size(); i != e; ++i) - CurrentAnalyses[II[i]] = ImmutablePasses[i]; + CurrentAnalyses[II[i]] = IPass; } - + } // LastUserOf - This contains the inverted LastUseOfMap... std::map > LastUserOf; @@ -297,6 +298,10 @@ // dumpPassStructure - Implement the -debug-passes=PassStructure option virtual void dumpPassStructure(unsigned Offset = 0) { + // Print out the immutable passes... + for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) + ImmutablePasses[i]->dumpPassStructure(0); + std::cerr << std::string(Offset*2, ' ') << Traits::getPMName() << " Pass Manager\n"; for (typename std::vector::iterator From lattner at cs.uiuc.edu Wed Sep 25 17:28:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 17:28:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ValueNumbering.cpp Message-ID: <200209252227.RAA13729@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ValueNumbering.cpp updated: 1.2 -> 1.3 --- Log message: Convert BasicVN to be an ImmutablePass --- Diffs of the changes: Index: llvm/lib/Analysis/ValueNumbering.cpp diff -u llvm/lib/Analysis/ValueNumbering.cpp:1.2 llvm/lib/Analysis/ValueNumbering.cpp:1.3 --- llvm/lib/Analysis/ValueNumbering.cpp:1.2 Fri Aug 30 17:30:36 2002 +++ llvm/lib/Analysis/ValueNumbering.cpp Wed Sep 25 17:27:25 2002 @@ -38,18 +38,7 @@ /// lexically identical expressions. This does not require any ahead of time /// analysis, so it is a very fast default implementation. /// - struct BasicVN : public FunctionPass, public ValueNumbering { - - /// Pass Implementation stuff. This isn't much of a pass. - /// - bool runOnFunction(Function &) { return false; } - - /// getAnalysisUsage - Does not modify anything. - /// - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - + struct BasicVN : public ImmutablePass, public ValueNumbering { /// getEqualNumberNodes - Return nodes with the same value number as the /// specified Value. This fills in the argument vector with any equal /// values. From lattner at cs.uiuc.edu Wed Sep 25 17:28:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 17:28:03 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/BasicAliasAnalysis.h Message-ID: <200209252227.RAA13745@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: BasicAliasAnalysis.h updated: 1.4 -> 1.5 --- Log message: ImmutablePass's don't need a runOnFunction, nor do they need to explicitly say that they preserve all xforms --- Diffs of the changes: Index: llvm/include/llvm/Analysis/BasicAliasAnalysis.h diff -u llvm/include/llvm/Analysis/BasicAliasAnalysis.h:1.4 llvm/include/llvm/Analysis/BasicAliasAnalysis.h:1.5 --- llvm/include/llvm/Analysis/BasicAliasAnalysis.h:1.4 Wed Sep 25 17:00:18 2002 +++ llvm/include/llvm/Analysis/BasicAliasAnalysis.h Wed Sep 25 17:27:54 2002 @@ -13,17 +13,7 @@ #include "llvm/Pass.h" struct BasicAliasAnalysis : public ImmutablePass, public AliasAnalysis { - - // Pass Implementation stuff. This isn't much of a pass. - // - bool runOnFunction(Function &) { return false; } - - // getAnalysisUsage - Does not modify anything. - // - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - + // alias - This is the only method here that does anything interesting... // Result alias(const Value *V1, const Value *V2) const; From lattner at cs.uiuc.edu Wed Sep 25 18:47:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 18:47:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetData.cpp Message-ID: <200209252346.SAA17259@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetData.cpp updated: 1.22 -> 1.23 --- Log message: Convert TargetData to be an ImmutablePass --- Diffs of the changes: Index: llvm/lib/Target/TargetData.cpp diff -u llvm/lib/Target/TargetData.cpp:1.22 llvm/lib/Target/TargetData.cpp:1.23 --- llvm/lib/Target/TargetData.cpp:1.22 Tue Sep 10 20:20:05 2002 +++ llvm/lib/Target/TargetData.cpp Wed Sep 25 18:46:55 2002 @@ -14,6 +14,13 @@ #include "llvm/DerivedTypes.h" #include "llvm/Constants.h" +// Handle the Pass registration stuff neccesary to use TargetData's. +namespace { + // Register the default SparcV9 implementation... + RegisterPass X("targetdata", "Target Data Layout"); +} + + static inline void getTypeInfo(const Type *Ty, const TargetData *TD, uint64_t &Size, unsigned char &Alignment); From lattner at cs.uiuc.edu Wed Sep 25 18:47:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 18:47:03 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetData.h Message-ID: <200209252346.SAA17265@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetData.h updated: 1.9 -> 1.10 --- Log message: Convert TargetData to be an ImmutablePass --- Diffs of the changes: Index: llvm/include/llvm/Target/TargetData.h diff -u llvm/include/llvm/Target/TargetData.h:1.9 llvm/include/llvm/Target/TargetData.h:1.10 --- llvm/include/llvm/Target/TargetData.h:1.9 Mon Sep 23 19:08:01 2002 +++ llvm/include/llvm/Target/TargetData.h Wed Sep 25 18:46:56 2002 @@ -14,6 +14,7 @@ #define LLVM_TARGET_TARGETDATA_H #include "llvm/Annotation.h" +#include "llvm/Pass.h" #include "Support/DataTypes.h" #include class Value; @@ -21,7 +22,7 @@ class StructType; class StructLayout; -class TargetData { +class TargetData : public ImmutablePass { unsigned char ByteAlignment; // Defaults to 1 bytes unsigned char ShortAlignment; // Defaults to 2 bytes unsigned char IntAlignment; // Defaults to 4 bytes @@ -35,7 +36,7 @@ static Annotation *TypeAnFactory(AnnotationID, const Annotable *, void *); public: - TargetData(const std::string &TargetName, + TargetData(const std::string &TargetName = "SparcV9", unsigned char IntRegSize = 8, unsigned char PtrSize = 8, unsigned char PtrAl = 8, unsigned char DoubleAl = 8, From lattner at cs.uiuc.edu Wed Sep 25 18:48:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 18:48:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerAllocations.cpp Message-ID: <200209252347.SAA17288@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerAllocations.cpp updated: 1.31 -> 1.32 --- Log message: Change LowerAllocations pass to 'require' TargetData instead of it being passed in. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LowerAllocations.cpp diff -u llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.31 llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.32 --- llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.31 Tue Sep 10 17:38:47 2002 +++ llvm/lib/Transforms/Scalar/LowerAllocations.cpp Wed Sep 25 18:47:47 2002 @@ -20,40 +20,39 @@ namespace { -// LowerAllocations - Turn malloc and free instructions into %malloc and %free -// calls. -// -class LowerAllocations : public BasicBlockPass { - Function *MallocFunc; // Functions in the module we are processing - Function *FreeFunc; // Initialized by doInitialization - - const TargetData &DataLayout; -public: - LowerAllocations(const TargetData &TD) : DataLayout(TD) { - MallocFunc = FreeFunc = 0; - } - - // doPassInitialization - For the lower allocations pass, this ensures that a - // module contains a declaration for a malloc and a free function. - // - bool doInitialization(Module &M); - - // runOnBasicBlock - This method does the actual work of converting - // instructions over, assuming that the pass has already been initialized. - // - bool runOnBasicBlock(BasicBlock &BB); -}; + /// LowerAllocations - Turn malloc and free instructions into %malloc and + /// %free calls. + /// + class LowerAllocations : public BasicBlockPass { + Function *MallocFunc; // Functions in the module we are processing + Function *FreeFunc; // Initialized by doInitialization + public: + LowerAllocations() : MallocFunc(0), FreeFunc(0) {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + + /// doPassInitialization - For the lower allocations pass, this ensures that + /// a module contains a declaration for a malloc and a free function. + /// + bool doInitialization(Module &M); + + /// runOnBasicBlock - This method does the actual work of converting + /// instructions over, assuming that the pass has already been initialized. + /// + bool runOnBasicBlock(BasicBlock &BB); + }; + + RegisterOpt + X("lowerallocs", "Lower allocations from instructions to calls"); } // createLowerAllocationsPass - Interface to this file... -Pass *createLowerAllocationsPass(const TargetData &TD) { - return new LowerAllocations(TD); +Pass *createLowerAllocationsPass() { + return new LowerAllocations(); } -static RegisterOpt -X("lowerallocs", "Lower allocations from instructions to calls (TD)", - createLowerAllocationsPass); - // doInitialization - For the lower allocations pass, this ensures that a // module contains a declaration for a malloc and a free function. @@ -83,6 +82,7 @@ assert(MallocFunc && FreeFunc && "Pass not initialized!"); BasicBlock::InstListType &BBIL = BB.getInstList(); + TargetData &DataLayout = getAnalysis(); // Loop over all of the instructions, looking for malloc or free instructions for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) { From lattner at cs.uiuc.edu Wed Sep 25 18:48:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 18:48:03 2002 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200209252347.SAA17294@apoc.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.59 -> 1.60 --- Log message: Change LowerAllocations pass to 'require' TargetData instead of it being passed in. --- Diffs of the changes: Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.59 llvm/tools/llc/llc.cpp:1.60 --- llvm/tools/llc/llc.cpp:1.59 Thu Sep 19 11:06:28 2002 +++ llvm/tools/llc/llc.cpp Wed Sep 25 18:47:49 2002 @@ -220,7 +220,7 @@ // Replace malloc and free instructions with library calls. // Do this after tracing until lli implements these lib calls. // For now, it will emulate malloc and free internally. - Passes.add(createLowerAllocationsPass(Target.DataLayout)); + Passes.add(createLowerAllocationsPass()); // If LLVM dumping after transformations is requested, add it to the pipeline if (DumpAsm) From lattner at cs.uiuc.edu Wed Sep 25 18:49:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 18:49:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Scalar.h Message-ID: <200209252348.SAA17317@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: Scalar.h updated: 1.11 -> 1.12 --- Log message: Change LowerAllocations pass to 'require' TargetData instead of it being passed in. --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.11 llvm/include/llvm/Transforms/Scalar.h:1.12 --- llvm/include/llvm/Transforms/Scalar.h:1.11 Tue Sep 24 10:42:27 2002 +++ llvm/include/llvm/Transforms/Scalar.h Wed Sep 25 18:47:45 2002 @@ -9,7 +9,6 @@ #define LLVM_TRANSFORMS_SCALAR_H class Pass; -class TargetData; class GetElementPtrInst; class PassInfo; @@ -191,11 +190,9 @@ //===----------------------------------------------------------------------===// // These two passes convert malloc and free instructions to and from %malloc & -// %free function calls. The LowerAllocations transformation is a target -// dependant tranformation because it depends on the size of data types and -// alignment constraints. +// %free function calls. // -Pass *createLowerAllocationsPass(const TargetData &TD); +Pass *createLowerAllocationsPass(); Pass *createRaiseAllocationsPass(); From lattner at cs.uiuc.edu Wed Sep 25 19:18:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 19:18:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/SimpleStructMutation.cpp Message-ID: <200209260017.TAA18417@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: SimpleStructMutation.cpp updated: 1.18 -> 1.19 --- Log message: Converted SimpleStructMutation to take TargetData as a required pass. --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/SimpleStructMutation.cpp diff -u llvm/lib/Transforms/IPO/SimpleStructMutation.cpp:1.18 llvm/lib/Transforms/IPO/SimpleStructMutation.cpp:1.19 --- llvm/lib/Transforms/IPO/SimpleStructMutation.cpp:1.18 Thu Aug 8 14:01:22 2002 +++ llvm/lib/Transforms/IPO/SimpleStructMutation.cpp Wed Sep 25 19:17:21 2002 @@ -12,7 +12,6 @@ #include "llvm/Target/TargetData.h" #include "llvm/DerivedTypes.h" #include -#include using std::vector; using std::set; using std::pair; @@ -20,8 +19,6 @@ namespace { struct SimpleStructMutation : public MutateStructTypes { enum Transform { SwapElements, SortElements }; - const TargetData &TD; - SimpleStructMutation(const TargetData &td) : TD(td) {} virtual bool run(Module &M) = 0; @@ -29,6 +26,7 @@ // FindUsedTypes and FindUnsafePointerTypes analysis passes... // virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); AU.addRequired(); AU.addRequired(); MutateStructTypes::getAnalysisUsage(AU); @@ -39,8 +37,6 @@ }; struct SwapStructElements : public SimpleStructMutation { - SwapStructElements(const TargetData &TD) : SimpleStructMutation(TD) {} - virtual bool run(Module &M) { setTransforms(getTransforms(M, SwapElements)); bool Changed = MutateStructTypes::run(M); @@ -50,8 +46,6 @@ }; struct SortStructElements : public SimpleStructMutation { - SortStructElements(const TargetData &TD) : SimpleStructMutation(TD) {} - virtual bool run(Module &M) { setTransforms(getTransforms(M, SortElements)); bool Changed = MutateStructTypes::run(M); @@ -59,8 +53,15 @@ return Changed; } }; + + RegisterOpt X("swapstructs", + "Swap structure types around"); + RegisterOpt Y("sortstructs", + "Sort structure elements by size"); } // end anonymous namespace +Pass *createSwapElementsPass() { return new SwapStructElements(); } +Pass *createSortElementsPass() { return new SortStructElements(); } // PruneTypes - Given a type Ty, make sure that neither it, or one of its @@ -168,6 +169,7 @@ // Build up a set of structure types that we are going to modify, and // information describing how to modify them. std::map > Transforms; + TargetData &TD = getAnalysis(); for (set::iterator I = TypesToModify.begin(), E = TypesToModify.end(); I != E; ++I) { @@ -178,21 +180,4 @@ } return Transforms; -} - - -Pass *createSwapElementsPass(const TargetData &TD) { - return new SwapStructElements(TD); -} -Pass *createSortElementsPass(const TargetData &TD) { - return new SortStructElements(TD); -} - -namespace { - RegisterOpt X("swapstructs", - "Swap structure types around", - createSwapElementsPass); - RegisterOpt Y("sortstructs", - "Sort structure elements by size", - createSortElementsPass); } From lattner at cs.uiuc.edu Wed Sep 25 19:18:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Sep 25 19:18:03 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/IPO.h Message-ID: <200209260017.TAA18422@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.12 -> 1.13 --- Log message: Converted SimpleStructMutation to take TargetData as a required pass. --- Diffs of the changes: Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.12 llvm/include/llvm/Transforms/IPO.h:1.13 --- llvm/include/llvm/Transforms/IPO.h:1.12 Wed Jul 24 12:10:58 2002 +++ llvm/include/llvm/Transforms/IPO.h Wed Sep 25 19:17:18 2002 @@ -9,7 +9,6 @@ #define LLVM_TRANSFORMS_IPO_H class Pass; -class TargetData; //===----------------------------------------------------------------------===// // createConstantMergePass - This function returns a new pass that merges @@ -69,7 +68,7 @@ // These passes are wrappers that can do a few simple structure mutation // transformations. // -Pass *createSwapElementsPass(const TargetData &); -Pass *createSortElementsPass(const TargetData &); +Pass *createSwapElementsPass(); +Pass *createSortElementsPass(); #endif From lattner at cs.uiuc.edu Thu Sep 26 00:04:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 00:04:01 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/BasicBlock.cpp Message-ID: <200209260503.AAA21647@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: BasicBlock.cpp updated: 1.25 -> 1.26 --- Log message: - Add new ctor to BasicBlock to allow insertion before any BB, not just at the end of the function. --- Diffs of the changes: Index: llvm/lib/VMCore/BasicBlock.cpp diff -u llvm/lib/VMCore/BasicBlock.cpp:1.25 llvm/lib/VMCore/BasicBlock.cpp:1.26 --- llvm/lib/VMCore/BasicBlock.cpp:1.25 Sun Sep 8 13:59:34 2002 +++ llvm/lib/VMCore/BasicBlock.cpp Thu Sep 26 00:03:22 2002 @@ -67,6 +67,26 @@ Parent->getBasicBlockList().push_back(this); } +/// BasicBlock ctor - If the InsertBefore parameter is specified, the basic +/// block is automatically inserted right before the specified block. +/// +BasicBlock::BasicBlock(const std::string &Name, BasicBlock *InsertBefore) + : Value(Type::LabelTy, Value::BasicBlockVal, Name) { + // Initialize the instlist... + InstList.setItemParent(this); + + // Make sure that we get added to a function + LeakDetector::addGarbageObject(this); + + if (InsertBefore) { + assert(InsertBefore->getParent() && + "Cannot insert block before another block that is not embedded into" + " a function yet!"); + InsertBefore->getParent()->getBasicBlockList().insert(InsertBefore, this); + } +} + + BasicBlock::~BasicBlock() { dropAllReferences(); InstList.clear(); From lattner at cs.uiuc.edu Thu Sep 26 00:04:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 00:04:05 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/BasicBlock.h Message-ID: <200209260503.AAA21653@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: BasicBlock.h updated: 1.27 -> 1.28 --- Log message: - Add new ctor to BasicBlock to allow insertion before any BB, not just at the end of the function. --- Diffs of the changes: Index: llvm/include/llvm/BasicBlock.h diff -u llvm/include/llvm/BasicBlock.h:1.27 llvm/include/llvm/BasicBlock.h:1.28 --- llvm/include/llvm/BasicBlock.h:1.27 Fri Sep 6 16:31:57 2002 +++ llvm/include/llvm/BasicBlock.h Thu Sep 26 00:03:17 2002 @@ -63,6 +63,10 @@ /// is automatically inserted at the end of the function. /// BasicBlock(const std::string &Name = "", Function *Parent = 0); + + /// BasicBlock ctor - If the InsertBefore parameter is specified, the basic + /// block is automatically inserted right before the specified block. + BasicBlock(const std::string &Name, BasicBlock *InsertBefore); ~BasicBlock(); // Specialize setName to take care of symbol table majik From lattner at cs.uiuc.edu Thu Sep 26 00:33:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 00:33:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200209260532.AAA22371@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.21 -> 1.22 --- Log message: - Add new methods to LoopInfo: getLoopPreheader, addBasicBlockToLoop. These allow extra information to be easily gathered, and loopinfo to be updated. --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.21 llvm/lib/Analysis/LoopInfo.cpp:1.22 --- llvm/lib/Analysis/LoopInfo.cpp:1.21 Mon Aug 26 11:43:42 2002 +++ llvm/lib/Analysis/LoopInfo.cpp Thu Sep 26 00:32:50 2002 @@ -81,7 +81,7 @@ } Loop *LoopInfo::ConsiderForLoop(BasicBlock *BB, const DominatorSet &DS) { - if (BBMap.find(BB) != BBMap.end()) return 0; // Havn't processed this node? + if (BBMap.find(BB) != BBMap.end()) return 0; // Haven't processed this node? std::vector TodoStack; @@ -127,4 +127,54 @@ } return L; +} + +/// 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 outside of the loop. If this is the case, the block branching to the +/// header of the loop is the preheader node. The "preheaders" pass can be +/// "Required" to ensure that there is always a preheader node for every loop. +/// +/// This method returns null if there is no preheader for the loop (either +/// because the loop is dead or because multiple blocks branch to the header +/// node of this loop). +/// +BasicBlock *Loop::getLoopPreheader() const { + // Keep track of nodes outside the loop branching to the header... + BasicBlock *Out = 0; + + // Loop over the predecessors of the header node... + BasicBlock *Header = getHeader(); + for (pred_iterator PI = pred_begin(Header), PE = pred_end(Header); + PI != PE; ++PI) + if (!contains(*PI)) { // If the block is not in the loop... + if (Out) return 0; // Multiple predecessors outside the loop + Out = *PI; + } + + // If there is exactly one preheader, return it. If there was zero, then Out + // is still null. + return Out; +} + +/// addBasicBlockToLoop - This function is used by other analyses to update loop +/// information. NewBB is set to be a new member of the current loop. Because +/// of this, it is added as a member of all parent loops, and is added to the +/// specified LoopInfo object as being in the current basic block. It is not +/// valid to replace the loop header with this method. +/// +void Loop::addBasicBlockToLoop(BasicBlock *NewBB, LoopInfo &LI) { + assert(LI[getHeader()] == this && "Incorrect LI specified for this loop!"); + assert(NewBB && "Cannot add a null basic block to the loop!"); + assert(LI[NewBB] == 0 && "BasicBlock already in the loop!"); + + // Add the loop mapping to the LoopInfo object... + LI.BBMap[NewBB] = this; + + // Add the basic block to this loop and all parent loops... + Loop *L = this; + while (L) { + L->Blocks.push_back(NewBB); + L = L->getParentLoop(); + } } From lattner at cs.uiuc.edu Thu Sep 26 00:33:06 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 00:33:06 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/LoopInfo.h Message-ID: <200209260533.AAA22377@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: LoopInfo.h updated: 1.17 -> 1.18 --- Log message: - Add new methods to LoopInfo: getLoopPreheader, addBasicBlockToLoop. These allow extra information to be easily gathered, and loopinfo to be updated. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/LoopInfo.h diff -u llvm/include/llvm/Analysis/LoopInfo.h:1.17 llvm/include/llvm/Analysis/LoopInfo.h:1.18 --- llvm/include/llvm/Analysis/LoopInfo.h:1.17 Wed Sep 25 14:10:06 2002 +++ llvm/include/llvm/Analysis/LoopInfo.h Thu Sep 26 00:32:43 2002 @@ -17,9 +17,9 @@ class LoopInfo; //===----------------------------------------------------------------------===// -// Loop class - Instances of this class are used to represent loops that are -// detected in the flow graph -// +/// Loop class - Instances of this class are used to represent loops that are +/// detected in the flow graph +/// class Loop { Loop *ParentLoop; std::vector Blocks; // First entry is the header node @@ -32,18 +32,40 @@ inline unsigned getLoopDepth() const { return LoopDepth; } inline BasicBlock *getHeader() const { return Blocks.front(); } + inline Loop *getParentLoop() const { return ParentLoop; } - // contains - Return true of the specified basic block is in this loop + /// contains - Return true of the specified basic block is in this loop bool contains(const BasicBlock *BB) const; - // getSubLoops - Return the loops contained entirely within this loop + /// getSubLoops - Return the loops contained entirely within this loop + /// inline const std::vector &getSubLoops() const { return SubLoops; } inline const std::vector &getBlocks() const { return Blocks; } - // isLoopExit - True if terminator in the block can branch to another block - // that is outside of the current loop. + /// isLoopExit - True if terminator in the block can branch to another block + /// that is outside of the current loop. bool isLoopExit(BasicBlock *BB) 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 outside of the loop. If this is the case, the block branching to the + /// header of the loop is the preheader node. The "preheaders" pass can be + /// "Required" to ensure that there is always a preheader node for every loop. + /// + /// This method returns null if there is no preheader for the loop (either + /// because the loop is dead or because multiple blocks branch to the header + /// node of this loop). + /// + BasicBlock *getLoopPreheader() const; + + /// addBasicBlockToLoop - This function is used by other analyses to update + /// loop information. NewBB is set to be a new member of the current loop. + /// Because of this, it is added as a member of all parent loops, and is added + /// to the specified LoopInfo object as being in the current basic block. It + /// is not valid to replace the loop header with this method. + /// + void addBasicBlockToLoop(BasicBlock *NewBB, LoopInfo &LI); + void print(std::ostream &O) const; private: friend class LoopInfo; @@ -63,31 +85,35 @@ //===----------------------------------------------------------------------===// -// LoopInfo - This class builds and contains all of the top level loop -// structures in the specified function. -// +/// LoopInfo - This class builds and contains all of the top level loop +/// structures in the specified function. +/// class LoopInfo : public FunctionPass { // BBMap - Mapping of basic blocks to the inner most loop they occur in std::map BBMap; std::vector TopLevelLoops; + friend class Loop; public: - // LoopInfo ctor - Calculate the natural loop information for a CFG ~LoopInfo() { releaseMemory(); } const std::vector &getTopLevelLoops() const { return TopLevelLoops; } - // getLoopFor - Return the inner most loop that BB lives in. If a basic block - // is in no loop (for example the entry node), null is returned. - // + /// getLoopFor - Return the inner most loop that BB lives in. If a basic + /// block is in no loop (for example the entry node), null is returned. + /// const Loop *getLoopFor(const BasicBlock *BB) const { std::map::const_iterator I=BBMap.find((BasicBlock*)BB); return I != BBMap.end() ? I->second : 0; } + + /// operator[] - same as getLoopFor... + /// inline const Loop *operator[](const BasicBlock *BB) const { return getLoopFor(BB); } - // getLoopDepth - Return the loop nesting level of the specified block... + /// getLoopDepth - Return the loop nesting level of the specified block... + /// unsigned getLoopDepth(const BasicBlock *BB) const { const Loop *L = getLoopFor(BB); return L ? L->getLoopDepth() : 0; @@ -102,14 +128,15 @@ bool isLoopEnd(BasicBlock *BB) const; #endif - // runOnFunction - Pass framework implementation + /// runOnFunction - Calculate the natural loop information. + /// virtual bool runOnFunction(Function &F); virtual void releaseMemory(); void print(std::ostream &O) const; - // getAnalysisUsage - Provide loop info, require dominator set - // + /// getAnalysisUsage - Requires dominator sets + /// virtual void getAnalysisUsage(AnalysisUsage &AU) const; static void stub(); // Noop @@ -119,7 +146,7 @@ }; -// Make sure that any clients of this file link in PostDominators.cpp +// Make sure that any clients of this file link in LoopInfo.cpp static IncludeFile LOOP_INFO_INCLUDE_FILE((void*)&LoopInfo::stub); From lattner at cs.uiuc.edu Thu Sep 26 00:43:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 00:43:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200209260542.AAA22833@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.23 -> 1.24 --- Log message: Add a new "DominatorSet::addDominator" method to allow updates --- Diffs of the changes: Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.23 llvm/include/llvm/Analysis/Dominators.h:1.24 --- llvm/include/llvm/Analysis/Dominators.h:1.23 Thu Sep 5 21:16:27 2002 +++ llvm/include/llvm/Analysis/Dominators.h Thu Sep 26 00:42:47 2002 @@ -107,6 +107,15 @@ assert(find(BB) == end() && "Block already in DominatorSet!"); Doms.insert(std::make_pair(BB, Dominators)); } + + // addDominator - If a new block is inserted into the CFG, then method may be + // called to notify the blocks it dominates that it is in their set. + // + void addDominator(BasicBlock *BB, BasicBlock *NewDominator) { + iterator I = find(BB); + assert(I != end() && "BB is not in DominatorSet!"); + I->second.insert(NewDominator); + } }; From lattner at cs.uiuc.edu Thu Sep 26 11:15:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:15:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200209261614.LAA27114@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.24 -> 1.25 --- Log message: - Add methods to ImmediateDominators & DominatorTree to allow updates - Make DominatorTree::Node not inherit from std::vector --- Diffs of the changes: Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.24 llvm/include/llvm/Analysis/Dominators.h:1.25 --- llvm/include/llvm/Analysis/Dominators.h:1.24 Thu Sep 26 00:42:47 2002 +++ llvm/include/llvm/Analysis/Dominators.h Thu Sep 26 11:14:37 2002 @@ -183,6 +183,14 @@ IDoms[BB] = IDom; } + /// setImmediateDominator - Update the immediate dominator information to + /// change the current immediate dominator for the specified block to another + /// block. This method requires that BB already have an IDom, otherwise just + /// use addNewBlock. + void setImmediateDominator(BasicBlock *BB, BasicBlock *NewIDom) { + assert(IDoms.find(BB) != IDoms.end() && "BB doesn't have idom yet!"); + IDoms[BB] = NewIDom; + } // print - Convert to human readable form virtual void print(std::ostream &OS) const; @@ -224,16 +232,25 @@ void reset(); typedef std::map NodeMapType; public: - class Node2 : public std::vector { + class Node2 { friend class DominatorTree; friend class PostDominatorTree; friend class DominatorTreeBase; BasicBlock *TheNode; Node2 *IDom; + std::vector Children; public: + typedef std::vector::iterator iterator; + typedef std::vector::const_iterator const_iterator; + + iterator begin() { return Children.begin(); } + iterator end() { return Children.end(); } + const_iterator begin() const { return Children.begin(); } + const_iterator end() const { return Children.end(); } + inline BasicBlock *getNode() const { return TheNode; } inline Node2 *getIDom() const { return IDom; } - inline const std::vector &getChildren() const { return *this; } + inline const std::vector &getChildren() const { return Children; } // dominates - Returns true iff this dominates N. Note that this is not a // constant time operation! @@ -247,7 +264,9 @@ private: inline Node2(BasicBlock *node, Node *iDom) : TheNode(node), IDom(iDom) {} - inline Node2 *addChild(Node *C) { push_back(C); return C; } + inline Node2 *addChild(Node *C) { Children.push_back(C); return C; } + + void setIDom(Node2 *NewIDom); }; public: @@ -268,7 +287,7 @@ return getNode(BB); } - // API to update (Post)DominatorTree information based on modifications to + //===--------------------------------------------------------------------===// // API to update (Post)DominatorTree information based on modifications to // the CFG... /// createNewNode - Add a new node to the dominator tree information. This @@ -280,6 +299,14 @@ Node *New = Nodes[BB] = new Node(BB, IDomNode); if (IDomNode) IDomNode->addChild(New); return New; + } + + /// changeImmediateDominator - This method is used to update the dominator + /// tree information when a node's immediate dominator changes. + /// + void changeImmediateDominator(Node *Node, Node *NewIDom) { + assert(Node && NewIDom && "Cannot change null node pointers!"); + Node->setIDom(NewIDom); } /// print - Convert to human readable form From lattner at cs.uiuc.edu Thu Sep 26 11:15:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:15:04 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200209261614.LAA27120@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.38 -> 1.39 --- Log message: - Add methods to ImmediateDominators & DominatorTree to allow updates - Make DominatorTree::Node not inherit from std::vector --- Diffs of the changes: Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.38 llvm/lib/VMCore/Dominators.cpp:1.39 --- llvm/lib/VMCore/Dominators.cpp:1.38 Thu Aug 22 15:39:29 2002 +++ llvm/lib/VMCore/Dominators.cpp Thu Sep 26 11:14:41 2002 @@ -186,6 +186,23 @@ Nodes.clear(); } +void DominatorTreeBase::Node2::setIDom(Node2 *NewIDom) { + assert(IDom && "No immediate dominator?"); + if (IDom != NewIDom) { + std::vector::iterator I = + std::find(IDom->Children.begin(), IDom->Children.end(), this); + assert(I != IDom->Children.end() && + "Not in immediate dominator children set!"); + // I am no longer your child... + IDom->Children.erase(I); + + // Switch to new dominator + IDom = NewIDom; + IDom->Children.push_back(this); + } +} + + void DominatorTree::calculate(const DominatorSet &DS) { Nodes[Root] = new Node(Root, 0); // Add a node for the root... From lattner at cs.uiuc.edu Thu Sep 26 11:16:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:16:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/LoopInfo.h Message-ID: <200209261615.LAA27137@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: LoopInfo.h updated: 1.18 -> 1.19 --- Log message: - Fix bug in LoopInfo causing ParentLoop to be garbage --- Diffs of the changes: Index: llvm/include/llvm/Analysis/LoopInfo.h diff -u llvm/include/llvm/Analysis/LoopInfo.h:1.18 llvm/include/llvm/Analysis/LoopInfo.h:1.19 --- llvm/include/llvm/Analysis/LoopInfo.h:1.18 Thu Sep 26 00:32:43 2002 +++ llvm/include/llvm/Analysis/LoopInfo.h Thu Sep 26 11:15:19 2002 @@ -69,7 +69,9 @@ void print(std::ostream &O) const; private: friend class LoopInfo; - inline Loop(BasicBlock *BB) { Blocks.push_back(BB); LoopDepth = 0; } + inline Loop(BasicBlock *BB) : ParentLoop(0) { + Blocks.push_back(BB); LoopDepth = 0; + } ~Loop() { for (unsigned i = 0, e = SubLoops.size(); i != e; ++i) delete SubLoops[i]; From lattner at cs.uiuc.edu Thu Sep 26 11:16:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:16:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200209261615.LAA27150@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.22 -> 1.23 --- Log message: Fix printing of loop information --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.22 llvm/lib/Analysis/LoopInfo.cpp:1.23 --- llvm/lib/Analysis/LoopInfo.cpp:1.22 Thu Sep 26 00:32:50 2002 +++ llvm/lib/Analysis/LoopInfo.cpp Thu Sep 26 11:15:54 2002 @@ -76,8 +76,8 @@ } void LoopInfo::print(std::ostream &OS) const { - std::copy(getTopLevelLoops().begin(), getTopLevelLoops().end(), - std::ostream_iterator(OS, "\n")); + for (unsigned i = 0; i < TopLevelLoops.size(); ++i) + TopLevelLoops[i]->print(OS); } Loop *LoopInfo::ConsiderForLoop(BasicBlock *BB, const DominatorSet &DS) { From lattner at cs.uiuc.edu Thu Sep 26 11:18:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:18:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopPreheaders.cpp Message-ID: <200209261617.LAA27169@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopPreheaders.cpp added (r1.1) --- Log message: Checkin new loop-preheader insertion pass. --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Sep 26 11:18:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:18:03 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Scalar.h Message-ID: <200209261617.LAA27175@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: Scalar.h updated: 1.12 -> 1.13 --- Log message: Checkin new loop-preheader insertion pass. --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.12 llvm/include/llvm/Transforms/Scalar.h:1.13 --- llvm/include/llvm/Transforms/Scalar.h:1.12 Wed Sep 25 18:47:45 2002 +++ llvm/include/llvm/Transforms/Scalar.h Thu Sep 26 11:17:33 2002 @@ -188,6 +188,19 @@ Pass *createBreakCriticalEdgesPass(); extern const PassInfo *BreakCriticalEdgesID; + +//===----------------------------------------------------------------------===// +// +// LoopPreheaders pass - Insert Pre-header blocks into the CFG for every +// function in the module. This pass updates dominator information, loop +// information, and does not add critical edges to the CFG. +// +// AU.addRequiredID(LoopPreheadersID); +// +Pass *createLoopPreheaderInsertionPass(); +extern const PassInfo *LoopPreheadersID; + + //===----------------------------------------------------------------------===// // These two passes convert malloc and free instructions to and from %malloc & // %free function calls. From lattner at cs.uiuc.edu Thu Sep 26 11:19:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:19:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Message-ID: <200209261618.LAA27189@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: BreakCriticalEdges.cpp updated: 1.3 -> 1.4 --- Log message: - Cleanup break-crit-edges pass by making SplitCriticalEdge a member method. - break-crit-edges pass does not invalidate loop-preheader pass. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp diff -u llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.3 llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.4 --- llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp:1.3 Tue Sep 24 10:51:56 2002 +++ llvm/lib/Transforms/Scalar/BreakCriticalEdges.cpp Thu Sep 26 11:18:51 2002 @@ -26,7 +26,10 @@ AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); + AU.addPreservedID(LoopPreheadersID); // No preheaders deleted. } + private: + void SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum); }; RegisterOpt X("break-crit-edges", @@ -59,7 +62,7 @@ // will update DominatorSet, ImmediateDominator and DominatorTree information if // it is available, thus calling this pass will not invalidate either of them. // -static void SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P) { +void BreakCriticalEdges::SplitCriticalEdge(TerminatorInst *TI,unsigned SuccNum){ assert(isCriticalEdge(TI, SuccNum) && "Cannot break a critical edge, if it isn't a critical edge"); BasicBlock *TIBB = TI->getParent(); @@ -87,36 +90,34 @@ PN->replaceUsesOfWith(TIBB, NewBB); } - // Now if we have a pass object, update analysis information. Currently we - // update DominatorSet and DominatorTree information if it's available. + // Now update analysis information. These are the analyses that we are + // currently capable of updating... // - if (P) { - // Should we update DominatorSet information? - 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); - DomSet.insert(NewBB); // A block always dominates itself. - DS->addBasicBlock(NewBB, DomSet); - } - // Should we update ImmdediateDominator information? - 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 DominatorSet information? + if (DominatorSet *DS = 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); + DomSet.insert(NewBB); // A block always dominates itself. + DS->addBasicBlock(NewBB, DomSet); + } - // Should we update DominatorTree information? - if (DominatorTree *DT = P->getAnalysisToUpdate()) { - DominatorTree::Node *TINode = DT->getNode(TIBB); - - // 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); - } + // Should we update ImmdediateDominator information? + if (ImmediateDominators *ID = 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()) { + DominatorTree::Node *TINode = DT->getNode(TIBB); + + // 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); } } @@ -130,7 +131,7 @@ if (TI->getNumSuccessors() > 1) for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) if (isCriticalEdge(TI, i)) { - SplitCriticalEdge(TI, i, this); + SplitCriticalEdge(TI, i); ++NumBroken; Changed = true; } From lattner at cs.uiuc.edu Thu Sep 26 11:20:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:20:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200209261619.LAA27201@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.12 -> 1.13 --- Log message: Loop invariant code motion now depends on the LoopPreheader pass. Dead code has not yet been removed. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.12 llvm/lib/Transforms/Scalar/LICM.cpp:1.13 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.12 Tue Sep 10 17:38:47 2002 +++ llvm/lib/Transforms/Scalar/LICM.cpp Thu Sep 26 11:19:31 2002 @@ -42,6 +42,7 @@ // This transformation requires natural loop information... virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.preservesCFG(); + AU.addRequiredID(LoopPreheadersID); AU.addRequired(); AU.addRequired(); } @@ -104,11 +105,7 @@ } void visitShiftInst(ShiftInst &I) { visitBinaryOperator((Instruction&)I); } - void visitLoadInst(LoadInst &LI) { - if (isLoopInvariant(LI.getOperand(0)) && - !pointerInvalidatedByLoop(LI.getOperand(0))) - hoist(LI); - } + void visitLoadInst(LoadInst &LI); void visitGetElementPtrInst(GetElementPtrInst &GEPI) { Instruction &I = (Instruction&)GEPI; @@ -274,6 +271,14 @@ } Changed = true; +} + + +void LICM::visitLoadInst(LoadInst &LI) { + if (isLoopInvariant(LI.getOperand(0)) && + !pointerInvalidatedByLoop(LI.getOperand(0))) + hoist(LI); + } // pointerInvalidatedByLoop - Return true if the body of this loop may store From lattner at cs.uiuc.edu Thu Sep 26 11:38:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:38:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopPreheaders.cpp Message-ID: <200209261637.LAA28198@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopPreheaders.cpp updated: 1.1 -> 1.2 --- Log message: Change pass name to something sane --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LoopPreheaders.cpp diff -u llvm/lib/Transforms/Scalar/LoopPreheaders.cpp:1.1 llvm/lib/Transforms/Scalar/LoopPreheaders.cpp:1.2 --- llvm/lib/Transforms/Scalar/LoopPreheaders.cpp:1.1 Thu Sep 26 11:17:31 2002 +++ llvm/lib/Transforms/Scalar/LoopPreheaders.cpp Thu Sep 26 11:37:37 2002 @@ -36,8 +36,7 @@ void InsertPreheaderForLoop(Loop *L); }; - RegisterOpt X("preheaders", - "Insert a pre-header node for every loop in the CFG"); + RegisterOpt X("preheaders", "Natural loop pre-header insertion"); } // Publically exposed interface to pass... From lattner at cs.uiuc.edu Thu Sep 26 11:38:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:38:04 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200209261638.LAA28210@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.13 -> 1.14 --- Log message: Clean up LICM significantly now that it is guaranteed to have loop preheaders --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.13 llvm/lib/Transforms/Scalar/LICM.cpp:1.14 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.13 Thu Sep 26 11:19:31 2002 +++ llvm/lib/Transforms/Scalar/LICM.cpp Thu Sep 26 11:38:03 2002 @@ -2,17 +2,6 @@ // // This pass is a simple loop invariant code motion pass. // -// Note that this pass does NOT require pre-headers to exist on loops in the -// CFG, but if there is not distinct preheader for a loop, the hoisted code will -// be *DUPLICATED* in every basic block, outside of the loop, that preceeds the -// loop header. Additionally, any use of one of these hoisted expressions -// cannot be loop invariant itself, because the expression hoisted gets a PHI -// node that is loop variant. -// -// For these reasons, and many more, it makes sense to run a pass before this -// that ensures that there are preheaders on all loops. That said, we don't -// REQUIRE it. :) -// //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" @@ -20,22 +9,17 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/iOperators.h" -#include "llvm/iPHINode.h" #include "llvm/iMemory.h" #include "llvm/Support/InstVisitor.h" -#include "llvm/Support/CFG.h" #include "Support/STLExtras.h" #include "Support/StatisticReporter.h" #include using std::string; -static Statistic<> NumHoistedNPH("licm\t\t- Number of insts hoisted to multiple" - " loop preds (bad, no loop pre-header)"); -static Statistic<> NumHoistedPH("licm\t\t- Number of insts hoisted to a loop " - "pre-header"); -static Statistic<> NumHoistedLoads("licm\t\t- Number of load insts hoisted"); - namespace { + Statistic<>NumHoisted("licm\t\t- Number of instructions hoisted out of loop"); + Statistic<> NumHoistedLoads("licm\t\t- Number of load insts hoisted"); + struct LICM : public FunctionPass, public InstVisitor { virtual bool runOnFunction(Function &F); @@ -48,11 +32,6 @@ } private: - // List of predecessor blocks for the current loop - These blocks are where - // we hoist loop invariants to for the current loop. - // - std::vector LoopPreds, LoopBackEdges; - Loop *CurLoop; // The current loop we are working on... bool Changed; // Set to true when we change anything. AliasAnalysis *AA; // Currently AliasAnalysis information @@ -143,32 +122,6 @@ bind_obj(this, &LICM::visitLoop)); CurLoop = L; - // Calculate the set of predecessors for this loop. The predecessors for this - // loop are equal to the predecessors for the header node of the loop that are - // not themselves in the loop. - // - BasicBlock *Header = L->getHeader(); - - // Calculate the sets of predecessors and backedges of the loop... - LoopBackEdges.insert(LoopBackEdges.end(),pred_begin(Header),pred_end(Header)); - - std::vector::iterator LPI = - std::partition(LoopBackEdges.begin(), LoopBackEdges.end(), - bind_obj(CurLoop, &Loop::contains)); - - // Move all predecessors to the LoopPreds vector... - LoopPreds.insert(LoopPreds.end(), LPI, LoopBackEdges.end()); - - // Remove predecessors from backedges list... - LoopBackEdges.erase(LPI, LoopBackEdges.end()); - - - // The only way that there could be no predecessors to a loop is if the loop - // is not reachable. Since we don't care about optimizing dead loops, - // summarily ignore them. - // - if (LoopPreds.empty()) return; - // We want to visit all of the instructions in this loop... that are not parts // of our subloops (they have already had their invariants hoisted out of // their loop, into this loop, so there is no need to process the BODIES of @@ -188,8 +141,6 @@ // Clear out loops state information for the next iteration CurLoop = 0; - LoopPreds.clear(); - LoopBackEdges.clear(); } void LICM::visitBasicBlock(BasicBlock *BB) { @@ -220,55 +171,19 @@ // The common case is that we have a pre-header. Generate special case code // that is faster if that is the case. // - if (LoopPreds.size() == 1) { - BasicBlock *Pred = LoopPreds[0]; - - // Create a new copy of the instruction, for insertion into Pred. - Instruction *New = Inst.clone(); - New->setName(InstName); - - // Insert the new node in Pred, before the terminator. - Pred->getInstList().insert(--Pred->end(), New); - - // Kill the old instruction... - Inst.replaceAllUsesWith(New); - ++NumHoistedPH; - - } else { - // No loop pre-header, insert a PHI node into header to capture all of the - // incoming versions of the value. - // - PHINode *LoopVal = new PHINode(Inst.getType(), InstName+".phi", - Header->begin()); - - // Insert cloned versions of the instruction into all of the loop preds. - for (unsigned i = 0, e = LoopPreds.size(); i != e; ++i) { - BasicBlock *Pred = LoopPreds[i]; - - // Create a new copy of the instruction, for insertion into Pred. - Instruction *New = Inst.clone(); - New->setName(InstName); + BasicBlock *Preheader = CurLoop->getLoopPreheader(); + assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!"); - // Insert the new node in Pred, before the terminator. - Pred->getInstList().insert(--Pred->end(), New); + // Create a new copy of the instruction, for insertion into Preheader. + Instruction *New = Inst.clone(); + New->setName(InstName); - // Add the incoming value to the PHI node. - LoopVal->addIncoming(New, Pred); - } - - // Add incoming values to the PHI node for all backedges in the loop... - for (unsigned i = 0, e = LoopBackEdges.size(); i != e; ++i) - LoopVal->addIncoming(LoopVal, LoopBackEdges[i]); - - // Replace all uses of the old version of the instruction in the loop with - // the new version that is out of the loop. We know that this is ok, - // because the new definition is in the loop header, which dominates the - // entire loop body. The old definition was defined _inside_ of the loop, - // so the scope cannot extend outside of the loop, so we're ok. - // - Inst.replaceAllUsesWith(LoopVal); - ++NumHoistedNPH; - } + // Insert the new node in Preheader, before the terminator. + Preheader->getInstList().insert(--Preheader->end(), New); + + // Kill the old instruction... + Inst.replaceAllUsesWith(New); + ++NumHoisted; Changed = true; } From lattner at cs.uiuc.edu Thu Sep 26 11:52:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 11:52:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200209261652.LAA01073@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.14 -> 1.15 --- Log message: Improve comments, doxygenize more --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.14 llvm/lib/Transforms/Scalar/LICM.cpp:1.15 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.14 Thu Sep 26 11:38:03 2002 +++ llvm/lib/Transforms/Scalar/LICM.cpp Thu Sep 26 11:52:07 2002 @@ -23,7 +23,9 @@ struct LICM : public FunctionPass, public InstVisitor { virtual bool runOnFunction(Function &F); - // This transformation requires natural loop information... + /// This transformation requires natural loop information & requires that + /// loop preheaders be inserted into the CFG... + /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.preservesCFG(); AU.addRequiredID(LoopPreheadersID); @@ -36,13 +38,14 @@ bool Changed; // Set to true when we change anything. AliasAnalysis *AA; // Currently AliasAnalysis information - // visitLoop - Hoist expressions out of the specified loop... + /// visitLoop - Hoist expressions out of the specified loop... + /// void visitLoop(Loop *L); - // notInCurrentLoop - Little predicate that returns true if the specified - // basic block is in a subloop of the current one, not the current one - // itself. - // + /// notInCurrentLoop - Little predicate that returns true if the specified + /// basic block is in a subloop of the current one, not the current one + /// itself. + /// bool notInCurrentLoop(BasicBlock *BB) { for (unsigned i = 0, e = CurLoop->getSubLoops().size(); i != e; ++i) if (CurLoop->getSubLoops()[i]->contains(BB)) @@ -50,29 +53,31 @@ return false; } - // hoist - When an instruction is found to only use loop invariant operands - // that is safe to hoist, this instruction is called to do the dirty work. - // + /// hoist - When an instruction is found to only use loop invariant operands + /// that is safe to hoist, this instruction is called to do the dirty work. + /// void hoist(Instruction &I); - // pointerInvalidatedByLoop - Return true if the body of this loop may store - // into the memory location pointed to by V. - // + /// pointerInvalidatedByLoop - Return true if the body of this loop may + /// store into the memory location pointed to by V. + /// bool pointerInvalidatedByLoop(Value *V); - // isLoopInvariant - Return true if the specified value is loop invariant + /// isLoopInvariant - Return true if the specified value is loop invariant + /// inline bool isLoopInvariant(Value *V) { if (Instruction *I = dyn_cast(V)) return !CurLoop->contains(I->getParent()); return true; // All non-instructions are loop invariant } - // visitBasicBlock - Run LICM on a particular block. + /// visitBasicBlock - Run LICM on a particular block. + /// void visitBasicBlock(BasicBlock *BB); - // Instruction visitation handlers... these basically control whether or not - // the specified instruction types are hoisted. - // + /// Instruction visitation handlers... these basically control whether or + /// not the specified instruction types are hoisted. + /// friend class InstVisitor; void visitBinaryOperator(Instruction &I) { if (isLoopInvariant(I.getOperand(0)) && isLoopInvariant(I.getOperand(1))) @@ -99,6 +104,9 @@ Pass *createLICMPass() { return new LICM(); } +/// runOnFunction - For LICM, this simply traverses the loop structure of the +/// function, hoisting expressions out of loops if possible. +/// bool LICM::runOnFunction(Function &) { // get our loop information... const std::vector &TopLevelLoops = @@ -116,6 +124,9 @@ return Changed; } + +/// visitLoop - Hoist expressions out of the specified loop... +/// void LICM::visitLoop(Loop *L) { // Recurse through all subloops before we process this loop... std::for_each(L->getSubLoops().begin(), L->getSubLoops().end(), @@ -143,6 +154,8 @@ CurLoop = 0; } +/// visitBasicBlock - Run LICM on a particular block. +/// void LICM::visitBasicBlock(BasicBlock *BB) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { visit(*I); @@ -155,6 +168,9 @@ } +/// hoist - When an instruction is found to only use loop invariant operands +/// that is safe to hoist, this instruction is called to do the dirty work. +/// void LICM::hoist(Instruction &Inst) { if (Inst.use_empty()) return; // Don't (re) hoist dead instructions! //cerr << "Hoisting " << Inst; @@ -196,9 +212,9 @@ } -// pointerInvalidatedByLoop - Return true if the body of this loop may store -// into the memory location pointed to by V. -// +/// pointerInvalidatedByLoop - Return true if the body of this loop may store +/// into the memory location pointed to by V. +/// bool LICM::pointerInvalidatedByLoop(Value *V) { // Check to see if any of the basic blocks in CurLoop invalidate V. for (unsigned i = 0, e = CurLoop->getBlocks().size(); i != e; ++i) From lattner at cs.uiuc.edu Thu Sep 26 14:41:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 14:41:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200209261940.OAA07431@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.15 -> 1.16 --- Log message: - Further cleanups of LICM pass, remove extra work from previous implementation - Do not clone instructions then insert clone outside of loop. Just move them. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.15 llvm/lib/Transforms/Scalar/LICM.cpp:1.16 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.15 Thu Sep 26 11:52:07 2002 +++ llvm/lib/Transforms/Scalar/LICM.cpp Thu Sep 26 14:40:25 2002 @@ -34,23 +34,24 @@ } private: - Loop *CurLoop; // The current loop we are working on... - bool Changed; // Set to true when we change anything. - AliasAnalysis *AA; // Currently AliasAnalysis information + Loop *CurLoop; // The current loop we are working on... + BasicBlock *Preheader; // The preheader block of the current loop... + bool Changed; // Set to true when we change anything. + AliasAnalysis *AA; // Currently AliasAnalysis information /// visitLoop - Hoist expressions out of the specified loop... /// void visitLoop(Loop *L); - /// notInCurrentLoop - Little predicate that returns true if the specified + /// inCurrentLoop - Little predicate that returns false if the specified /// basic block is in a subloop of the current one, not the current one /// itself. /// - bool notInCurrentLoop(BasicBlock *BB) { + bool inCurrentLoop(BasicBlock *BB) { for (unsigned i = 0, e = CurLoop->getSubLoops().size(); i != e; ++i) if (CurLoop->getSubLoops()[i]->contains(BB)) - return true; // A subloop actually contains this block! - return false; + return false; // A subloop actually contains this block! + return true; } /// hoist - When an instruction is found to only use loop invariant operands @@ -71,10 +72,6 @@ return true; // All non-instructions are loop invariant } - /// visitBasicBlock - Run LICM on a particular block. - /// - void visitBasicBlock(BasicBlock *BB); - /// Instruction visitation handlers... these basically control whether or /// not the specified instruction types are hoisted. /// @@ -108,7 +105,7 @@ /// function, hoisting expressions out of loops if possible. /// bool LICM::runOnFunction(Function &) { - // get our loop information... + // Get information about the top level loops in the function... const std::vector &TopLevelLoops = getAnalysis().getTopLevelLoops(); @@ -133,41 +130,25 @@ bind_obj(this, &LICM::visitLoop)); CurLoop = L; + // Get the preheader block to move instructions into... + Preheader = L->getLoopPreheader(); + assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!"); + // We want to visit all of the instructions in this loop... that are not parts // of our subloops (they have already had their invariants hoisted out of // their loop, into this loop, so there is no need to process the BODIES of // the subloops). // - std::vector BBs(L->getBlocks().begin(), L->getBlocks().end()); - - // Remove blocks that are actually in subloops... - BBs.erase(std::remove_if(BBs.begin(), BBs.end(), - bind_obj(this, &LICM::notInCurrentLoop)), BBs.end()); - - // Visit all of the basic blocks we have chosen, hoisting out the instructions - // as neccesary. This leaves dead copies of the instruction in the loop - // unfortunately... - // - for_each(BBs.begin(), BBs.end(), bind_obj(this, &LICM::visitBasicBlock)); + for (std::vector::const_iterator + I = L->getBlocks().begin(), E = L->getBlocks().end(); I != E; ++I) + if (inCurrentLoop(*I)) + visit(**I); // Clear out loops state information for the next iteration CurLoop = 0; + Preheader = 0; } -/// visitBasicBlock - Run LICM on a particular block. -/// -void LICM::visitBasicBlock(BasicBlock *BB) { - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { - visit(*I); - - if (dceInstruction(I)) - Changed = true; - else - ++I; - } -} - - /// hoist - When an instruction is found to only use loop invariant operands /// that is safe to hoist, this instruction is called to do the dirty work. /// @@ -177,39 +158,24 @@ BasicBlock *Header = CurLoop->getHeader(); - // Old instruction will be removed, so take it's name... - string InstName = Inst.getName(); - Inst.setName(""); - - if (isa(Inst)) - ++NumHoistedLoads; - - // The common case is that we have a pre-header. Generate special case code - // that is faster if that is the case. - // - BasicBlock *Preheader = CurLoop->getLoopPreheader(); - assert(Preheader&&"Preheader insertion pass guarantees we have a preheader!"); - - // Create a new copy of the instruction, for insertion into Preheader. - Instruction *New = Inst.clone(); - New->setName(InstName); + // Remove the instruction from its current basic block... but don't delete the + // instruction. + Inst.getParent()->getInstList().remove(&Inst); // Insert the new node in Preheader, before the terminator. - Preheader->getInstList().insert(--Preheader->end(), New); + Preheader->getInstList().insert(Preheader->getTerminator(), &Inst); - // Kill the old instruction... - Inst.replaceAllUsesWith(New); ++NumHoisted; - Changed = true; } void LICM::visitLoadInst(LoadInst &LI) { if (isLoopInvariant(LI.getOperand(0)) && - !pointerInvalidatedByLoop(LI.getOperand(0))) + !pointerInvalidatedByLoop(LI.getOperand(0))) { hoist(LI); - + ++NumHoistedLoads; + } } /// pointerInvalidatedByLoop - Return true if the body of this loop may store From lattner at cs.uiuc.edu Thu Sep 26 14:46:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 14:46:00 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopPreheaders/ Message-ID: <200209261945.OAA07458@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopPreheaders: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Regression/Transforms/LoopPreheaders added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Sep 26 14:50:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 14:50:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopPreheaders/Makefile basictest.ll hardertest.ll Message-ID: <200209261950.OAA07804@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopPreheaders: Makefile added (r1.1) basictest.ll added (r1.1) hardertest.ll added (r1.1) --- Log message: Checkin the simple features tests for the preheader insertion pass. --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Sep 26 14:53:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 14:53:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Makefile Message-ID: <200209261953.OAA07824@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms: Makefile updated: 1.17 -> 1.18 --- Log message: * Run preheaders pass tests * Linearize list of directories so I don't have to keep dealing with wrapping problems. --- Diffs of the changes: Index: llvm/test/Regression/Transforms/Makefile diff -u llvm/test/Regression/Transforms/Makefile:1.17 llvm/test/Regression/Transforms/Makefile:1.18 --- llvm/test/Regression/Transforms/Makefile:1.17 Mon Sep 23 17:26:23 2002 +++ llvm/test/Regression/Transforms/Makefile Thu Sep 26 14:53:02 2002 @@ -1,6 +1,24 @@ -LEVEL = ../../.. -DIRS = ADCE CFGSimplify ConstProp ConstantMerge CorrelatedExprs \ - DecomposeMultiDimRefs FunctionResolve GCSE \ - GlobalDCE IndVarSimplify Inline InstCombine LevelRaise LICM Mem2Reg \ - PiNodeInserter ProfilePaths Reassociate SCCP SimplifyCFG +LEVEL = ../../.. +DIRS = ADCE \ + CFGSimplify \ + ConstProp \ + ConstantMerge \ + CorrelatedExprs \ + DecomposeMultiDimRefs \ + FunctionResolve \ + GCSE \ + GlobalDCE \ + IndVarSimplify \ + Inline \ + InstCombine \ + LevelRaise \ + LICM \ + Mem2Reg \ + PiNodeInserter \ + LoopPreheaders \ + ProfilePaths \ + Reassociate \ + SCCP \ + SimplifyCFG + include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Thu Sep 26 16:49:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 16:49:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/AliasSetTracker.h Message-ID: <200209262149.QAA10117@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: AliasSetTracker.h added (r1.1) --- Log message: First try at implementing the AliasSetTracker class. I'm sure it will need revision as I start to use it though. --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Sep 26 16:49:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Sep 26 16:49:04 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasSetTracker.cpp Message-ID: <200209262149.QAA10122@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasSetTracker.cpp added (r1.1) --- Log message: First try at implementing the AliasSetTracker class. I'm sure it will need revision as I start to use it though. --- Diffs of the changes: From vadve at cs.uiuc.edu Fri Sep 27 08:27:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Sep 27 08:27:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/LLC/casts.c Message-ID: <200209271326.IAA12285@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/LLC: casts.c updated: 1.2 -> 1.3 --- Log message: Overhauled completely. --- Diffs of the changes: Index: llvm/test/Regression/LLC/casts.c diff -u llvm/test/Regression/LLC/casts.c:1.2 llvm/test/Regression/LLC/casts.c:1.3 --- llvm/test/Regression/LLC/casts.c:1.2 Thu Sep 19 20:05:16 2002 +++ llvm/test/Regression/LLC/casts.c Fri Sep 27 08:26:36 2002 @@ -8,80 +8,119 @@ int main(int argc, char** argv) { - char c1; - short s1, ssf1, ssd1; - uint8_t ubs0; - int8_t bs0; - unsigned char ubc0, uc2; - unsigned short us2, usf1, usd1; - int ic3, is3, sif1, sid1; - unsigned uic4, uis4, uif1, uid1; - long slf1, sld1; - unsigned long ulf1, uld1; - float f1; - double d1; + int8_t C, c1; + uint8_t uc1; + + short S, s1; + unsigned short us1; + + int i1; + unsigned ui1; + + int64_t L, l1; + uint64_t ul1; + + float F; + double D; + + /* input values */ + C = (char) (argc >= 2)? atoi(argv[1]) : 0x64; /* 100 = 'd' */ + S = (short) (argc >= 3)? atoi(argv[2]) : -769; /* 0xfcff = -769 */ + L = (long) (argc >= 4)? atoi(argv[3]) : 0xa3a3a3a3a3a3; /*179923220407203*/ /* Test integer to integer conversions */ - - c1 = (char) (argc >= 2)? atoi(argv[1]) : 0xff64; /* 100 = 'd' */ - s1 = (short) (argc >= 3)? atoi(argv[2]) : -769; /* 0xfcff = -769 */ - - ubc0 = (unsigned char) c1; /* 100 = 'd' */ - ubs0 = (uint8_t) s1; /* 0xff = 255 */ - bs0 = (int8_t) s1; /* 0xff = -1 */ - - uc2 = (unsigned char) c1; /* 100 = 'd' */ - us2 = (unsigned short) s1; /* 0xfcff = 64767 */ - - ic3 = (int) c1; /* 100 = 'd' */ - is3 = (int) s1; /* 0xfffffcff = -769 */ - - uic4 = (unsigned int) c1; /* 100 = 'd' */ - uis4 = (unsigned int) s1; /* 0xfffffcff = 4294966527 */ - - printf("ubc0 = '%c'\n", ubc0); - printf("ubs0 = %u\n", ubs0); - printf("bs0 = %d\n", bs0); - printf("c1 = '%c'\n", c1); - printf("s1 = %d\n", s1); - printf("uc2 = '%c'\n", uc2); - printf("us2 = %u\n", us2); - printf("ic3 = '%c'\n", ic3); - printf("is3 = %d\n", is3); - printf("uic4 = '%c'\n", uic4); - printf("uis4 = %u\n", uis4); - + uc1 = (uint8_t) C; /* 100 = 'd' */ + us1 = (unsigned short) C; /* 100 = 'd' */ + ui1 = (unsigned int) C; /* 100 = 'd' */ + ul1 = (unsigned long) C; /* 100 = 'd' */ + + s1 = (short) C; /* 100 = 'd' */ + i1 = (int) C; /* 100 = 'd' */ + l1 = (long) C; /* 100 = 'd' */ + + printf("\nCHAR C = '%c' (%d)\t\t(0x%x)\n", C, C, C); + printf("char to short s1 = %d\t\t(0x%x)\n", s1, s1); + printf("char to int i1 = %d\t\t(0x%x)\n", i1, i1); + printf("char to long l1 = %ld\t\t(0x%lx)\n", l1, l1); + + printf("\nchar to ubyte uc1 = %u\t\t(0x%x)\n", uc1, uc1); + printf("char to ushort us1 = %u\t\t(0x%x)\n", us1, us1); + printf("char to uint ui1 = %u\t\t(0x%x)\n", ui1, ui1); + printf("char to ulong ul1 = %lu\t\t(0x%lx)\n", ul1, ul1); + + uc1 = (uint8_t) S; /* 0xff = 255 */ + us1 = (unsigned short) S; /* 0xfcff = 64767 */ + ui1 = (unsigned int) S; /* 0xfffffcff = 4294966527 */ + ul1 = (unsigned long) S; /* */ + + c1 = (int8_t) S; /* 0xff = -1 */ + i1 = (int) S; /* 0xfffffcff = -769 */ + l1 = (long) S; /* */ + + printf("\n\nSHORT S = %d\t\t(0x%x)\n", S, S); + printf("short to byte c1 = %d\t\t(0x%x)\n", c1, c1); + printf("short to int i1 = %d\t\t(0x%x)\n", i1, i1); + printf("short to long l1 = %ld\t\t(0x%lx)\n", l1, l1); + + printf("\nshort to ubyte uc1 = %u\t\t(0x%x)\n", uc1, uc1); + printf("short to ushort us1 = %u\t\t(0x%x)\n", us1, us1); + printf("short to uint ui1 = %u\t\t(0x%x)\n", ui1, ui1); + printf("short to ulong ul1 = %lu\t\t(0x%lx)\n", ul1, ul1); + + uc1 = (unsigned char) L; /* */ + c1 = (int8_t) L; /* */ + s1 = (short) L; /* */ + us1 = (unsigned short) L; /* */ + i1 = (int) L; /* */ + ui1 = (unsigned int) L; /* */ + ul1 = (unsigned long) L; /* */ + + printf("\n\nLONG L = %ld\t\t(0x%lx)\n", L, L); + printf("long to byte c1 = %d\t\t(0x%x)\n", c1, c1); + printf("long to short s1 = %d\t\t(0x%x)\n", s1, s1); + printf("long to int i1 = %d\t\t(0x%x)\n", i1, i1); + + printf("\nlong to ubyte uc1 = %u\t\t(0x%x)\n", uc1, uc1); + printf("long to ushort us1 = %u\t\t(0x%x)\n", us1, us1); + printf("long to uint ui1 = %u\t\t(0x%x)\n", ui1, ui1); + printf("long to ulong ul1 = %lu\t\t(0x%lx)\n", ul1, ul1); + /* Test floating-point to integer conversions */ - f1 = (float) (argc >= 4)? atof(argv[3]) : 1.0; - d1 = (argc >= 5)? atof(argv[4]) : 2.0; - - usf1 = (unsigned short) f1; - usd1 = (unsigned short) d1; - uif1 = (unsigned int) f1; - uid1 = (unsigned int) d1; - ulf1 = (unsigned long) f1; - uld1 = (unsigned long) d1; - - ssf1 = (short) f1; - ssd1 = (short) d1; - sif1 = (int) f1; - sid1 = (int) d1; - slf1 = (long) f1; - sld1 = (long) d1; - - printf("usf1 = %u\n", usf1); - printf("usd1 = %u\n", usd1); - printf("uif1 = %u\n", uif1); - printf("uid1 = %u\n", uid1); - printf("ulf1 = %lu\n", ulf1); - printf("uld1 = %lu\n", uld1); - - printf("ssf1 = %d\n", ssf1); - printf("ssd1 = %d\n", ssd1); - printf("sif1 = %d\n", sif1); - printf("sid1 = %d\n", sid1); - printf("slf1 = %ld\n", slf1); - printf("sld1 = %ld\n", sld1); + F = (float) (argc >= 4)? atof(argv[3]) : 1.0; + D = (argc >= 5)? atof(argv[4]) : 2.0; + us1 = (unsigned short) F; + ui1 = (unsigned int) F; + ul1 = (unsigned long) F; + + s1 = (short) F; + i1 = (int) F; + l1 = (long) F; + + printf("\n\nFLOAT F = %f\n", F); + printf("float to short s1 = %d\t\t(0x%x)\n", s1, s1); + printf("float to int i1 = %d\t\t(0x%x)\n", i1, i1); + + printf("float to ushort us1 = %u\t\t(0x%x)\n", us1, us1); + printf("float to uint ui1 = %u\t\t(0x%x)\n", ui1, ui1); + printf("float to ulong ul1 = %lu\t\t(0x%lx)\n", ul1, ul1); + + us1 = (unsigned short) D; + ui1 = (unsigned int) D; + ul1 = (unsigned long) D; + + s1 = (short) D; + i1 = (int) D; + l1 = (long) D; + + printf("\n\nDOUBLE D = %f\n", D); + printf("double to short s1 = %d\t\t(0x%x)\n", s1, s1); + printf("double to int i1 = %d\t\t(0x%x)\n", i1, i1); + printf("double to long l1 = %ld\t\t(0x%lx)\n", l1, l1); + + printf("double to ushort us1 = %u\t\t(0x%x)\n", us1, us1); + printf("double to uint ui1 = %u\t\t(0x%x)\n", ui1, ui1); + printf("double to ulong ul1 = %lu\t\t(0x%lx)\n", ul1, ul1); + return 0; } From vadve at cs.uiuc.edu Fri Sep 27 08:28:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Sep 27 08:28:00 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/LLC/globalrefs.c Message-ID: <200209271327.IAA12300@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/LLC: globalrefs.c added (r1.1) --- Log message: Simple test for constant expressions constructed from global addresses. --- Diffs of the changes: From vadve at cs.uiuc.edu Fri Sep 27 09:25:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Sep 27 09:25:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PreOpts/PreSelection.cpp Message-ID: <200209271424.JAA12828@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/PreOpts: PreSelection.cpp updated: 1.1 -> 1.2 --- Log message: Decompose FP-to-UInt casts into FP-to-ULong-toUInt. --- Diffs of the changes: Index: llvm/lib/CodeGen/PreOpts/PreSelection.cpp diff -u llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.1 llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.2 --- llvm/lib/CodeGen/PreOpts/PreSelection.cpp:1.1 Thu Sep 19 19:29:28 2002 +++ llvm/lib/CodeGen/PreOpts/PreSelection.cpp Fri Sep 27 09:24:45 2002 @@ -146,6 +146,7 @@ void visitInstruction(Instruction &I); // common work for every instr. void visitGetElementPtrInst(GetElementPtrInst &I); void visitLoadInst(LoadInst &I); + void visitCastInst(CastInst &I); void visitStoreInst(StoreInst &I); // Helper functions for visiting operands of every instruction @@ -225,6 +226,33 @@ // Perform other transformations common to all instructions visitInstruction(I); +} + + +// 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. +// +void +PreSelection::visitCastInst(CastInst &I) +{ + 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()) + { // 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 + } + + // Perform other transformations common to all instructions + visitInstruction(I); + if (castI) + visitInstruction(*castI); } From vadve at cs.uiuc.edu Fri Sep 27 09:27:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Sep 27 09:27:00 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp Message-ID: <200209271426.JAA12851@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSelection: InstrSelectionSupport.cpp updated: 1.32 -> 1.33 --- Log message: Sign-extend integer constants from original type size to 64 bits! --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp diff -u llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.32 llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.33 --- llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.32 Tue Sep 17 12:23:09 2002 +++ llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp Fri Sep 27 09:26:20 2002 @@ -373,11 +373,15 @@ else if (CPV->getType()->isSigned()) intValue = cast(CPV)->getValue(); else - { - assert(CPV->getType()->isUnsigned() && "Not pointer, bool, or integer?"); - uint64_t V = cast(CPV)->getValue(); - if (V >= INT64_MAX) return MachineOperand::MO_VirtualRegister; - intValue = (int64_t) V; + { // get the int value and sign-extend if original was less than 64 bits + intValue = (int64_t) cast(CPV)->getValue(); + switch(CPV->getType()->getPrimitiveID()) + { + case Type::UByteTyID: intValue = (int64_t) (int8_t) intValue; break; + case Type::UShortTyID: intValue = (int64_t) (short) intValue; break; + case Type::UIntTyID: intValue = (int64_t) (int) intValue; break; + default: break; + } } return ChooseRegOrImmed(intValue, CPV->getType()->isSigned(), From vadve at cs.uiuc.edu Fri Sep 27 09:28:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Sep 27 09:28:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PostOpts/PeepholeOpts.cpp Message-ID: <200209271427.JAA12869@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/PostOpts: PeepholeOpts.cpp updated: 1.1 -> 1.2 --- Log message: Bug fix: some redundant copies were not being deleted after detection :-|. --- Diffs of the changes: Index: llvm/lib/CodeGen/PostOpts/PeepholeOpts.cpp diff -u llvm/lib/CodeGen/PostOpts/PeepholeOpts.cpp:1.1 llvm/lib/CodeGen/PostOpts/PeepholeOpts.cpp:1.2 --- llvm/lib/CodeGen/PostOpts/PeepholeOpts.cpp:1.1 Thu Sep 19 19:42:10 2002 +++ llvm/lib/CodeGen/PostOpts/PeepholeOpts.cpp Fri Sep 27 09:27:37 2002 @@ -1,4 +1,4 @@ -// $Id: PeepholeOpts.cpp,v 1.1 2002/09/20 00:42:10 vadve Exp $ -*-c++-*- +// $Id: PeepholeOpts.cpp,v 1.2 2002/09/27 14:27:37 vadve Exp $ -*-c++-*- //*************************************************************************** // File: // PeepholeOpts.h @@ -30,23 +30,25 @@ const TargetMachine& target) { // Check if this instruction is in a delay slot of its predecessor. - // If so, replace this instruction with a nop, else just delete it. - // By replacing in place, we save having to update the I-I maps. if (BBI != mvec.begin()) { const MachineInstrInfo& mii = target.getInstrInfo(); MachineInstr* predMI = *(BBI-1); if (unsigned ndelay = mii.getNumDelaySlots(predMI->getOpCode())) { + // This instruction is in a delay slot of its predecessor, so + // replace it with a nop. By replacing in place, we save having + // to update the I-I maps. + // assert(ndelay == 1 && "Not yet handling multiple-delay-slot targets"); (*BBI)->replace(mii.getNOPOpCode(), 0); + return; } } - else - { - mvec.erase(BBI); - BBI = mvec.end(); - } + + // The instruction is not in a delay slot, so we can simply erase it. + mvec.erase(BBI); + BBI = mvec.end(); } //******************* Individual Peephole Optimizations ********************/ From vadve at cs.uiuc.edu Fri Sep 27 09:30:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Sep 27 09:30:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrInfo.cpp SparcInternals.h Message-ID: <200209271429.JAA12895@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrInfo.cpp updated: 1.27 -> 1.28 SparcInternals.h updated: 1.64 -> 1.65 --- Log message: Modify operand order for Create{Sign,Zero}ExtensionInstructions. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrInfo.cpp diff -u llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.27 llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.28 --- llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.27 Mon Sep 16 10:55:52 2002 +++ llvm/lib/Target/Sparc/SparcInstrInfo.cpp Fri Sep 27 09:29:45 2002 @@ -497,10 +497,10 @@ { // sign- or zero-extend respectively storeVal = new TmpInstruction(storeType, val); if (val->getType()->isSigned()) - CreateSignExtensionInstructions(target, F, val, 8*srcSize, storeVal, + CreateSignExtensionInstructions(target, F, val, storeVal, 8*srcSize, mvec, mcfi); else - CreateZeroExtensionInstructions(target, F, val, 8*srcSize, storeVal, + CreateZeroExtensionInstructions(target, F, val, storeVal, 8*srcSize, mvec, mcfi); } MachineInstr* store=new MachineInstr(ChooseStoreInstruction(storeType)); @@ -640,27 +640,27 @@ const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, vector& mvec, MachineCodeForInstruction& mcfi) { MachineInstr* M; - assert(srcSizeInBits <= 32 && - "Hmmm... 32 < srcSizeInBits < 64 unexpected but could be handled."); - if (srcSizeInBits < 32) + assert(numLowBits <= 32 && "Otherwise, nothing should be done here!"); + + if (numLowBits < 32) { // SLL is needed since operand size is < 32 bits. - TmpInstruction *tmpI = new TmpInstruction(dest->getType(), - srcVal, dest,"make32"); + TmpInstruction *tmpI = new TmpInstruction(destVal->getType(), + srcVal, destVal, "make32"); mcfi.addTemp(tmpI); - M = Create3OperandInstr_UImmed(SLLX, srcVal, 32-srcSizeInBits, tmpI); + M = Create3OperandInstr_UImmed(SLLX, srcVal, 32-numLowBits, tmpI); mvec.push_back(M); srcVal = tmpI; } M = Create3OperandInstr_UImmed(signExtend? SRA : SRL, - srcVal, 32-srcSizeInBits, dest); + srcVal, 32-numLowBits, destVal); mvec.push_back(M); } @@ -676,13 +676,13 @@ const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, vector& mvec, MachineCodeForInstruction& mcfi) const { CreateBitExtensionInstructions(/*signExtend*/ true, target, F, srcVal, - srcSizeInBits, dest, mvec, mcfi); + destVal, numLowBits, mvec, mcfi); } @@ -698,11 +698,11 @@ const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, vector& mvec, MachineCodeForInstruction& mcfi) const { CreateBitExtensionInstructions(/*signExtend*/ false, target, F, srcVal, - srcSizeInBits, dest, mvec, mcfi); + destVal, numLowBits, mvec, mcfi); } Index: llvm/lib/Target/Sparc/SparcInternals.h diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.64 llvm/lib/Target/Sparc/SparcInternals.h:1.65 --- llvm/lib/Target/Sparc/SparcInternals.h:1.64 Thu Sep 19 19:52:09 2002 +++ llvm/lib/Target/Sparc/SparcInternals.h Fri Sep 27 09:29:45 2002 @@ -194,8 +194,8 @@ virtual void CreateSignExtensionInstructions(const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, std::vector& mvec, MachineCodeForInstruction& mcfi) const; @@ -208,8 +208,8 @@ virtual void CreateZeroExtensionInstructions(const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, std::vector& mvec, MachineCodeForInstruction& mcfi) const; }; From vadve at cs.uiuc.edu Fri Sep 27 09:31:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Sep 27 09:31:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcOptInfo.cpp Message-ID: <200209271430.JAA12911@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcOptInfo.cpp updated: 1.1 -> 1.2 --- Log message: Check for floating point copies (FMOVS, FMOVD). Also handle add with constant 0, in addition to add with %g0. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcOptInfo.cpp diff -u llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.1 llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.2 --- llvm/lib/Target/Sparc/SparcOptInfo.cpp:1.1 Fri Sep 20 11:38:35 2002 +++ llvm/lib/Target/Sparc/SparcOptInfo.cpp Fri Sep 27 09:30:49 2002 @@ -11,8 +11,9 @@ //---------------------------------------------------------------------------- // Function: IsUselessCopy // Decide whether a machine instruction is a redundant copy: -// -- add with g0 -// -- or with g0. +// -- ADD with g0 and result and operand are identical, or +// -- OR with g0 and result and operand are identical, or +// -- FMOVS or FMOVD and result and operand are identical. // Other cases are possible but very rare that they would be useless copies, // so it's not worth analyzing them. //---------------------------------------------------------------------------- @@ -20,12 +21,28 @@ bool UltraSparcOptInfo::IsUselessCopy(const MachineInstr* MI) const { - if (MI->getOpCode() != ADD && MI->getOpCode() != OR) + if (MI->getOpCode() == FMOVS || MI->getOpCode() == FMOVD) + { + return (/* both operands are allocated to the same register */ + MI->getOperand(0).getAllocatedRegNum() == + MI->getOperand(1).getAllocatedRegNum()); + } + 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))); + } + else return false; - - return ((MI->getOperand(0).getAllocatedRegNum() == - MI->getOperand(2).getAllocatedRegNum()) && - (MI->getOperand(1).hasAllocatedReg() && - MI->getOperand(1).getAllocatedRegNum() == - target.getRegInfo().getZeroRegNum())); } From vadve at cs.uiuc.edu Fri Sep 27 09:34:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Sep 27 09:34:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200209271433.JAA12926@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.72 -> 1.73 --- Log message: Overhaul integer conversions to match C++ ISO standard. Don't allow direct FP-to-uint conversion (must be eliminated by preselection). Address arithmetic for arrays is now entirely 64-bit so no sign-ext needed. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.72 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.73 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.72 Mon Sep 16 10:56:45 2002 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Fri Sep 27 09:33:08 2002 @@ -268,43 +268,38 @@ } static inline MachineOpCode -ChooseConvertToIntInstr(Type::PrimitiveID tid, const Type* opType) +ChooseConvertFPToIntInstr(Type::PrimitiveID tid, const Type* opType) { MachineOpCode opCode = INVALID_OPCODE;; - - if (tid==Type::SByteTyID || tid==Type::ShortTyID || tid==Type::IntTyID || - tid==Type::UByteTyID || tid==Type::UShortTyID || tid==Type::UIntTyID) + + assert((opType == Type::FloatTy || opType == Type::DoubleTy) + && "This function should only be called for FLOAT or DOUBLE"); + + if (tid==Type::UIntTyID) { - switch (opType->getPrimitiveID()) - { - case Type::FloatTyID: opCode = FSTOI; break; - case Type::DoubleTyID: opCode = FDTOI; break; - default: - assert(0 && "Non-numeric non-bool type cannot be converted to Int"); - break; - } + assert(tid != Type::UIntTyID && "FP-to-uint conversions must be expanded" + " into FP->long->uint for SPARC v9: SO RUN PRESELECTION PASS!"); + } + else if (tid==Type::SByteTyID || tid==Type::ShortTyID || tid==Type::IntTyID || + tid==Type::UByteTyID || tid==Type::UShortTyID) + { + opCode = (opType == Type::FloatTy)? FSTOI : FDTOI; } else if (tid==Type::LongTyID || tid==Type::ULongTyID) { - switch (opType->getPrimitiveID()) - { - case Type::FloatTyID: opCode = FSTOX; break; - case Type::DoubleTyID: opCode = FDTOX; break; - default: - assert(0 && "Non-numeric non-bool type cannot be converted to Long"); - break; - } + opCode = (opType == Type::FloatTy)? FSTOX : FDTOX; } else assert(0 && "Should not get here, Mo!"); - + return opCode; } MachineInstr* -CreateConvertToIntInstr(Type::PrimitiveID destTID, Value* srcVal,Value* destVal) +CreateConvertFPToIntInstr(Type::PrimitiveID destTID, + Value* srcVal, Value* destVal) { - MachineOpCode opCode = ChooseConvertToIntInstr(destTID, srcVal->getType()); + MachineOpCode opCode = ChooseConvertFPToIntInstr(destTID, srcVal->getType()); assert(opCode != INVALID_OPCODE && "Expected to need conversion!"); MachineInstr* M = new MachineInstr(opCode); @@ -348,8 +343,8 @@ mcfi.addTemp(destForCast); // Create the fp-to-int conversion code - MachineInstr* M = CreateConvertToIntInstr(destI->getType()->getPrimitiveID(), - opVal, destForCast); + MachineInstr* M =CreateConvertFPToIntInstr(destI->getType()->getPrimitiveID(), + opVal, destForCast); mvec.push_back(M); // Create the fpreg-to-intreg copy code @@ -540,7 +535,6 @@ // of dest, so we need to put the result of the SLL into a temporary. // Value* shiftDest = destVal; - const Type* opType = argVal1->getType(); unsigned opSize = target.DataLayout.getTypeSize(argVal1->getType()); if ((shiftOpCode == SLL || shiftOpCode == SLLX) && opSize < target.DataLayout.getIntegerRegize()) @@ -558,8 +552,8 @@ { // extend the sign-bit of the result into all upper bits of dest assert(8*opSize <= 32 && "Unexpected type size > 4 and < IntRegSize?"); target.getInstrInfo(). - CreateSignExtensionInstructions(target, F, shiftDest, 8*opSize, - destVal, mvec, mcfi); + CreateSignExtensionInstructions(target, F, shiftDest, destVal, + 8*opSize, mvec, mcfi); } } @@ -1000,7 +994,7 @@ Value* idxVal = idxVec[firstIdxIsZero]; vector mulVec; - Instruction* addr = new TmpInstruction(Type::UIntTy, memInst); + Instruction* addr = new TmpInstruction(Type::ULongTy, memInst); MachineCodeForInstruction::get(memInst).addTemp(addr); // Get the array type indexed by idxVal, and compute its element size. @@ -1024,9 +1018,6 @@ MachineCodeForInstruction::get(memInst), INVALID_MACHINE_OPCODE); - // Sign-extend the result of MUL from 32 to 64 bits. - target.getInstrInfo().CreateSignExtensionInstructions(target, memInst->getParent()->getParent(), addr, /*srcSizeInBits*/32, addr, mulVec, MachineCodeForInstruction::get(memInst)); - // Insert mulVec[] before *mvecI in mvec[] and update mvecI // to point to the same instruction it pointed to before. assert(mulVec.size() > 0 && "No multiply code created?"); @@ -1446,29 +1437,64 @@ } case 23: // reg: ToUByteTy(reg) + case 24: // reg: ToSByteTy(reg) case 25: // reg: ToUShortTy(reg) + case 26: // reg: ToShortTy(reg) case 27: // reg: ToUIntTy(reg) - case 29: // reg: ToULongTy(reg) + case 28: // reg: ToIntTy(reg) { + //====================================================================== + // Rules for integer conversions: + // + //-------- + // From ISO 1998 C++ Standard, Sec. 4.7: + // + // 2. If the destination type is unsigned, the resulting value is + // the least unsigned integer congruent to the source integer + // (modulo 2n where n is the number of bits used to represent the + // unsigned type). [Note: In a two s complement representation, + // this conversion is conceptual and there is no change in the + // bit pattern (if there is no truncation). ] + // + // 3. If the destination type is signed, the value is unchanged if + // it can be represented in the destination type (and bitfield width); + // otherwise, the value is implementation-defined. + //-------- + // + // Since we assume 2s complement representations, this implies: + // + // -- if operand is smaller than destination, zero-extend or sign-extend + // according to the signedness of the *operand*: source decides. + // ==> we have to do nothing here! + // + // -- if operand is same size as or larger than destination, and the + // destination is *unsigned*, zero-extend the operand: dest. decides + // + // -- if operand is same size as or larger than destination, and the + // destination is *signed*, the choice is implementation defined: + // we sign-extend the operand: i.e., again dest. decides. + // Note: this matches both Sun's cc and gcc3.2. + //====================================================================== + Instruction* destI = subtreeRoot->getInstruction(); Value* opVal = subtreeRoot->leftChild()->getValue(); - const Type* opType = subtreeRoot->leftChild()->getValue()->getType(); + const Type* opType = opVal->getType(); if (opType->isIntegral() || isa(opType)) { unsigned opSize = target.DataLayout.getTypeSize(opType); unsigned destSize = target.DataLayout.getTypeSize(destI->getType()); - if (opSize > destSize || - (opType->isSigned() - && destSize < target.DataLayout.getIntegerRegize())) - { // operand is larger than dest, - // OR both are equal but smaller than the full register size - // AND operand is signed, so it may have extra sign bits: - // mask high bits using AND - M = Create3OperandInstr(AND, opVal, - ConstantUInt::get(Type::ULongTy, - ((uint64_t) 1 << 8*destSize) - 1), - destI); - mvec.push_back(M); + if (opSize >= destSize) + { // Operand is same size as or larger than dest: + // zero- or sign-extend, according to the signeddness of + // the destination (see above). + if (destI->getType()->isSigned()) + target.getInstrInfo().CreateSignExtensionInstructions(target, + destI->getParent()->getParent(), opVal, destI, 8*destSize, + mvec, MachineCodeForInstruction::get(destI)); + else + target.getInstrInfo().CreateZeroExtensionInstructions(target, + destI->getParent()->getParent(), opVal, destI, 8*destSize, + mvec, MachineCodeForInstruction::get(destI)); } else forwardOperandNum = 0; // forward first operand to user @@ -1477,69 +1503,33 @@ { CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, MachineCodeForInstruction::get(destI)); - maskUnsignedResult = true; // not handled by convert code + if (destI->getType()->isUnsigned()) + maskUnsignedResult = true; // not handled by fp->int code } else assert(0 && "Unrecognized operand type for convert-to-unsigned"); break; } - - case 24: // reg: ToSByteTy(reg) - case 26: // reg: ToShortTy(reg) - case 28: // reg: ToIntTy(reg) + + case 29: // reg: ToULongTy(reg) case 30: // reg: ToLongTy(reg) { - Instruction* destI = subtreeRoot->getInstruction(); Value* opVal = subtreeRoot->leftChild()->getValue(); - MachineCodeForInstruction& mcfi =MachineCodeForInstruction::get(destI); - const Type* opType = opVal->getType(); if (opType->isIntegral() || isa(opType)) + forwardOperandNum = 0; // forward first operand to user + else if (opType->isFloatingPoint()) { - // These operand types have the same format as the destination, - // but may have different size: add sign bits or mask as needed. - // - const Type* destType = destI->getType(); - unsigned opSize = target.DataLayout.getTypeSize(opType); - unsigned destSize = target.DataLayout.getTypeSize(destType); - - if (opSize < destSize || - (opSize == destSize && - opSize == target.DataLayout.getIntegerRegize())) - { // operand is smaller or both operand and result fill register - forwardOperandNum = 0; // forward first operand to user - } - else - { // need to mask (possibly) and then sign-extend (definitely) - Value* srcForSignExt = opVal; - unsigned srcSizeForSignExt = 8 * opSize; - if (opSize > destSize) - { // operand is larger than dest: mask high bits - TmpInstruction *tmpI = new TmpInstruction(destType, opVal, - destI, "maskHi"); - mcfi.addTemp(tmpI); - M = Create3OperandInstr(AND, opVal, - ConstantUInt::get(Type::ULongTy, - ((uint64_t) 1 << 8*destSize)-1), - tmpI); - mvec.push_back(M); - srcForSignExt = tmpI; - srcSizeForSignExt = 8 * destSize; - } - - // sign-extend - target.getInstrInfo().CreateSignExtensionInstructions(target, destI->getParent()->getParent(), srcForSignExt, srcSizeForSignExt, destI, mvec, mcfi); - } + Instruction* destI = subtreeRoot->getInstruction(); + CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, + MachineCodeForInstruction::get(destI)); } - else if (opType->isFloatingPoint()) - CreateCodeToConvertFloatToInt(target, opVal, destI, mvec, mcfi); else assert(0 && "Unrecognized operand type for convert-to-signed"); - break; - } - + } + case 31: // reg: ToFloatTy(reg): case 32: // reg: ToDoubleTy(reg): case 232: // reg: ToDoubleTy(Constant): @@ -1600,7 +1590,7 @@ } else srcForCast = leftVal; - + M = new MachineInstr(opCode); M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, srcForCast); @@ -2174,7 +2164,7 @@ for (unsigned i=0, N=mvec.size(); i < N; ++i) mvec[i]->substituteValue(dest, tmpI); - M = Create3OperandInstr_UImmed(SRL, tmpI, 4-destSize, dest); + M = Create3OperandInstr_UImmed(SRL, tmpI, 8*(4-destSize), dest); mvec.push_back(M); } else if (destSize < target.DataLayout.getIntegerRegize()) From vadve at cs.uiuc.edu Sat Sep 28 11:52:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 11:52:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/LLC/badCallArgLR.llvm.ll Message-ID: <200209281651.LAA17111@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/LLC: badCallArgLR.llvm.ll added (r1.1) --- Log message: Regression test for live range bug for call arguments. --- Diffs of the changes: From vadve at cs.uiuc.edu Sat Sep 28 11:56:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 11:56:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp Message-ID: <200209281655.LAA17175@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.73 -> 1.74 --- Log message: Simplify Call translation slightly. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.73 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.74 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.73 Fri Sep 27 09:33:08 2002 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Sat Sep 28 11:55:41 2002 @@ -1965,11 +1965,11 @@ } case 61: // reg: Call - { // Generate a direct (CALL) or indirect (JMPL). depending - // Mark the return-address register and the indirection - // register (if any) as hidden virtual registers. - // Also, mark the operands of the Call and return value (if - // any) as implicit operands of the CALL machine instruction. + { // Generate a direct (CALL) or indirect (JMPL) call. + // Mark the return-address register, the indirection + // register (for indirect calls), the operands of the Call, + // and the return value (if any) as implicit operands + // of the machine instruction. // // If this is a varargs function, floating point arguments // have to passed in integer registers so insert @@ -1977,34 +1977,22 @@ // CallInst *callInstr = cast(subtreeRoot->getInstruction()); Value *callee = callInstr->getCalledValue(); - - // Create hidden virtual register for return address, with type void*. + + // Create hidden virtual register for return address with type void* TmpInstruction* retAddrReg = new TmpInstruction(PointerType::get(Type::VoidTy), callInstr); MachineCodeForInstruction::get(callInstr).addTemp(retAddrReg); - + // Generate the machine instruction and its operands. // Use CALL for direct function calls; this optimistically assumes // the PC-relative address fits in the CALL address field (22 bits). // Use JMPL for indirect calls. // - if (isa(callee)) - { // direct function call - M = new MachineInstr(CALL); - M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp, - callee); - } - else - { // indirect function call - M = new MachineInstr(JMPLCALL); - M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, - callee); - M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed, - (int64_t) 0); - M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, - retAddrReg); - } - + if (isa(callee)) // direct function call + M = Create1OperandInstr_Addr(CALL, callee); + else // indirect function call + M = Create3OperandInstr_SImmed(JMPLCALL, callee, + (int64_t) 0, retAddrReg); mvec.push_back(M); const FunctionType* funcType = From vadve at cs.uiuc.edu Sat Sep 28 11:57:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 11:57:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInternals.h Message-ID: <200209281656.LAA17188@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInternals.h updated: 1.65 -> 1.66 --- Log message: Simplified code that handles call args and rets, so it no longer needs the RegClass list to be passed in. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInternals.h diff -u llvm/lib/Target/Sparc/SparcInternals.h:1.65 llvm/lib/Target/Sparc/SparcInternals.h:1.66 --- llvm/lib/Target/Sparc/SparcInternals.h:1.65 Fri Sep 27 09:29:45 2002 +++ llvm/lib/Target/Sparc/SparcInternals.h Sat Sep 28 11:56:39 2002 @@ -277,8 +277,7 @@ void suggestReg4RetAddr(MachineInstr *RetMI, LiveRangeInfo &LRI) const; - void suggestReg4CallAddr(MachineInstr *CallMI, LiveRangeInfo &LRI, - std::vector RCList) const; + void suggestReg4CallAddr(MachineInstr *CallMI, LiveRangeInfo &LRI) const; void InitializeOutgoingArg(MachineInstr* CallMI, AddedInstrns *CallAI, PhyRegAlloc &PRA, LiveRange* LR, @@ -384,8 +383,7 @@ LiveRangeInfo& LRI) const; void suggestRegs4CallArgs(MachineInstr *CallMI, - LiveRangeInfo& LRI, - std::vector RCL) const; + LiveRangeInfo& LRI) const; void suggestReg4RetValue(MachineInstr *RetMI, LiveRangeInfo& LRI) const; From vadve at cs.uiuc.edu Sat Sep 28 11:58:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 11:58:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MachineRegInfo.h Message-ID: <200209281657.LAA17202@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MachineRegInfo.h updated: 1.26 -> 1.27 --- Log message: Simplified code that handles call args and rets, so it no longer needs the RegClass list to be passed in. --- Diffs of the changes: Index: llvm/include/llvm/Target/MachineRegInfo.h diff -u llvm/include/llvm/Target/MachineRegInfo.h:1.26 llvm/include/llvm/Target/MachineRegInfo.h:1.27 --- llvm/include/llvm/Target/MachineRegInfo.h:1.26 Mon Aug 12 16:24:55 2002 +++ llvm/include/llvm/Target/MachineRegInfo.h Sat Sep 28 11:56:59 2002 @@ -122,7 +122,7 @@ LiveRangeInfo &LRI) const = 0; virtual void suggestRegs4CallArgs(MachineInstr *CallI, - LiveRangeInfo &LRI, std::vector RCL) const = 0; + LiveRangeInfo &LRI) const = 0; virtual void suggestReg4RetValue(MachineInstr *RetI, LiveRangeInfo &LRI) const = 0; From vadve at cs.uiuc.edu Sat Sep 28 12:00:02 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 12:00:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcRegInfo.cpp Message-ID: <200209281659.LAA17221@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcRegInfo.cpp updated: 1.71 -> 1.72 --- Log message: Live ranges for Return value and return address of a Call are no longer created here. Instead they are created in LiveRangeInfo.cpp. This simplifies the code here quite a bit. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcRegInfo.cpp diff -u llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.71 llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.72 --- llvm/lib/Target/Sparc/SparcRegInfo.cpp:1.71 Mon Sep 2 20:06:59 2002 +++ llvm/lib/Target/Sparc/SparcRegInfo.cpp Sat Sep 28 11:59:05 2002 @@ -351,23 +351,21 @@ // Suggests a register for the ret address in the JMPL/CALL machine instr. // Sparc ABI dictates that %o7 be used for this purpose. //--------------------------------------------------------------------------- -void UltraSparcRegInfo::suggestReg4CallAddr(MachineInstr * CallMI, - LiveRangeInfo& LRI, - std::vector RCList) const { +void +UltraSparcRegInfo::suggestReg4CallAddr(MachineInstr * CallMI, + LiveRangeInfo& LRI) const +{ CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI); const Value *RetAddrVal = argDesc->getReturnAddrReg(); - assert(RetAddrVal && "Return address value is required"); - - // create a new LR for the return address and color it - LiveRange * RetAddrLR = new LiveRange(); - RetAddrLR->insert( RetAddrVal ); - unsigned RegClassID = getRegClassIDOfValue( RetAddrVal ); - RetAddrLR->setRegClass( RCList[RegClassID] ); - RetAddrLR->setColor(getUnifiedRegNum(IntRegClassID,SparcIntRegClass::o7)); - LRI.addLRToMap( RetAddrVal, RetAddrLR); - -} + assert(RetAddrVal && "INTERNAL ERROR: Return address value is required"); + // A LR must already exist for the return address. + LiveRange *RetAddrLR = LRI.getLiveRangeForValue(RetAddrVal); + assert(RetAddrLR && "INTERNAL ERROR: No LR for return address of call!"); + + unsigned RegClassID = RetAddrLR->getRegClass()->getID(); + RetAddrLR->setColor(getUnifiedRegNum(IntRegClassID, SparcIntRegClass::o7)); +} @@ -565,39 +563,24 @@ // outgoing call args and the return value of the call. //--------------------------------------------------------------------------- void UltraSparcRegInfo::suggestRegs4CallArgs(MachineInstr *CallMI, - LiveRangeInfo& LRI, - std::vector RCList) const { + LiveRangeInfo& LRI) const { assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) ); CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI); - suggestReg4CallAddr(CallMI, LRI, RCList); + suggestReg4CallAddr(CallMI, LRI); - // First color the return value of the call instruction. The return value - // will be in %o0 if the value is an integer type, or in %f0 if the - // value is a float type. - - // the return value cannot have a LR in machine instruction since it is - // only defined by the call instruction - - // if type is not void, create a new live range and set its - // register class and add to LRI - - const Value *RetVal = argDesc->getReturnValue(); - - if (RetVal) { - assert ((!LRI.getLiveRangeForValue(RetVal)) && - "LR for ret Value of call already definded!"); - - // create a new LR for the return value - LiveRange *RetValLR = new LiveRange(); - RetValLR->insert(RetVal); - unsigned RegClassID = getRegClassIDOfValue(RetVal); - RetValLR->setRegClass(RCList[RegClassID]); - LRI.addLRToMap(RetVal, RetValLR); - - // now suggest a register depending on the register class of ret arg + // First color the return value of the call instruction, if any. + // The return value will be in %o0 if the value is an integer type, + // or in %f0 if the value is a float type. + // + if (const Value *RetVal = argDesc->getReturnValue()) { + LiveRange *RetValLR = LRI.getLiveRangeForValue(RetVal); + assert(RetValLR && "No LR for return Value of call!"); + + unsigned RegClassID = RetValLR->getRegClass()->getID(); + // now suggest a register depending on the register class of ret arg if( RegClassID == IntRegClassID ) RetValLR->setSuggestedColor(SparcIntRegClass::o0); else if (RegClassID == FloatRegClassID ) @@ -605,7 +588,6 @@ else assert( 0 && "Unknown reg class for return value of call\n"); } - // Now suggest colors for arguments (operands) of the call instruction. // Colors are suggested only if the arg number is smaller than the // the number of registers allocated for argument passing. @@ -620,17 +602,12 @@ // get the LR of call operand (parameter) LiveRange *const LR = LRI.getLiveRangeForValue(CallArg); - - // not possible to have a null LR since all args (even consts) - // must be defined before - if (!LR) { - cerr << " ERROR: In call instr, no LR for arg: " << RAV(CallArg) << "\n"; - assert(0 && "NO LR for call arg"); - } - + assert (LR && "Must have a LR for all arguments since " + "all args (even consts) must be defined before"); + unsigned regType = getRegType( LR ); unsigned regClassIDOfArgReg = MAXINT; // reg class of chosen reg (unused) - + // Choose a register for this arg depending on whether it is // an INT or FP value. Here we ignore whether or not it is a // varargs calls, because FP arguments will be explicitly copied From vadve at cs.uiuc.edu Sat Sep 28 12:01:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 12:01:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstr.def Message-ID: <200209281700.MAA17240@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstr.def updated: 1.10 -> 1.11 --- Log message: Return address register should be marked as "result" for the JMPL instruction since it is defined by the instruction. --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcInstr.def diff -u llvm/lib/Target/Sparc/SparcInstr.def:1.10 llvm/lib/Target/Sparc/SparcInstr.def:1.11 --- llvm/lib/Target/Sparc/SparcInstr.def:1.10 Mon Jul 8 18:25:17 2002 +++ llvm/lib/Target/Sparc/SparcInstr.def Sat Sep 28 12:00:15 2002 @@ -426,11 +426,12 @@ I(STFSR, "st", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG) I(STXFSR, "stx", 3, -1, B12, true , 0, 0, SPARC_ST, M_FLOAT_FLAG | M_STORE_FLAG) -// Call, Return and "Jump and link". +// 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, -1, B12, true , 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_CALL_FLAG ) -I(JMPLRET, "jmpl", 3, -1, B12, true , 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_RET_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) // SAVE and restore instructions From vadve at cs.uiuc.edu Sat Sep 28 12:03:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 12:03:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Message-ID: <200209281702.MAA17261@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: PhyRegAlloc.cpp updated: 1.76 -> 1.77 --- Log message: Fixed incorrect assertion: spill code for function ptr should be handled like normal operands, not like other call arguments. --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.76 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.77 --- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.76 Sun Sep 15 02:07:55 2002 +++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp Sat Sep 28 12:02:40 2002 @@ -592,9 +592,10 @@ const BasicBlock *BB, const unsigned OpNum) { - assert(! TM.getInstrInfo().isCall(MInst->getOpCode()) && - (! TM.getInstrInfo().isReturn(MInst->getOpCode())) && - "Arg of a call/ret must be handled elsewhere"); + assert((! TM.getInstrInfo().isCall(MInst->getOpCode()) || OpNum == 0) && + "Outgoing arg of a call must be handled elsewhere (func arg ok)"); + assert(! TM.getInstrInfo().isReturn(MInst->getOpCode()) && + "Return value of a ret must be handled elsewhere"); MachineOperand& Op = MInst->getOperand(OpNum); bool isDef = MInst->operandIsDefined(OpNum); From vadve at cs.uiuc.edu Sat Sep 28 12:04:02 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 12:04:02 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSelection/MachineInstrAnnot.cpp Message-ID: <200209281703.MAA17274@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSelection: MachineInstrAnnot.cpp updated: 1.2 -> 1.3 --- Log message: Fixed method getReturnValue(): it should return NULL if the callee does not return a value. --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSelection/MachineInstrAnnot.cpp diff -u llvm/lib/CodeGen/InstrSelection/MachineInstrAnnot.cpp:1.2 llvm/lib/CodeGen/InstrSelection/MachineInstrAnnot.cpp:1.3 --- llvm/lib/CodeGen/InstrSelection/MachineInstrAnnot.cpp:1.2 Fri Aug 9 15:07:57 2002 +++ llvm/lib/CodeGen/InstrSelection/MachineInstrAnnot.cpp Sat Sep 28 12:03:40 2002 @@ -30,3 +30,10 @@ for (unsigned int i=1; i < numArgs; ++i) argInfoVec.push_back(CallArgInfo(callInstr->getOperand(i))); } + + +const CallInst* +CallArgsDescriptor::getReturnValue() const +{ + return (callInstr->getType() == Type::VoidTy? NULL : callInstr); +} From vadve at cs.uiuc.edu Sat Sep 28 12:04:06 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 12:04:06 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstrAnnot.h Message-ID: <200209281703.MAA17287@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstrAnnot.h updated: 1.5 -> 1.6 --- Log message: Fixed method getReturnValue(): it should return NULL if the callee does not return a value. --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineInstrAnnot.h diff -u llvm/include/llvm/CodeGen/MachineInstrAnnot.h:1.5 llvm/include/llvm/CodeGen/MachineInstrAnnot.h:1.6 --- llvm/include/llvm/CodeGen/MachineInstrAnnot.h:1.5 Fri Aug 9 15:07:36 2002 +++ llvm/include/llvm/CodeGen/MachineInstrAnnot.h Sat Sep 28 12:03:54 2002 @@ -68,12 +68,12 @@ unsigned int getNumArgs() const { return argInfoVec.size(); } CallArgInfo& getArgInfo(unsigned int op) { assert(op < argInfoVec.size()); return argInfoVec[op]; } - const CallInst* getReturnValue() const { return callInstr; } + const CallInst* getReturnValue() const; const Value* getIndirectFuncPtr() const { return funcPtr; } TmpInstruction* getReturnAddrReg() const { return retAddrReg; } bool isVarArgsFunc() const { return isVarArgs; } bool hasNoPrototype() const { return noPrototype; } - + // Annotation mechanism to annotate a MachineInstr with the descriptor. // This is not demand-driven because annotations can only be created // at restricted points during code generation. From vadve at cs.uiuc.edu Sat Sep 28 12:06:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 12:06:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp Message-ID: <200209281705.MAA17300@psmith.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/RegAlloc: LiveRangeInfo.cpp updated: 1.28 -> 1.29 --- Log message: Live ranges for Return value and return address of a Call are now created here, simply by handling all implicit operands (which should have been done anyway). --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp diff -u llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.28 llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.29 --- llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp:1.28 Thu Sep 19 19:45:47 2002 +++ llvm/lib/CodeGen/RegAlloc/LiveRangeInfo.cpp Sat Sep 28 12:05:22 2002 @@ -78,6 +78,48 @@ } +//--------------------------------------------------------------------------- +// Method for creating a single live range for a definition. +// The definition must be represented by a virtual register (a Value). +// Note: this function does *not* check that no live range exists for def. +//--------------------------------------------------------------------------- + +LiveRange* +LiveRangeInfo::createNewLiveRange(const Value* Def, bool isCC /* = false*/) +{ + LiveRange* DefRange = new LiveRange(); // Create a new live range, + DefRange->insert(Def); // add Def to it, + LiveRangeMap[Def] = DefRange; // and update the map. + + // set the register class of the new live range + DefRange->setRegClass(RegClassList[MRI.getRegClassIDOfValue(Def, isCC)]); + + if (DEBUG_RA >= RA_DEBUG_LiveRanges) { + cerr << " Creating a LR for def "; + if (isCC) cerr << " (CC Register!)"; + cerr << " : " << RAV(Def) << "\n"; + } + return DefRange; +} + + +LiveRange* +LiveRangeInfo::createOrAddToLiveRange(const Value* Def, bool isCC /* = false*/) +{ + LiveRange *DefRange = LiveRangeMap[Def]; + + // check if the LR is already there (because of multiple defs) + if (!DefRange) { + DefRange = this->createNewLiveRange(Def, isCC); + } else { // live range already exists + DefRange->insert(Def); // add the operand to the range + LiveRangeMap[Def] = DefRange; // make operand point to merged set + if (DEBUG_RA >= RA_DEBUG_LiveRanges) + cerr << " Added to existing LR for def: " << RAV(Def) << "\n"; + } + return DefRange; +} + //--------------------------------------------------------------------------- // Method for constructing all live ranges in a function. It creates live @@ -91,128 +133,66 @@ // first find the live ranges for all incoming args of the function since // those LRs start from the start of the function - for (Function::const_aiterator AI = Meth->abegin(); AI != Meth->aend(); ++AI){ - LiveRange *ArgRange = new LiveRange(); // creates a new LR and - ArgRange->insert(AI); // add the arg (def) to it - LiveRangeMap[AI] = ArgRange; - - // create a temp machine op to find the register class of value - //const MachineOperand Op(MachineOperand::MO_VirtualRegister); - - unsigned rcid = MRI.getRegClassIDOfValue(AI); - ArgRange->setRegClass(RegClassList[rcid]); - - - if( DEBUG_RA >= RA_DEBUG_LiveRanges) - cerr << " Adding LiveRange for argument " << RAV(AI) << "\n"; - } + for (Function::const_aiterator AI = Meth->abegin(); AI != Meth->aend(); ++AI) + this->createNewLiveRange(AI, /*isCC*/ false); // Now suggest hardware registers for these function args MRI.suggestRegs4MethodArgs(Meth, *this); - - // Now find speical LLVM instructions (CALL, RET) and LRs in machine - // instructions. + // Now create LRs for machine instructions. A new LR will be created + // only for defs in the machine instr since, we assume that all Values are + // defined before they are used. However, there can be multiple defs for + // the same Value in machine instructions. + // + // Also, find CALL and RETURN instructions, which need extra work. // for (Function::const_iterator BBI=Meth->begin(); BBI != Meth->end(); ++BBI){ - // Now find all LRs for machine the instructions. A new LR will be created - // only for defs in the machine instr since, we assume that all Values are - // defined before they are used. However, there can be multiple defs for - // the same Value in machine instructions. - - // get the iterator for machine instructions + // get the vector of machine instructions for this basic block. MachineCodeForBasicBlock& MIVec = MachineCodeForBasicBlock::get(BBI); - + // iterate over all the machine instructions in BB for(MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin(); MInstIterator != MIVec.end(); ++MInstIterator) { MachineInstr *MInst = *MInstIterator; - // Now if the machine instruction is a call/return instruction, - // add it to CallRetInstrList for processing its implicit operands - + // If the machine instruction is a call/return instruction, add it to + // CallRetInstrList for processing its args, ret value, and ret addr. + // if(TM.getInstrInfo().isReturn(MInst->getOpCode()) || TM.getInstrInfo().isCall(MInst->getOpCode())) CallRetInstrList.push_back( MInst ); - - // iterate over MI operands to find defs + // iterate over explicit MI operands and create a new LR + // for each operand that is defined by the instruction for (MachineInstr::val_op_iterator OpI = MInst->begin(), - OpE = MInst->end(); OpI != OpE; ++OpI) { - if(DEBUG_RA >= RA_DEBUG_LiveRanges) { - MachineOperand::MachineOperandType OpTyp = - OpI.getMachineOperand().getOperandType(); - - if (OpTyp == MachineOperand::MO_CCRegister) - cerr << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:" - << RAV(OpI.getMachineOperand().getVRegValue()) << "\n"; - } - - // create a new LR iff this operand is a def + OpE = MInst->end(); OpI != OpE; ++OpI) if (OpI.isDef()) { const Value *Def = *OpI; + bool isCC = (OpI.getMachineOperand().getOperandType() + == MachineOperand::MO_CCRegister); + this->createOrAddToLiveRange(Def, isCC); + } - // Only instruction values are accepted for live ranges here - if (Def->getValueType() != Value::InstructionVal ) { - cerr << "\n**%%Error: Def is not an instruction val. Def=" - << RAV(Def) << "\n"; - continue; - } - - LiveRange *DefRange = LiveRangeMap[Def]; - - // see LR already there (because of multiple defs) - if( !DefRange) { // if it is not in LiveRangeMap - DefRange = new LiveRange(); // creates a new live range and - DefRange->insert(Def); // add the instruction (def) to it - LiveRangeMap[ Def ] = DefRange; // update the map - - if (DEBUG_RA >= RA_DEBUG_LiveRanges) - cerr << " creating a LR for def: " << RAV(Def) << "\n"; - - // set the register class of the new live range - //assert( RegClassList.size() ); - MachineOperand::MachineOperandType OpTy = - OpI.getMachineOperand().getOperandType(); - - bool isCC = ( OpTy == MachineOperand::MO_CCRegister); - unsigned rcid = MRI.getRegClassIDOfValue( - OpI.getMachineOperand().getVRegValue(), isCC ); - - - if (isCC && DEBUG_RA >= RA_DEBUG_LiveRanges) - cerr << "\a**created a LR for a CC reg:" - << RAV(OpI.getMachineOperand().getVRegValue()); - - DefRange->setRegClass(RegClassList[rcid]); - } else { - DefRange->insert(Def); // add the opearand to def range - // update the map - Operand points - // to the merged set - LiveRangeMap[Def] = DefRange; - - if (DEBUG_RA >= RA_DEBUG_LiveRanges) - cerr << " Added to existing LR for def: " << RAV(Def) << "\n"; - } - - } // if isDef() - - } // for all opereands in machine instructions + // iterate over implicit MI operands and create a new LR + // for each operand that is defined by the instruction + for (unsigned i = 0; i < MInst->getNumImplicitRefs(); ++i) + if (MInst->implicitRefIsDefined(i)) { + const Value *Def = MInst->getImplicitRef(i); + this->createOrAddToLiveRange(Def, /*isCC*/ false); + } } // for all machine instructions in the BB } // for all BBs in function - // Now we have to suggest clors for call and return arg live ranges. // Also, if there are implicit defs (e.g., retun value of a call inst) // they must be added to the live range list - + // suggestRegs4CallRets(); if( DEBUG_RA >= RA_DEBUG_LiveRanges) cerr << "Initial Live Ranges constructed!\n"; - } @@ -236,7 +216,7 @@ MRI.suggestReg4RetValue( MInst, *this); else if( (TM.getInstrInfo()).isCall( OpCode ) ) - MRI.suggestRegs4CallArgs( MInst, *this, RegClassList ); + MRI.suggestRegs4CallArgs( MInst, *this); else assert( 0 && "Non call/ret instr in CallRetInstrList" ); From vadve at cs.uiuc.edu Sat Sep 28 12:06:05 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 12:06:05 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/LiveRangeInfo.h Message-ID: <200209281705.MAA17314@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveRangeInfo.h updated: 1.12 -> 1.13 --- Log message: Added a couple of helper methods for live range construction. --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/LiveRangeInfo.h diff -u llvm/include/llvm/CodeGen/LiveRangeInfo.h:1.12 llvm/include/llvm/CodeGen/LiveRangeInfo.h:1.13 --- llvm/include/llvm/CodeGen/LiveRangeInfo.h:1.12 Wed Jul 24 16:21:28 2002 +++ llvm/include/llvm/CodeGen/LiveRangeInfo.h Sat Sep 28 12:05:43 2002 @@ -58,13 +58,21 @@ //------------ Private methods (see LiveRangeInfo.cpp for description)------- - void unionAndUpdateLRs(LiveRange *L1, LiveRange *L2); + LiveRange* createNewLiveRange (const Value* Def, + bool isCC = false); - void addInterference(const Instruction *Inst, const ValueSet *LVSet); + LiveRange* createOrAddToLiveRange (const Value* Def, + bool isCC = false); + + void unionAndUpdateLRs (LiveRange *L1, + LiveRange *L2); + + void addInterference (const Instruction *Inst, + const ValueSet *LVSet); - void suggestRegs4CallRets(); + void suggestRegs4CallRets (); - const Function *getMethod() { return Meth; } + const Function *getMethod () const { return Meth; } public: @@ -79,15 +87,6 @@ // Main entry point for live range construction // void constructLiveRanges(); - - // This method is used to add a live range created elsewhere (e.g., - // in machine specific code) to the common live range map - // - inline void addLRToMap(const Value *Val, LiveRange *LR) { - assert(Val && LR && "Val/LR is NULL!\n"); - assert((!LiveRangeMap[Val]) && "LR already set in map"); - LiveRangeMap[Val] = LR; - } // return the common live range map for this method // From vadve at cs.uiuc.edu Sat Sep 28 13:10:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Sep 28 13:10:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/LLC/badFoldGEP.ll Message-ID: <200209281809.NAA17577@psmith.cs.uiuc.edu> Changes in directory llvm/test/Regression/LLC: badFoldGEP.ll added (r1.1) --- Log message: Regression test for llc bug that was folding two getelementptrs illegally. --- Diffs of the changes: From vadve at cs.uiuc.edu Sun Sep 29 06:53:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Sep 29 06:53:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/Makefile Message-ID: <200209291152.GAA07395@choi.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: Makefile updated: 1.8 -> 1.9 --- Log message: Convert DIRS to PARALLEL_DIRS. They can be built independently. --- Diffs of the changes: Index: llvm/lib/CodeGen/Makefile diff -u llvm/lib/CodeGen/Makefile:1.8 llvm/lib/CodeGen/Makefile:1.9 --- llvm/lib/CodeGen/Makefile:1.8 Thu Sep 19 19:53:53 2002 +++ llvm/lib/CodeGen/Makefile Sun Sep 29 06:52:04 2002 @@ -1,4 +1,4 @@ LEVEL = ../.. -DIRS = PreOpts InstrSelection InstrSched RegAlloc PostOpts Mapping +PARALLEL_DIRS = PreOpts InstrSelection InstrSched RegAlloc PostOpts Mapping include $(LEVEL)/Makefile.common From vadve at cs.uiuc.edu Sun Sep 29 06:53:05 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Sep 29 06:53:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Makefile Message-ID: <200209291152.GAA07425@choi.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: Makefile updated: 1.6 -> 1.7 --- Log message: Convert DIRS to PARALLEL_DIRS. They can be built independently. --- Diffs of the changes: Index: llvm/lib/Transforms/Makefile diff -u llvm/lib/Transforms/Makefile:1.6 llvm/lib/Transforms/Makefile:1.7 --- llvm/lib/Transforms/Makefile:1.6 Tue Jul 23 12:52:35 2002 +++ llvm/lib/Transforms/Makefile Sun Sep 29 06:52:14 2002 @@ -1,5 +1,5 @@ LEVEL = ../.. -DIRS = Utils Instrumentation Scalar IPO +PARALLEL_DIRS = Utils Instrumentation Scalar IPO LIBRARYNAME = transforms BUILD_ARCHIVE = 1 From jstanley at cs.uiuc.edu Sun Sep 29 12:32:01 2002 From: jstanley at cs.uiuc.edu (Joel Stanley) Date: Sun Sep 29 12:32:01 2002 Subject: [llvm-commits] CVS: llvm/www/docs/ProgrammersManual.html Message-ID: <200209291731.MAA03972@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: ProgrammersManual.html updated: 1.31 -> 1.32 --- Log message: Fixed errors in ReplaceInstWithValue/ReplaceInstWithInst examples. --- Diffs of the changes: Index: llvm/www/docs/ProgrammersManual.html diff -u llvm/www/docs/ProgrammersManual.html:1.31 llvm/www/docs/ProgrammersManual.html:1.32 --- llvm/www/docs/ProgrammersManual.html:1.31 Sun Sep 22 16:25:12 2002 +++ llvm/www/docs/ProgrammersManual.html Sun Sep 29 12:31:54 2002 @@ -882,7 +882,8 @@
 AllocaInst* instToReplace = ...;
-ReplaceInstWithValue(*instToReplace->getParent(), instToReplace,
+BasicBlock::iterator ii(instToReplace);
+ReplaceInstWithValue(instToReplace->getParent()->getInstList(), ii,
                      Constant::getNullValue(PointerType::get(Type::IntTy)));
 
@@ -894,7 +895,8 @@
 AllocaInst* instToReplace = ...;
-ReplaceInstWithInst(*instToReplace->getParent(), instToReplace,
+BasicBlock::iterator ii(instToReplace);
+ReplaceInstWithInst(instToReplace->getParent()->getInstList(), ii,
                     new AllocaInst(Type::IntTy, 0, "ptrToReplacedInt");
 
@@ -1758,6 +1760,6 @@ Chris Lattner -Last modified: Sun Sep 22 14:38:05 CDT 2002 +Last modified: Sun Sep 29 12:31:23 CDT 2002 From lattner at cs.uiuc.edu Sun Sep 29 16:38:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 16:38:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200209292137.QAA15854@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.25 -> 1.26 --- Log message: Simplify code a bit, add an assertion --- Diffs of the changes: Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.25 llvm/include/llvm/Analysis/Dominators.h:1.26 --- llvm/include/llvm/Analysis/Dominators.h:1.25 Thu Sep 26 11:14:37 2002 +++ llvm/include/llvm/Analysis/Dominators.h Sun Sep 29 16:37:08 2002 @@ -296,9 +296,8 @@ /// Node *createNewNode(BasicBlock *BB, Node *IDomNode) { assert(getNode(BB) == 0 && "Block already in dominator tree!"); - Node *New = Nodes[BB] = new Node(BB, IDomNode); - if (IDomNode) IDomNode->addChild(New); - return New; + assert(IDomNode && "Not immediate dominator specified for block!"); + return Nodes[BB] = IDomNode->addChild(new Node(BB, IDomNode)); } /// changeImmediateDominator - This method is used to update the dominator From lattner at cs.uiuc.edu Sun Sep 29 16:43:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 16:43:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopPreheaders.cpp Message-ID: <200209292141.QAA15964@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopPreheaders.cpp updated: 1.2 -> 1.3 --- Log message: Fix major bugs in dominator set & tree information updating --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LoopPreheaders.cpp diff -u llvm/lib/Transforms/Scalar/LoopPreheaders.cpp:1.2 llvm/lib/Transforms/Scalar/LoopPreheaders.cpp:1.3 --- llvm/lib/Transforms/Scalar/LoopPreheaders.cpp:1.2 Thu Sep 26 11:37:37 2002 +++ llvm/lib/Transforms/Scalar/LoopPreheaders.cpp Sun Sep 29 16:41:38 2002 @@ -153,14 +153,18 @@ // Update dominator information if it is around... if (DominatorSet *DS = getAnalysisToUpdate()) { - // We need to add information about the fact that NewBB dominates Header. - DS->addDominator(Header, NewBB); - // The blocks that dominate NewBB are the blocks that dominate Header, // minus Header, plus NewBB. DominatorSet::DomSetType DomSet = DS->getDominators(Header); + DomSet.insert(NewBB); // We dominate ourself DomSet.erase(Header); // Header does not dominate us... DS->addBasicBlock(NewBB, DomSet); + + // The newly created basic block dominates all nodes dominated by Header. + for (Function::iterator I = Header->getParent()->begin(), + E = Header->getParent()->end(); I != E; ++I) + if (DS->dominates(Header, I)) + DS->addDominator(I, NewBB); } // Update immediate dominator information if we have it... @@ -178,11 +182,10 @@ // the old header. // DominatorTree::Node *HeaderNode = DT->getNode(Header); - DominatorTree::Node *PHNode = DT->createNewNode(NewBB, HeaderNode); + DominatorTree::Node *PHNode = DT->createNewNode(NewBB, + HeaderNode->getIDom()); // Change the header node so that PNHode is the new immediate dominator DT->changeImmediateDominator(HeaderNode, PHNode); } } - - From lattner at cs.uiuc.edu Sun Sep 29 16:44:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 16:44:01 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200209292142.QAA15977@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.39 -> 1.40 --- Log message: Improve printing of dominator sets --- Diffs of the changes: Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.39 llvm/lib/VMCore/Dominators.cpp:1.40 --- llvm/lib/VMCore/Dominators.cpp:1.39 Thu Sep 26 11:14:41 2002 +++ llvm/lib/VMCore/Dominators.cpp Sun Sep 29 16:42:42 2002 @@ -114,10 +114,12 @@ } void DominatorSetBase::print(std::ostream &o) const { - for (const_iterator I = begin(), E = end(); I != E; ++I) + for (const_iterator I = begin(), E = end(); I != E; ++I) { o << "=============================--------------------------------\n" - << "\nDominator Set For Basic Block\n" << I->first - << "-------------------------------\n" << I->second << "\n"; + << "\nDominator Set For Basic Block: "; + WriteAsOperand(o, I->first, false); + o << "\n-------------------------------\n" << I->second << "\n"; + } } //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Sun Sep 29 16:44:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 16:44:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200209292143.QAA15989@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.23 -> 1.24 --- Log message: Fix printing of loop information --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.23 llvm/lib/Analysis/LoopInfo.cpp:1.24 --- llvm/lib/Analysis/LoopInfo.cpp:1.23 Thu Sep 26 11:15:54 2002 +++ llvm/lib/Analysis/LoopInfo.cpp Sun Sep 29 16:43:04 2002 @@ -33,8 +33,8 @@ } OS << "\n"; - std::copy(getSubLoops().begin(), getSubLoops().end(), - std::ostream_iterator(OS, "\n")); + for (unsigned i = 0, e = getSubLoops().size(); i != e; ++i) + getSubLoops()[i]->print(OS); } //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Sun Sep 29 16:47:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 16:47:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200209292146.QAA16001@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.16 -> 1.17 --- Log message: Hoist the contents of Loops in depth first order in the dominator tree, rather than in random order. This causes LICM to be DRAMATICALLY more effective. For example, on bzip2.c, it is able to hoist 302 loads and 2380 total instructions, as opposed to 44/338 before. This obviously makes other transformations much more powerful as well! --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.16 llvm/lib/Transforms/Scalar/LICM.cpp:1.17 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.16 Thu Sep 26 14:40:25 2002 +++ llvm/lib/Transforms/Scalar/LICM.cpp Sun Sep 29 16:46:09 2002 @@ -8,6 +8,7 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/iOperators.h" #include "llvm/iMemory.h" #include "llvm/Support/InstVisitor.h" @@ -30,6 +31,7 @@ AU.preservesCFG(); AU.addRequiredID(LoopPreheadersID); AU.addRequired(); + AU.addRequired(); AU.addRequired(); } @@ -43,6 +45,14 @@ /// void visitLoop(Loop *L); + /// HoistRegion - Walk the specified region of the CFG (defined by all + /// blocks dominated by the specified block, and that are in the current + /// loop) in depth first order w.r.t the DominatorTree. This allows us to + /// visit defintions before uses, allowing us to hoist a loop body in one + /// pass without iteration. + /// + void HoistRegion(DominatorTree::Node *N); + /// inCurrentLoop - Little predicate that returns false if the specified /// basic block is in a subloop of the current one, not the current one /// itself. @@ -139,22 +149,42 @@ // their loop, into this loop, so there is no need to process the BODIES of // the subloops). // - for (std::vector::const_iterator - I = L->getBlocks().begin(), E = L->getBlocks().end(); I != E; ++I) - if (inCurrentLoop(*I)) - visit(**I); + // Traverse the body of the loop in depth first order on the dominator tree so + // that we are guaranteed to see definitions before we see uses. This allows + // us to perform the LICM transformation in one pass, without iteration. + // + HoistRegion(getAnalysis()[L->getHeader()]); // Clear out loops state information for the next iteration CurLoop = 0; Preheader = 0; } +/// HoistRegion - Walk the specified region of the CFG (defined by all blocks +/// dominated by the specified block, and that are in the current loop) in depth +/// first order w.r.t the DominatorTree. This allows us to visit defintions +/// before uses, allowing us to hoist a loop body in one pass without iteration. +/// +void LICM::HoistRegion(DominatorTree::Node *N) { + assert(N != 0 && "Null dominator tree node?"); + + // This subregion is not in the loop, it has already been already been hoisted + if (!inCurrentLoop(N->getNode())) + return; + + visit(*N->getNode()); + + const std::vector &Children = N->getChildren(); + for (unsigned i = 0, e = Children.size(); i != e; ++i) + HoistRegion(Children[i]); +} + + /// hoist - When an instruction is found to only use loop invariant operands /// that is safe to hoist, this instruction is called to do the dirty work. /// void LICM::hoist(Instruction &Inst) { - if (Inst.use_empty()) return; // Don't (re) hoist dead instructions! - //cerr << "Hoisting " << Inst; + DEBUG(std::cerr << "LICM hoisting: " << Inst); BasicBlock *Header = CurLoop->getHeader(); From vadve at cs.uiuc.edu Sun Sep 29 16:54:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Sep 29 16:54:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MachineInstrInfo.h Message-ID: <200209292153.QAA14454@choi.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MachineInstrInfo.h updated: 1.21 -> 1.22 --- Log message: Minor change to interface for Create{Zero,Sign}ExtensionsInstructions. --- Diffs of the changes: Index: llvm/include/llvm/Target/MachineInstrInfo.h diff -u llvm/include/llvm/Target/MachineInstrInfo.h:1.21 llvm/include/llvm/Target/MachineInstrInfo.h:1.22 --- llvm/include/llvm/Target/MachineInstrInfo.h:1.21 Thu Sep 19 19:50:44 2002 +++ llvm/include/llvm/Target/MachineInstrInfo.h Sun Sep 29 16:53:31 2002 @@ -334,8 +334,8 @@ virtual void CreateSignExtensionInstructions(const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, std::vector& mvec, MachineCodeForInstruction& mcfi) const=0; @@ -348,8 +348,8 @@ virtual void CreateZeroExtensionInstructions(const TargetMachine& target, Function* F, Value* srcVal, + Value* destVal, unsigned int srcSizeInBits, - Value* dest, std::vector& mvec, MachineCodeForInstruction& mcfi) const=0; }; From lattner at cs.uiuc.edu Sun Sep 29 17:27:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 17:27:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200209292226.RAA16284@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.17 -> 1.18 --- Log message: Fix bug in LICM that caused the previous big win. :( --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.17 llvm/lib/Transforms/Scalar/LICM.cpp:1.18 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.17 Sun Sep 29 16:46:09 2002 +++ llvm/lib/Transforms/Scalar/LICM.cpp Sun Sep 29 17:26:07 2002 @@ -14,6 +14,7 @@ #include "llvm/Support/InstVisitor.h" #include "Support/STLExtras.h" #include "Support/StatisticReporter.h" +#include "llvm/Assembly/Writer.h" #include using std::string; @@ -53,15 +54,15 @@ /// void HoistRegion(DominatorTree::Node *N); - /// inCurrentLoop - Little predicate that returns false if the specified - /// basic block is in a subloop of the current one, not the current one - /// itself. + /// inSubLoop - Little predicate that returns true if the specified basic + /// block is in a subloop of the current one, not the current one itself. /// - bool inCurrentLoop(BasicBlock *BB) { + bool inSubLoop(BasicBlock *BB) { + assert(CurLoop->contains(BB) && "Only valid if BB is IN the loop"); for (unsigned i = 0, e = CurLoop->getSubLoops().size(); i != e; ++i) if (CurLoop->getSubLoops()[i]->contains(BB)) - return false; // A subloop actually contains this block! - return true; + return true; // A subloop actually contains this block! + return false; } /// hoist - When an instruction is found to only use loop invariant operands @@ -168,11 +169,13 @@ void LICM::HoistRegion(DominatorTree::Node *N) { assert(N != 0 && "Null dominator tree node?"); - // This subregion is not in the loop, it has already been already been hoisted - if (!inCurrentLoop(N->getNode())) - return; + // If this subregion is not in the top level loop at all, exit. + if (!CurLoop->contains(N->getNode())) return; - visit(*N->getNode()); + // Only need to hoist the contents of this block if it is not part of a + // subloop (which would already have been hoisted) + if (!inSubLoop(N->getNode())) + visit(*N->getNode()); const std::vector &Children = N->getChildren(); for (unsigned i = 0, e = Children.size(); i != e; ++i) @@ -184,9 +187,9 @@ /// that is safe to hoist, this instruction is called to do the dirty work. /// void LICM::hoist(Instruction &Inst) { - DEBUG(std::cerr << "LICM hoisting: " << Inst); - - BasicBlock *Header = CurLoop->getHeader(); + DEBUG(std::cerr << "LICM hoisting to"; + WriteAsOperand(std::cerr, Preheader, false); + std::cerr << ": " << Inst); // Remove the instruction from its current basic block... but don't delete the // instruction. From lattner at cs.uiuc.edu Sun Sep 29 17:51:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 17:51:00 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/PassManagerT.h Message-ID: <200209292250.RAA17303@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.29 -> 1.30 --- Log message: Fix a problem that was caused by stale analyses being in CurrentAnalyses --- Diffs of the changes: Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.29 llvm/lib/VMCore/PassManagerT.h:1.30 --- llvm/lib/VMCore/PassManagerT.h:1.29 Wed Sep 25 17:26:52 2002 +++ llvm/lib/VMCore/PassManagerT.h Sun Sep 29 17:50:22 2002 @@ -292,6 +292,19 @@ (Annotable*)M); (*I)->releaseMemory(); } + + // Make sure to remove dead passes from the CurrentAnalyses list... + for (std::map::iterator I = CurrentAnalyses.begin(); + I != CurrentAnalyses.end(); ) { + std::vector::iterator DPI = std::find(DeadPass.begin(), + DeadPass.end(), I->second); + if (DPI != DeadPass.end()) { // This pass is dead now... remove it + std::map::iterator IDead = I++; + CurrentAnalyses.erase(IDead); + } else { + ++I; // Move on to the next element... + } + } } return MadeChanges; } From vadve at cs.uiuc.edu Sun Sep 29 17:56:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Sep 29 17:56:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp Message-ID: <200209292255.RAA21948@choi.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSelection: InstrSelectionSupport.cpp updated: 1.33 -> 1.34 --- Log message: Bug fix in folding getElementPtr instructions: don't fold one into a predecessor if it has a non-zero first index and the predecessor ends with a struct index. --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp diff -u llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.33 llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.34 --- llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp:1.33 Fri Sep 27 09:26:20 2002 +++ llvm/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp Sun Sep 29 17:55:05 2002 @@ -109,8 +109,17 @@ // FoldConstantIndices that does the actual folding. //--------------------------------------------------------------------------- + +// Check for a constant 0. +inline bool +IsZero(Value* idx) +{ + return (idx == ConstantSInt::getNullValue(idx->getType())); +} + static Value* -FoldGetElemChain(InstrTreeNode* ptrNode, vector& chainIdxVec) +FoldGetElemChain(InstrTreeNode* ptrNode, vector& chainIdxVec, + bool lastInstHasLeadingNonZero) { InstructionNode* gepNode = dyn_cast(ptrNode); GetElementPtrInst* gepInst = @@ -124,11 +133,12 @@ // Return NULL if we don't fold any instructions in. Value* ptrVal = NULL; - // Remember if the last instruction had a leading [0] index. - bool hasLeadingZero = false; - // Now chase the chain of getElementInstr instructions, if any. // Check for any non-constant indices and stop there. + // Also, stop if the first index of child is a non-zero array index + // and the last index of the current node is a non-array index: + // in that case, a non-array declared type is being accessed as an array + // which is not type-safe, but could be legal. // InstructionNode* ptrChild = gepNode; while (ptrChild && (ptrChild->getOpLabel() == Instruction::GetElementPtr || @@ -140,6 +150,19 @@ User::op_iterator lastIdx = gepInst->idx_end(); bool allConstantOffsets = true; + // The first index of every GEP must be an array index. + assert((*firstIdx)->getType() == Type::LongTy && + "INTERNAL ERROR: Structure index for a pointer type!"); + + // If the last instruction had a leading non-zero index, + // check if the current one ends with an array index. If not, + // the code is not type-safe and we would create an illegal GEP + // by folding them, so don't fold any more instructions. + // + if (lastInstHasLeadingNonZero) + if (firstIdx != lastIdx && (*(lastIdx-1))->getType() != Type::LongTy) + break; // cannot fold in any preceding getElementPtr instrs. + // Check that all offsets are constant for this instruction for (OI = firstIdx; allConstantOffsets && OI != lastIdx; ++OI) allConstantOffsets = isa(*OI); @@ -148,26 +171,26 @@ { // Get pointer value out of ptrChild. ptrVal = gepInst->getPointerOperand(); - // Check for a leading [0] index, if any. It will be discarded later. - hasLeadingZero = (*firstIdx == - Constant::getNullValue((*firstIdx)->getType())); + // Remember if it has leading zero index: it will be discarded later. + lastInstHasLeadingNonZero = ! IsZero(*firstIdx); // Insert its index vector at the start, skipping any leading [0] chainIdxVec.insert(chainIdxVec.begin(), - firstIdx + hasLeadingZero, lastIdx); + firstIdx + !lastInstHasLeadingNonZero, lastIdx); // Mark the folded node so no code is generated for it. ((InstructionNode*) ptrChild)->markFoldedIntoParent(); + + // Get the previous GEP instruction and continue trying to fold + ptrChild = dyn_cast(ptrChild->leftChild()); } - else // cannot fold this getElementPtr instr. or any further ones + else // cannot fold this getElementPtr instr. or any preceding ones break; - - ptrChild = dyn_cast(ptrChild->leftChild()); } // If the first getElementPtr instruction had a leading [0], add it back. // Note that this instruction is the *last* one successfully folded above. - if (ptrVal && hasLeadingZero) + if (ptrVal && ! lastInstHasLeadingNonZero) chainIdxVec.insert(chainIdxVec.begin(), ConstantSInt::get(Type::LongTy,0)); return ptrVal; @@ -191,14 +214,6 @@ // Returns true/false in allConstantIndices if all indices are/aren't const. //--------------------------------------------------------------------------- - -// Check for a constant (uint) 0. -inline bool -IsZero(Value* idx) -{ - return (isa(idx) && cast(idx)->isNullValue()); -} - Value* GetMemInstArgs(const InstructionNode* memInstrNode, vector& idxVec, @@ -206,6 +221,7 @@ { allConstantIndices = true; Instruction* memInst = memInstrNode->getInstruction(); + assert(idxVec.size() == 0 && "Need empty vector to return indices"); // If there is a GetElemPtr instruction to fold in to this instr, // it must be in the left child for Load and GetElemPtr, and in the @@ -217,12 +233,12 @@ // Default pointer is the one from the current instruction. Value* ptrVal = ptrChild->getValue(); - // GEP is the only indexed memory instruction. gepI is used below. + // GEP is the only indexed memory instruction. Extract its index vector. + // Also, if all indices are constant and first index is zero, try to fold + // in preceding GEPs with all constant indices. GetElementPtrInst* gepI = dyn_cast(memInst); - - // If memInst is a GEP, check if all indices are constant for this instruction if (gepI) - for (User::op_iterator OI=gepI->idx_begin(), OE=gepI->idx_end(); + for (User::op_iterator OI=gepI->idx_begin(), OE=gepI->idx_end(); allConstantIndices && OI != OE; ++OI) if (! isa(*OI)) allConstantIndices = false; // note: this also terminates loop! @@ -230,18 +246,20 @@ // If we have only constant indices, fold chains of constant indices // in this and any preceding GetElemPtr instructions. bool foldedGEPs = false; + bool leadingNonZeroIdx = gepI && ! IsZero(*gepI->idx_begin()); if (allConstantIndices) - if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec)) + if (Value* newPtr = FoldGetElemChain(ptrChild, idxVec, leadingNonZeroIdx)) { ptrVal = newPtr; foldedGEPs = true; - assert((!gepI || IsZero(*gepI->idx_begin())) && "1st index not 0"); } // Append the index vector of the current instruction, if any. // Skip the leading [0] index if preceding GEPs were folded into this. if (gepI) - idxVec.insert(idxVec.end(), gepI->idx_begin() +foldedGEPs, gepI->idx_end()); + idxVec.insert(idxVec.end(), + gepI->idx_begin() + (foldedGEPs && !leadingNonZeroIdx), + gepI->idx_end()); return ptrVal; } From vadve at cs.uiuc.edu Sun Sep 29 17:56:05 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Sep 29 17:56:05 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/InstrSelectionSupport.h Message-ID: <200209292255.RAA22048@choi.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: InstrSelectionSupport.h updated: 1.13 -> 1.14 --- Log message: Added several more helper functions for construction MachineInstrs. --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/InstrSelectionSupport.h diff -u llvm/include/llvm/CodeGen/InstrSelectionSupport.h:1.13 llvm/include/llvm/CodeGen/InstrSelectionSupport.h:1.14 --- llvm/include/llvm/CodeGen/InstrSelectionSupport.h:1.13 Mon Sep 16 10:58:34 2002 +++ llvm/include/llvm/CodeGen/InstrSelectionSupport.h Sun Sep 29 17:55:45 2002 @@ -114,6 +114,32 @@ } inline MachineInstr* +Create1OperandInstr_UImmed(MachineOpCode opCode, unsigned int unextendedImmed) +{ + MachineInstr* M = new MachineInstr(opCode); + M->SetMachineOperandConst(0, MachineOperand::MO_UnextendedImmed, + unextendedImmed); + return M; +} + +inline MachineInstr* +Create1OperandInstr_SImmed(MachineOpCode opCode, int signExtendedImmed) +{ + MachineInstr* M = new MachineInstr(opCode); + M->SetMachineOperandConst(0, MachineOperand::MO_SignExtendedImmed, + signExtendedImmed); + return M; +} + +inline MachineInstr* +Create1OperandInstr_Addr(MachineOpCode opCode, Value* label) +{ + MachineInstr* M = new MachineInstr(opCode); + M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp, label); + return M; +} + +inline MachineInstr* Create2OperandInstr(MachineOpCode opCode, Value* argVal1, Value* argVal2) { MachineInstr* M = new MachineInstr(opCode); From lattner at cs.uiuc.edu Sun Sep 29 18:00:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 18:00:01 2002 Subject: [llvm-commits] CVS: llvm/test/Makefile.tests Message-ID: <200209292258.RAA17488@apoc.cs.uiuc.edu> Changes in directory llvm/test: Makefile.tests updated: 1.44 -> 1.45 --- Log message: Enable buidling of programs on Linux again --- Diffs of the changes: Index: llvm/test/Makefile.tests diff -u llvm/test/Makefile.tests:1.44 llvm/test/Makefile.tests:1.45 --- llvm/test/Makefile.tests:1.44 Thu Sep 19 16:46:03 2002 +++ llvm/test/Makefile.tests Sun Sep 29 17:58:51 2002 @@ -42,7 +42,7 @@ NATGCC = /usr/dcs/software/supported/bin/gcc CP = /bin/cp -f -ifndef DISABLE_LLC +ifndef DISABLE_LLC_DIFFS CC = /opt/SUNWspro/bin/cc AS = /opt/SUNWspro/bin/cc DIS = /usr/ccs/bin/dis From lattner at cs.uiuc.edu Sun Sep 29 18:01:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Sep 29 18:01:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200209292259.RAA17773@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.24 -> 1.25 --- Log message: Minor tweak --- Diffs of the changes: Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.24 llvm/lib/Analysis/LoopInfo.cpp:1.25 --- llvm/lib/Analysis/LoopInfo.cpp:1.24 Sun Sep 29 16:43:04 2002 +++ llvm/lib/Analysis/LoopInfo.cpp Sun Sep 29 17:59:29 2002 @@ -147,8 +147,9 @@ BasicBlock *Header = getHeader(); for (pred_iterator PI = pred_begin(Header), PE = pred_end(Header); PI != PE; ++PI) - if (!contains(*PI)) { // If the block is not in the loop... - if (Out) return 0; // Multiple predecessors outside the loop + if (!contains(*PI)) { // If the block is not in the loop... + if (Out && Out != *PI) + return 0; // Multiple predecessors outside the loop Out = *PI; }