From lattner at cs.uiuc.edu Mon Mar 8 00:11:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 00:11:06 2004 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200403080610.AAA04161@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.156 -> 1.157 --- Log message: Eliminate a REALLY HORRIBLE API: mutateReferences, which is gross gross gross. --- Diffs of the changes: (+7 -5) Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.156 llvm/lib/AsmParser/llvmAsmParser.y:1.157 --- llvm/lib/AsmParser/llvmAsmParser.y:1.156 Mon Feb 9 15:03:38 2004 +++ llvm/lib/AsmParser/llvmAsmParser.y Mon Mar 8 00:09:57 2004 @@ -73,7 +73,7 @@ // here. This is used for forward references of ConstantPointerRefs. // typedef std::map, GlobalVariable*> GlobalRefsType; + ValID>, GlobalValue*> GlobalRefsType; GlobalRefsType GlobalRefs; void ModuleDone() { @@ -114,7 +114,7 @@ GlobalRefs.find(std::make_pair(GV->getType(), D)); if (I != GlobalRefs.end()) { - GlobalVariable *OldGV = I->second; // Get the placeholder... + GlobalValue *OldGV = I->second; // Get the placeholder... I->first.second.destroy(); // Free string memory if necessary // Loop over all of the uses of the GlobalValue. The only thing they are @@ -125,12 +125,14 @@ // Change the const pool reference to point to the real global variable // now. This should drop a use from the OldGV. - CPR->mutateReferences(OldGV, GV); + CPR->replaceUsesOfWithOnConstant(OldGV, GV); assert(OldGV->use_empty() && "All uses should be gone now!"); // Remove OldGV from the module... - CurrentModule->getGlobalList().remove(OldGV); - delete OldGV; // Delete the old placeholder + if (GlobalVariable *GVar = dyn_cast(OldGV)) + CurrentModule->getGlobalList().erase(GVar); + else + CurrentModule->getFunctionList().erase(cast(OldGV)); // Remove the map entry for the global now that it has been created... GlobalRefs.erase(I); From lattner at cs.uiuc.edu Mon Mar 8 00:11:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 00:11:11 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Message-ID: <200403080610.AAA04178@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.12 -> 1.13 --- Log message: remove *THANKFULLY* dead method --- Diffs of the changes: (+0 -6) Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.12 llvm/include/llvm/Constant.h:1.13 --- llvm/include/llvm/Constant.h:1.12 Tue Nov 11 16:41:29 2003 +++ llvm/include/llvm/Constant.h Mon Mar 8 00:10:32 2004 @@ -85,12 +85,6 @@ "implemented for all constants that have operands!"); assert(0 && "Constants that do not have operands cannot be using 'From'!"); } - - // WARNING: Only to be used by Bytecode & Assembly Parsers! USER CODE SHOULD - // NOT USE THIS!! - // Returns the number of uses of OldV that were replaced. - unsigned mutateReferences(Value* OldV, Value *NewV); - // END WARNING!! }; } // End llvm namespace From lattner at cs.uiuc.edu Mon Mar 8 00:12:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 00:12:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200403080611.AAA04191@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.80 -> 1.81 --- Log message: Eliminate nightmarish API --- Diffs of the changes: (+0 -23) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.80 llvm/lib/VMCore/Constants.cpp:1.81 --- llvm/lib/VMCore/Constants.cpp:1.80 Mon Feb 16 14:46:13 2004 +++ llvm/lib/VMCore/Constants.cpp Mon Mar 8 00:11:10 2004 @@ -1119,26 +1119,3 @@ const char *ConstantExpr::getOpcodeName() const { return Instruction::getOpcodeName(getOpcode()); } - -unsigned Constant::mutateReferences(Value *OldV, Value *NewV) { - // Uses of constant pointer refs are global values, not constants! - if (ConstantPointerRef *CPR = dyn_cast(this)) { - GlobalValue *NewGV = cast(NewV); - GlobalValue *OldGV = CPR->getValue(); - - assert(OldGV == OldV && "Cannot mutate old value if I'm not using it!"); - Operands[0] = NewGV; - OldGV->getParent()->mutateConstantPointerRef(OldGV, NewGV); - return 1; - } else { - Constant *NewC = cast(NewV); - unsigned NumReplaced = 0; - for (unsigned i = 0, N = getNumOperands(); i != N; ++i) - if (Operands[i] == OldV) { - ++NumReplaced; - Operands[i] = NewC; - } - return NumReplaced; - } -} - From lattner at cs.uiuc.edu Mon Mar 8 00:16:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 00:16:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Module.h Message-ID: <200403080615.AAA06058@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Module.h updated: 1.42 -> 1.43 --- Log message: Remove Module::mutateConstantPointerRef, which is now thankfully dead! --- Diffs of the changes: (+0 -1) Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.42 llvm/include/llvm/Module.h:1.43 --- llvm/include/llvm/Module.h:1.42 Sun Feb 29 19:25:37 2004 +++ llvm/include/llvm/Module.h Mon Mar 8 00:15:33 2004 @@ -77,7 +77,6 @@ // Accessor for the underlying GVRefMap... only through the Constant class... friend class Constant; friend class ConstantPointerRef; - void mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV); ConstantPointerRef *getConstantPointerRef(GlobalValue *GV); void destroyConstantPointerRef(ConstantPointerRef *CPR); From lattner at cs.uiuc.edu Mon Mar 8 00:17:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 00:17:03 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Module.cpp Message-ID: <200403080616.AAA06381@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Module.cpp updated: 1.47 -> 1.48 --- Log message: Remove Module::mutateConstantPointerRef, which is now thankfully dead! This is one small step towards the complete obliteration of ConstantPointerRef's entirely!! Woot! --- Diffs of the changes: (+0 -25) Index: llvm/lib/VMCore/Module.cpp diff -u llvm/lib/VMCore/Module.cpp:1.47 llvm/lib/VMCore/Module.cpp:1.48 --- llvm/lib/VMCore/Module.cpp:1.47 Wed Dec 31 02:43:01 2003 +++ llvm/lib/VMCore/Module.cpp Mon Mar 8 00:16:10 2004 @@ -335,28 +335,3 @@ GVRefMap = 0; } } - -void Module::mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV) { - assert(OldGV != NewGV && "Cannot mutate to the same global!"); - GlobalValueRefMap::iterator I = GVRefMap->Map.find(OldGV); - assert(I != GVRefMap->Map.end() && - "mutateConstantPointerRef; OldGV not in table!"); - ConstantPointerRef *Ref = I->second; - - // Remove the old entry... - GVRefMap->Map.erase(I); - - // Check to see if a CPR already exists for NewGV - I = GVRefMap->Map.lower_bound(NewGV); - - if (I == GVRefMap->Map.end() || I->first != NewGV) { - // Insert the new entry... - GVRefMap->Map.insert(I, std::make_pair(NewGV, Ref)); - } else { - // Otherwise, an entry already exists for the current global value. - // Completely replace the old CPR with the existing one... - Ref->replaceAllUsesWith(I->second); - delete Ref; - } -} - From lattner at cs.uiuc.edu Mon Mar 8 00:18:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 00:18:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2004-03-07-FunctionAddressAlignment.llx Message-ID: <200403080617.AAA06413@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2004-03-07-FunctionAddressAlignment.llx added (r1.1) --- Log message: New testcase for folding in some important situations. The first two come up a lot in the code generated by the C++ front-end for pointers to member functions. See PR166. --- Diffs of the changes: (+15 -0) Index: llvm/test/Regression/Assembler/2004-03-07-FunctionAddressAlignment.llx diff -c /dev/null llvm/test/Regression/Assembler/2004-03-07-FunctionAddressAlignment.llx:1.1 *** /dev/null Mon Mar 8 00:17:25 2004 --- llvm/test/Regression/Assembler/2004-03-07-FunctionAddressAlignment.llx Mon Mar 8 00:17:15 2004 *************** *** 0 **** --- 1,15 ---- + ; RUN: llvm-as < %s | llvm-dis | not grep cast + ; All of these should be eliminable + + + int %foo() { + ret int and (int cast (int()* %foo to int), int 1) + } + + int %foo2() { + ret int and (int 1, int cast (int()* %foo2 to int)) + } + + bool %foo3() { + ret bool cast (bool()* %foo3 to bool) + } From lattner at cs.uiuc.edu Mon Mar 8 00:18:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 00:18:03 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp Message-ID: <200403080617.AAA06426@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.cpp updated: 1.53 -> 1.54 --- Log message: Implement test/Regression/Assembler/2004-03-07-FunctionAddressAlignment.llx --- Diffs of the changes: (+20 -0) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.53 llvm/lib/VMCore/ConstantFolding.cpp:1.54 --- llvm/lib/VMCore/ConstantFolding.cpp:1.53 Sun Feb 22 00:25:38 2004 +++ llvm/lib/VMCore/ConstantFolding.cpp Mon Mar 8 00:17:35 2004 @@ -22,6 +22,7 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/DerivedTypes.h" +#include "llvm/Function.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include using namespace llvm; @@ -523,6 +524,15 @@ const Type *DestTy) { if (V->getType() == DestTy) return (Constant*)V; + // Cast of a global address to boolean is always true. + if (const ConstantPointerRef *CPR = dyn_cast(V)) + if (DestTy == Type::BoolTy) + // FIXME: When we support 'external weak' references, we have to prevent + // this transformation from happening. In the meantime we avoid folding + // any cast of an external symbol. + if (!CPR->getValue()->isExternal()) + return ConstantBool::True; + if (const ConstantExpr *CE = dyn_cast(V)) if (CE->getOpcode() == Instruction::Cast) { Constant *Op = const_cast(CE->getOperand(0)); @@ -873,6 +883,16 @@ if (cast(V2)->isAllOnesValue()) return const_cast(V1); // X & -1 == X if (V2->isNullValue()) return const_cast(V2); // X & 0 == 0 + if (CE1->getOpcode() == Instruction::Cast && + isa(CE1->getOperand(0))) { + ConstantPointerRef *CPR =cast(CE1->getOperand(0)); + + // Functions are at least 4-byte aligned. If and'ing the address of a + // function with a constant < 4, fold it to zero. + if (const ConstantInt *CI = dyn_cast(V2)) + if (CI->getRawValue() < 4 && isa(CPR->getValue())) + return Constant::getNullValue(CI->getType()); + } break; case Instruction::Or: if (V2->isNullValue()) return const_cast(V1); // X | 0 == X From criswell at cs.uiuc.edu Mon Mar 8 09:11:05 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Mar 8 09:11:05 2004 Subject: [llvm-commits] CVS: poolalloc/test/TEST.poolalloc.Makefile Message-ID: <200403081510.JAA10213@choi.cs.uiuc.edu> Changes in directory poolalloc/test: TEST.poolalloc.Makefile updated: 1.22 -> 1.23 --- Log message: Fix comment regarding the heuristic options. --- Diffs of the changes: (+1 -1) Index: poolalloc/test/TEST.poolalloc.Makefile diff -u poolalloc/test/TEST.poolalloc.Makefile:1.22 poolalloc/test/TEST.poolalloc.Makefile:1.23 --- poolalloc/test/TEST.poolalloc.Makefile:1.22 Fri Mar 5 15:36:53 2004 +++ poolalloc/test/TEST.poolalloc.Makefile Mon Mar 8 09:10:04 2004 @@ -10,7 +10,7 @@ EXTRA_PA_FLAGS := -poolalloc-force-simple-pool-init # HEURISTIC can be set to: -# AllPools +# AllNodes ifdef HEURISTIC EXTRA_PA_FLAGS += -poolalloc-heuristic=$(HEURISTIC) endif From lattner at cs.uiuc.edu Mon Mar 8 10:15:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 10:15:01 2004 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200403081614.KAA29075@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.157 -> 1.158 --- Log message: Insert functions into the module promptly, not lazily. This fixes a bug I introduced last night. Note to self: test the *correct* tree... --- Diffs of the changes: (+2 -11) Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.157 llvm/lib/AsmParser/llvmAsmParser.y:1.158 --- llvm/lib/AsmParser/llvmAsmParser.y:1.157 Mon Mar 8 00:09:57 2004 +++ llvm/lib/AsmParser/llvmAsmParser.y Mon Mar 8 10:14:19 2004 @@ -1295,8 +1295,6 @@ // FunctionList : FunctionList Function { $$ = $1; - assert($2->getParent() == 0 && "Function already in module!"); - $1->getFunctionList().push_back($2); CurFun.FunctionDone(); } | FunctionList FunctionProto { @@ -1471,18 +1469,13 @@ if (!CurFun.isDeclare && !Fn->isExternal()) ThrowException("Redefinition of function '" + FunctionName + "'!"); - // If we found a preexisting function prototype, remove it from the - // module, so that we don't get spurious conflicts with global & local - // variables. - // - CurModule.CurrentModule->getFunctionList().remove(Fn); - // Make sure to strip off any argument names so we can't get conflicts... for (Function::aiterator AI = Fn->abegin(), AE = Fn->aend(); AI != AE; ++AI) AI->setName(""); } else { // Not already defined? - Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName); + Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName, + CurModule.CurrentModule); InsertValue(Fn, CurModule.Values); CurModule.DeclareNewGlobalValue(Fn, ValID::create($2)); } @@ -1534,8 +1527,6 @@ FunctionProto : DECLARE { CurFun.isDeclare = true; } FunctionHeaderH { $$ = CurFun.CurrentFunction; - assert($$->getParent() == 0 && "Function already in module!"); - CurModule.CurrentModule->getFunctionList().push_back($$); CurFun.FunctionDone(); }; From lattner at cs.uiuc.edu Mon Mar 8 10:47:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 10:47:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp Message-ID: <200403081646.KAA02615@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: EmitFunctions.cpp updated: 1.16 -> 1.17 --- Log message: finegrainify namespacification --- Diffs of the changes: (+14 -14) Index: llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp diff -u llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp:1.16 llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp:1.17 --- llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp:1.16 Sat Feb 14 22:07:26 2004 +++ llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp Mon Mar 8 10:45:53 2004 @@ -7,7 +7,9 @@ // //===----------------------------------------------------------------------===// // -// This inserts a global constant table with function pointers all along +// This inserts a global constant table with function pointers all along. +// +// NOTE: This pass is used by the reoptimizer only. // //===----------------------------------------------------------------------===// @@ -16,24 +18,24 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" - -namespace llvm { - -enum Color{ - WHITE, - GREY, - BLACK -}; +using namespace llvm; namespace { + enum Color{ + WHITE, + GREY, + BLACK + }; + struct EmitFunctionTable : public Pass { bool run(Module &M); }; - RegisterOpt X("emitfuncs", "Emit a Function Table"); + RegisterOpt + X("emitfuncs", "Emit a function table for the reoptimizer"); } -char doDFS(BasicBlock * node,std::map &color){ +static char doDFS(BasicBlock * node,std::map &color){ color[node] = GREY; for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){ @@ -56,7 +58,7 @@ return 1; } -char hasBackEdge(Function *F){ +static char hasBackEdge(Function *F){ std::map color; return doDFS(F->begin(), color); } @@ -106,5 +108,3 @@ M.getGlobalList().push_back(fnCount); return true; // Always modifies program } - -} // End llvm namespace From criswell at cs.uiuc.edu Mon Mar 8 10:47:07 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Mar 8 10:47:07 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Applications/hbd/Makefile Message-ID: <200403081646.KAA14653@choi.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Applications/hbd: Makefile updated: 1.1 -> 1.2 --- Log message: Specify full pathname of the input file. --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/MultiSource/Applications/hbd/Makefile diff -u llvm/test/Programs/MultiSource/Applications/hbd/Makefile:1.1 llvm/test/Programs/MultiSource/Applications/hbd/Makefile:1.2 --- llvm/test/Programs/MultiSource/Applications/hbd/Makefile:1.1 Fri Feb 27 12:06:47 2004 +++ llvm/test/Programs/MultiSource/Applications/hbd/Makefile Mon Mar 8 10:46:22 2004 @@ -3,6 +3,6 @@ CPPFLAGS += -DHAVE_CONFIG_H LDFLAGS += -lstdc++ LIBS += -lstdc++ -RUN_OPTIONS = Sort.class +RUN_OPTIONS = $(BUILD_SRC_DIR)/Sort.class REQUIRES_EH_SUPPORT := 1 include ../../Makefile.multisrc From lattner at cs.uiuc.edu Mon Mar 8 10:50:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 10:50:02 2004 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200403081649.KAA05412@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.51 -> 1.52 --- Log message: Remove the comment "Constants must always have an initial value.", which is incorrect. Fix some formatting nastiness. --- Diffs of the changes: (+41 -25) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.51 llvm/docs/LangRef.html:1.52 --- llvm/docs/LangRef.html:1.51 Mon Mar 1 11:47:27 2004 +++ llvm/docs/LangRef.html Mon Mar 8 10:49:10 2004 @@ -623,45 +623,61 @@ outside of the current module. It is illegal for a function declaration to have any linkage type other than "externally visible".

+ - + +
+

Global variables define regions of memory allocated at compilation time instead of run-time. Global variables may optionally be initialized. A variable may be defined as a global "constant", which indicates that the contents of the variable will never be modified -(opening options for optimization). Constants must always have an -initial value.

+(opening options for optimization).

+

As SSA values, global variables define pointer values that are in scope (i.e. they dominate) for all basic blocks in the program. Global variables always define a pointer to their "content" type because they describe a region of memory, and all memory objects in LLVM are accessed through pointers.

+
+ + - + +
-

LLVM function definitions are composed of a (possibly empty) -argument list, an opening curly brace, a list of basic blocks, and a -closing curly brace. LLVM function declarations are defined with the "declare" -keyword, a function name, and a function signature.

-

A function definition contains a list of basic blocks, forming the -CFG for the function. Each basic block may optionally start with a -label (giving the basic block a symbol table entry), contains a list of -instructions, and ends with a terminator -instruction (such as a branch or function return).

-

The first basic block in program is special in two ways: it is -immediately executed on entrance to the function, and it is not allowed -to have predecessor basic blocks (i.e. there can not be any branches to -the entry block of a function). Because the block can have no -predecessors, it also cannot have any PHI nodes.

-

-LLVM functions are identified by their name and type signature. Hence, two -functions with the same name but different parameter lists or return values -are considered different functions, and LLVM will resolves references to each -appropriately. -

+ +

LLVM function definitions are composed of a (possibly empty) argument list, +an opening curly brace, a list of basic blocks, and a closing curly brace. LLVM +function declarations are defined with the "declare" keyword, a +function name, and a function signature.

+ +

A function definition contains a list of basic blocks, forming the CFG for +the function. Each basic block may optionally start with a label (giving the +basic block a symbol table entry), contains a list of instructions, and ends +with a terminator instruction (such as a branch or +function return).

+ +

The first basic block in program is special in two ways: it is immediately +executed on entrance to the function, and it is not allowed to have predecessor +basic blocks (i.e. there can not be any branches to the entry block of a +function). Because the block can have no predecessors, it also cannot have any +PHI nodes.

+ +

LLVM functions are identified by their name and type signature. Hence, two +functions with the same name but different parameter lists or return values are +considered different functions, and LLVM will resolves references to each +appropriately.

+
+ + @@ -2058,7 +2074,7 @@ Chris Lattner
The LLVM Compiler Infrastructure
- Last modified: $Date: 2004/03/01 17:47:27 $ + Last modified: $Date: 2004/03/08 16:49:10 $ From lattner at cs.uiuc.edu Mon Mar 8 11:07:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 11:07:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp ProfilingUtils.h BlockProfiling.cpp Message-ID: <200403081706.LAA10332@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: ProfilingUtils.cpp added (r1.1) ProfilingUtils.h added (r1.1) BlockProfiling.cpp updated: 1.6 -> 1.7 --- Log message: Split utility functions out of BlockProfiling.cpp --- Diffs of the changes: (+137 -85) Index: llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp diff -c /dev/null llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp:1.1 *** /dev/null Mon Mar 8 11:06:24 2004 --- llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp Mon Mar 8 11:06:13 2004 *************** *** 0 **** --- 1,102 ---- + //===- ProfilingUtils.cpp - Helper functions shared by profilers ----------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This files implements a few helper functions which are used by profile + // instrumentation code to instrument the code. This allows the profiler pass + // to worry about *what* to insert, and these functions take care of *how* to do + // it. + // + //===----------------------------------------------------------------------===// + + #include "ProfilingUtils.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Instructions.h" + #include "llvm/Module.h" + + void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName, + GlobalValue *Array) { + const Type *ArgVTy = PointerType::get(PointerType::get(Type::SByteTy)); + const Type *UIntPtr = PointerType::get(Type::UIntTy); + Module &M = *MainFn->getParent(); + Function *InitFn = M.getOrInsertFunction(FnName, Type::IntTy, Type::IntTy, + ArgVTy, UIntPtr, Type::UIntTy, 0); + + // This could force argc and argv into programs that wouldn't otherwise have + // them, but instead we just pass null values in. + std::vector Args(4); + Args[0] = Constant::getNullValue(Type::IntTy); + Args[1] = Constant::getNullValue(ArgVTy); + + // Skip over any allocas in the entry block. + BasicBlock *Entry = MainFn->begin(); + BasicBlock::iterator InsertPos = Entry->begin(); + while (isa(InsertPos)) ++InsertPos; + + ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array); + std::vector GEPIndices(2, Constant::getNullValue(Type::LongTy)); + Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices); + + unsigned NumElements = + cast(Array->getType()->getElementType())->getNumElements(); + Args[3] = ConstantUInt::get(Type::UIntTy, NumElements); + + Instruction *InitCall = new CallInst(InitFn, Args, "newargc", InsertPos); + + // If argc or argv are not available in main, just pass null values in. + Function::aiterator AI; + switch (MainFn->asize()) { + default: + case 2: + AI = MainFn->abegin(); ++AI; + if (AI->getType() != ArgVTy) { + InitCall->setOperand(2, new CastInst(AI, ArgVTy, "argv.cast", InitCall)); + } else { + InitCall->setOperand(2, AI); + } + + case 1: + AI = MainFn->abegin(); + // If the program looked at argc, have it look at the return value of the + // init call instead. + if (AI->getType() != Type::IntTy) { + if (!AI->use_empty()) + AI->replaceAllUsesWith(new CastInst(InitCall, AI->getType(), "", + InsertPos)); + InitCall->setOperand(1, new CastInst(AI, Type::IntTy, "argc.cast", + InitCall)); + } else { + AI->replaceAllUsesWith(InitCall); + InitCall->setOperand(1, AI); + } + + case 0: break; + } + } + + void llvm::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, + ConstantPointerRef *CounterArray) { + // Insert the increment after any alloca or PHI instructions... + BasicBlock::iterator InsertPos = BB->begin(); + while (isa(InsertPos) || isa(InsertPos)) + ++InsertPos; + + // Create the getelementptr constant expression + std::vector Indices(2); + Indices[0] = Constant::getNullValue(Type::LongTy); + Indices[1] = ConstantSInt::get(Type::LongTy, CounterNum); + Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray, Indices); + + // Load, increment and store the value back. + Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); + Value *NewVal = BinaryOperator::create(Instruction::Add, OldVal, + ConstantInt::get(Type::UIntTy, 1), + "NewFuncCounter", InsertPos); + new StoreInst(NewVal, ElementPtr, InsertPos); + } Index: llvm/lib/Transforms/Instrumentation/ProfilingUtils.h diff -c /dev/null llvm/lib/Transforms/Instrumentation/ProfilingUtils.h:1.1 *** /dev/null Mon Mar 8 11:06:24 2004 --- llvm/lib/Transforms/Instrumentation/ProfilingUtils.h Mon Mar 8 11:06:13 2004 *************** *** 0 **** --- 1,32 ---- + //===- ProfilingUtils.h - Helper functions shared by profilers --*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This files defines a few helper functions which are used by profile + // instrumentation code to instrument the code. This allows the profiler pass + // to worry about *what* to insert, and these functions take care of *how* to do + // it. + // + //===----------------------------------------------------------------------===// + + #ifndef PROFILINGUTILS_H + #define PROFILINGUTILS_H + + namespace llvm { + class Function; + class GlobalValue; + class ConstantPointerRef; + class BasicBlock; + + void InsertProfilingInitCall(Function *MainFn, const char *FnName, + GlobalValue *Arr); + void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, + ConstantPointerRef *CounterArray); + } + + #endif Index: llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp diff -u llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp:1.6 llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp:1.7 --- llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp:1.6 Tue Feb 10 11:41:01 2004 +++ llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp Mon Mar 8 11:06:13 2004 @@ -21,93 +21,11 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Pass.h" +#include "ProfilingUtils.h" using namespace llvm; -static void insertInitializationCall(Function *MainFn, const char *FnName, - GlobalValue *Array) { - const Type *ArgVTy = PointerType::get(PointerType::get(Type::SByteTy)); - const Type *UIntPtr = PointerType::get(Type::UIntTy); - Module &M = *MainFn->getParent(); - Function *InitFn = M.getOrInsertFunction(FnName, Type::IntTy, Type::IntTy, - ArgVTy, UIntPtr, Type::UIntTy, 0); - - // This could force argc and argv into programs that wouldn't otherwise have - // them, but instead we just pass null values in. - std::vector Args(4); - Args[0] = Constant::getNullValue(Type::IntTy); - Args[1] = Constant::getNullValue(ArgVTy); - - // Skip over any allocas in the entry block. - BasicBlock *Entry = MainFn->begin(); - BasicBlock::iterator InsertPos = Entry->begin(); - while (isa(InsertPos)) ++InsertPos; - - ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array); - std::vector GEPIndices(2, Constant::getNullValue(Type::LongTy)); - Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices); - - unsigned NumElements = - cast(Array->getType()->getElementType())->getNumElements(); - Args[3] = ConstantUInt::get(Type::UIntTy, NumElements); - - Instruction *InitCall = new CallInst(InitFn, Args, "newargc", InsertPos); - - // If argc or argv are not available in main, just pass null values in. - Function::aiterator AI; - switch (MainFn->asize()) { - default: - case 2: - AI = MainFn->abegin(); ++AI; - if (AI->getType() != ArgVTy) { - InitCall->setOperand(2, new CastInst(AI, ArgVTy, "argv.cast", InitCall)); - } else { - InitCall->setOperand(2, AI); - } - - case 1: - AI = MainFn->abegin(); - // If the program looked at argc, have it look at the return value of the - // init call instead. - if (AI->getType() != Type::IntTy) { - if (!AI->use_empty()) - AI->replaceAllUsesWith(new CastInst(InitCall, AI->getType(), "", - InsertPos)); - InitCall->setOperand(1, new CastInst(AI, Type::IntTy, "argc.cast", - InitCall)); - } else { - AI->replaceAllUsesWith(InitCall); - InitCall->setOperand(1, AI); - } - - case 0: break; - } -} - -static void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, - ConstantPointerRef *CounterArray) { - // Insert the increment after any alloca or PHI instructions... - BasicBlock::iterator InsertPos = BB->begin(); - while (isa(InsertPos) || isa(InsertPos)) - ++InsertPos; - - // Create the getelementptr constant expression - std::vector Indices(2); - Indices[0] = Constant::getNullValue(Type::LongTy); - Indices[1] = ConstantSInt::get(Type::LongTy, CounterNum); - Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray, Indices); - - // Load, increment and store the value back. - Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); - Value *NewVal = BinaryOperator::create(Instruction::Add, OldVal, - ConstantInt::get(Type::UIntTy, 1), - "NewFuncCounter", InsertPos); - new StoreInst(NewVal, ElementPtr, InsertPos); -} - - namespace { class FunctionProfiler : public Pass { bool run(Module &M); @@ -145,7 +63,7 @@ IncrementCounterInBlock(I->begin(), i++, CounterCPR); // Add the initialization call to main. - insertInitializationCall(Main, "llvm_start_func_profiling", Counters); + InsertProfilingInitCall(Main, "llvm_start_func_profiling", Counters); return true; } @@ -186,7 +104,7 @@ IncrementCounterInBlock(BB, i++, CounterCPR); // Add the initialization call to main. - insertInitializationCall(Main, "llvm_start_block_profiling", Counters); + InsertProfilingInitCall(Main, "llvm_start_block_profiling", Counters); return true; } From lattner at cs.uiuc.edu Mon Mar 8 11:55:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 11:55:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/EdgeProfiling.cpp Message-ID: <200403081754.LAA24912@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: EdgeProfiling.cpp added (r1.1) --- Log message: Initial support for edge profiling --- Diffs of the changes: (+94 -0) Index: llvm/lib/Transforms/Instrumentation/EdgeProfiling.cpp diff -c /dev/null llvm/lib/Transforms/Instrumentation/EdgeProfiling.cpp:1.1 *** /dev/null Mon Mar 8 11:54:45 2004 --- llvm/lib/Transforms/Instrumentation/EdgeProfiling.cpp Mon Mar 8 11:54:34 2004 *************** *** 0 **** --- 1,94 ---- + //===- EdgeProfiling.cpp - Insert counters for edge profiling -------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This pass instruments the specified program with counters for edge profiling. + // Edge profiling can give a reasonable approximation of the hot paths through a + // program, and is used for a wide variety of program transformations. + // + // Note that this implementation is very naive. We insert a counter for *every* + // edge in the program, instead of using control flow information to prune the + // number of counters inserted. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Module.h" + #include "llvm/Pass.h" + #include "llvm/Transforms/Utils/BasicBlockUtils.h" + #include "ProfilingUtils.h" + #include + using namespace llvm; + + namespace { + class EdgeProfiler : public Pass { + bool run(Module &M); + }; + + RegisterOpt X("insert-edge-profiling", + "Insert instrumentation for edge profiling"); + } + + bool EdgeProfiler::run(Module &M) { + Function *Main = M.getMainFunction(); + if (Main == 0) { + std::cerr << "WARNING: cannot insert edge profiling into a module" + << " with no main function!\n"; + return false; // No main, no instrumentation! + } + + std::set BlocksToInstrument; + unsigned NumEdges = 0; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + // Keep track of which blocks need to be instrumented. We don't want to + // instrument blocks that are added as the result of breaking critical + // edges! + BlocksToInstrument.insert(BB); + NumEdges += BB->getTerminator()->getNumSuccessors(); + } + + const Type *ATy = ArrayType::get(Type::UIntTy, NumEdges); + GlobalVariable *Counters = + new GlobalVariable(ATy, false, GlobalValue::InternalLinkage, + Constant::getNullValue(ATy), "EdgeProfCounters", &M); + + ConstantPointerRef *CounterCPR = ConstantPointerRef::get(Counters); + + // Instrument all of the edges... + unsigned i = 0; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + if (BlocksToInstrument.count(BB)) { // Don't instrument inserted blocks + // Okay, we have to add a counter of each outgoing edge. If the + // outgoing edge is not critical don't split it, just insert the counter + // in the source or destination of the edge. + TerminatorInst *TI = BB->getTerminator(); + for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { + // If the edge is critical, split it. + SplitCriticalEdge(TI, s, this); + + // Okay, we are guaranteed that the edge is no longer critical. If we + // only have a single successor, insert the counter in this block, + // otherwise insert it in the successor block. + if (TI->getNumSuccessors() == 0) { + // Insert counter at the start of the block + IncrementCounterInBlock(BB, i++, CounterCPR); + } else { + // Insert counter at the start of the block + IncrementCounterInBlock(TI->getSuccessor(s), i++, CounterCPR); + } + } + } + + // Add the initialization call to main. + InsertProfilingInitCall(Main, "llvm_start_edge_profiling", Counters); + return true; + } + From brukman at cs.uiuc.edu Mon Mar 8 12:00:03 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Mar 8 12:00:03 2004 Subject: [llvm-commits] CVS: llvm/docs/index.html Message-ID: <200403081759.LAA26094@zion.cs.uiuc.edu> Changes in directory llvm/docs: index.html updated: 1.9 -> 1.10 --- Log message: Fix link to license: point to current version in CVS. --- Diffs of the changes: (+1 -1) Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.9 llvm/docs/index.html:1.10 --- llvm/docs/index.html:1.9 Sat Feb 21 23:45:02 2004 +++ llvm/docs/index.html Mon Mar 8 11:59:31 2004 @@ -48,7 +48,7 @@
For license information:
- llvm/LICENSE.TXT + llvm/LICENSE.TXT

From lattner at cs.uiuc.edu Mon Mar 8 12:05:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 12:05:02 2004 Subject: [llvm-commits] CVS: llvm/runtime/libprofile/EdgeProfiling.c Message-ID: <200403081804.MAA32706@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libprofile: EdgeProfiling.c added (r1.1) --- Log message: Add edge profiling support to the runtime library --- Diffs of the changes: (+45 -0) Index: llvm/runtime/libprofile/EdgeProfiling.c diff -c /dev/null llvm/runtime/libprofile/EdgeProfiling.c:1.1 *** /dev/null Mon Mar 8 12:04:41 2004 --- llvm/runtime/libprofile/EdgeProfiling.c Mon Mar 8 12:04:31 2004 *************** *** 0 **** --- 1,45 ---- + /*===-- EdgeProfiling.c - Support library for edge profiling --------------===*\ + |* + |* The LLVM Compiler Infrastructure + |* + |* This file was developed by the LLVM research group and is distributed under + |* the University of Illinois Open Source License. See LICENSE.TXT for details. + |* + |*===----------------------------------------------------------------------===*| + |* + |* This file implements the call back routines for the edge profiling + |* instrumentation pass. This should be used with the -insert-edge-profiling + |* LLVM pass. + |* + \*===----------------------------------------------------------------------===*/ + + #include "Profiling.h" + #include + + static unsigned *ArrayStart; + static unsigned NumElements; + + /* EdgeProfAtExitHandler - When the program exits, just write out the profiling + * data. + */ + static void EdgeProfAtExitHandler() { + /* Note that if this were doing something more intellegent with the + instrumentation, that we could do some computation here to expand what we + collected into simple edge profiles. Since we directly count each edge, we + just write out all of the counters directly. + */ + write_profiling_data(Edge, ArrayStart, NumElements); + } + + + /* llvm_start_edge_profiling - This is the main entry point of the edge + * profiling library. It is responsible for setting up the atexit handler. + */ + int llvm_start_edge_profiling(int argc, const char **argv, + unsigned *arrayStart, unsigned numElements) { + int Ret = save_arguments(argc, argv); + ArrayStart = arrayStart; + NumElements = numElements; + atexit(EdgeProfAtExitHandler); + return Ret; + } From lattner at cs.uiuc.edu Mon Mar 8 12:20:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 12:20:02 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ProfileInfoLoader.h Message-ID: <200403081819.MAA01324@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ProfileInfoLoader.h updated: 1.1 -> 1.2 --- Log message: Add support for representing edge counts --- Diffs of the changes: (+19 -1) Index: llvm/include/llvm/Analysis/ProfileInfoLoader.h diff -u llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.1 llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.2 --- llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.1 Tue Feb 10 23:54:08 2004 +++ llvm/include/llvm/Analysis/ProfileInfoLoader.h Mon Mar 8 12:19:37 2004 @@ -31,6 +31,7 @@ std::vector CommandLines; std::vector FunctionCounts; std::vector BlockCounts; + std::vector EdgeCounts; public: // ProfileInfoLoader ctor - Read the specified profiling data file, exiting // the program if the file is invalid or broken. @@ -50,7 +51,14 @@ // frequency information from whatever we have. // bool hasAccurateBlockCounts() const { - return !BlockCounts.empty(); + return !BlockCounts.empty() || !EdgeCounts.empty(); + } + + // hasAccurateEdgeCounts - Return true if we can synthesize accurate edge + // frequency information from whatever we have. + // + bool hasAccurateEdgeCounts() const { + return !EdgeCounts.empty(); } // getBlockCounts - This method is used by consumers of block counting @@ -58,6 +66,16 @@ // compute it from other, more refined, types of profile information. // void getBlockCounts(std::vector > &Counts); + + // getEdgeCounts - This method is used by consumers of edge counting + // information. If we do not directly have edge count information, we compute + // it from other, more refined, types of profile information. + // + // Edges are represented as a pair, where the first element is the basic block + // and the second element is the successor number. + // + typedef std::pair Edge; + void getEdgeCounts(std::vector > &Counts); }; } // End llvm namespace From lattner at cs.uiuc.edu Mon Mar 8 12:21:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 12:21:00 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ProfileInfoLoader.cpp Message-ID: <200403081820.MAA01346@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ProfileInfoLoader.cpp updated: 1.2 -> 1.3 --- Log message: Add initial support for reading edge counts. This will be improved to enable translation of edge counts into block/function counts when possible. --- Diffs of the changes: (+29 -0) Index: llvm/lib/Analysis/ProfileInfoLoader.cpp diff -u llvm/lib/Analysis/ProfileInfoLoader.cpp:1.2 llvm/lib/Analysis/ProfileInfoLoader.cpp:1.3 --- llvm/lib/Analysis/ProfileInfoLoader.cpp:1.2 Wed Feb 11 12:20:41 2004 +++ llvm/lib/Analysis/ProfileInfoLoader.cpp Mon Mar 8 12:20:18 2004 @@ -14,6 +14,7 @@ #include "llvm/Analysis/ProfileInfoLoader.h" #include "llvm/Module.h" +#include "llvm/InstrTypes.h" #include using namespace llvm; @@ -21,6 +22,7 @@ ArgumentInfo = 1, // The command line argument block FunctionInfo = 2, // Function profiling information BlockInfo = 3, // Block profiling information + EdgeInfo = 4, // Edge profiling information }; // ByteSwap - Byteswap 'Var' if 'Really' is true. @@ -122,6 +124,10 @@ ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts); break; + case EdgeInfo: + ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts); + break; + default: std::cerr << ToolName << ": Unknown packet type #" << PacketType << "!\n"; exit(1); @@ -177,4 +183,27 @@ if (Counter == BlockCounts.size()) return; } +} + +// getEdgeCounts - This method is used by consumers of edge counting +// information. If we do not directly have edge count information, we compute +// it from other, more refined, types of profile information. +// +void ProfileInfoLoader::getEdgeCounts(std::vector > &Counts) { + if (EdgeCounts.empty()) { + std::cerr << "Edge counts not available, and no synthesis " + << "is implemented yet!\n"; + return; + } + + unsigned Counter = 0; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + for (unsigned i = 0, e = BB->getTerminator()->getNumSuccessors(); + i != e; ++i) { + Counts.push_back(std::make_pair(Edge(BB, i), EdgeCounts[Counter++])); + if (Counter == EdgeCounts.size()) + return; + } } From lattner at cs.uiuc.edu Mon Mar 8 12:52:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 12:52:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Assembly/AsmAnnotationWriter.h Message-ID: <200403081851.MAA07480@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Assembly: AsmAnnotationWriter.h updated: 1.2 -> 1.3 --- Log message: Add the ability to put an annotation at the end of a basic block as well. --- Diffs of the changes: (+9 -3) Index: llvm/include/llvm/Assembly/AsmAnnotationWriter.h diff -u llvm/include/llvm/Assembly/AsmAnnotationWriter.h:1.2 llvm/include/llvm/Assembly/AsmAnnotationWriter.h:1.3 --- llvm/include/llvm/Assembly/AsmAnnotationWriter.h:1.2 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Assembly/AsmAnnotationWriter.h Mon Mar 8 12:51:05 2004 @@ -31,9 +31,15 @@ // the start of a function. virtual void emitFunctionAnnot(const Function *F, std::ostream &OS) {} - // emitBasicBlockAnnot - This may be implemented to emit a string right after - // the basic block label, but before the first instruction in the block. - virtual void emitBasicBlockAnnot(const BasicBlock *BB, std::ostream &OS) {} + // emitBasicBlockStartAnnot - This may be implemented to emit a string right + // after the basic block label, but before the first instruction in the block. + virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, std::ostream &OS){ + } + + // emitBasicBlockEndAnnot - This may be implemented to emit a string right + // after the basic block. + virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, std::ostream &OS){ + } // emitInstructionAnnot - This may be implemented to emit a string right // before an instruction is emitted. From lattner at cs.uiuc.edu Mon Mar 8 12:52:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 12:52:04 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200403081851.MAA07676@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.124 -> 1.125 --- Log message: Adjust to new interface --- Diffs of the changes: (+3 -1) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.124 llvm/lib/VMCore/AsmWriter.cpp:1.125 --- llvm/lib/VMCore/AsmWriter.cpp:1.124 Mon Mar 1 18:22:19 2004 +++ llvm/lib/VMCore/AsmWriter.cpp Mon Mar 8 12:51:45 2004 @@ -752,11 +752,13 @@ Out << "\n"; - if (AnnotationWriter) AnnotationWriter->emitBasicBlockAnnot(BB, Out); + if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out); // Output all of the instructions in the basic block... for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) printInstruction(*I); + + if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } From lattner at cs.uiuc.edu Mon Mar 8 14:05:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 14:05:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ProfileInfoLoader.cpp Message-ID: <200403082004.OAA03975@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ProfileInfoLoader.cpp updated: 1.3 -> 1.4 --- Log message: If we have edge counts, we can produce block counts. I've verified that using an edge profile to produce block counts gives the exact same numbers as using a block count directly. --- Diffs of the changes: (+67 -11) Index: llvm/lib/Analysis/ProfileInfoLoader.cpp diff -u llvm/lib/Analysis/ProfileInfoLoader.cpp:1.3 llvm/lib/Analysis/ProfileInfoLoader.cpp:1.4 --- llvm/lib/Analysis/ProfileInfoLoader.cpp:1.3 Mon Mar 8 12:20:18 2004 +++ llvm/lib/Analysis/ProfileInfoLoader.cpp Mon Mar 8 14:03:52 2004 @@ -16,6 +16,7 @@ #include "llvm/Module.h" #include "llvm/InstrTypes.h" #include +#include using namespace llvm; enum ProfilingType { @@ -145,15 +146,19 @@ void ProfileInfoLoader::getFunctionCounts(std::vector > &Counts) { if (FunctionCounts.empty()) { - // Synthesize function frequency information from the number of times their - // entry blocks were executed. - std::vector > BlockCounts; - getBlockCounts(BlockCounts); - - for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i) - if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first) - Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(), - BlockCounts[i].second)); + if (hasAccurateBlockCounts()) { + // Synthesize function frequency information from the number of times + // their entry blocks were executed. + std::vector > BlockCounts; + getBlockCounts(BlockCounts); + + for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i) + if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first) + Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(), + BlockCounts[i].second)); + } else { + std::cerr << "Function counts are not available!\n"; + } return; } @@ -171,8 +176,59 @@ void ProfileInfoLoader::getBlockCounts(std::vector > &Counts) { if (BlockCounts.empty()) { - std::cerr << "Block counts not available, and no synthesis " - << "is implemented yet!\n"; + if (hasAccurateEdgeCounts()) { + // Synthesize block count information from edge frequency information. + // The block execution frequency is equal to the sum of the execution + // frequency of all outgoing edges from a block. + // + // If a block has no successors, this will not be correct, so we have to + // special case it. :( + std::vector > EdgeCounts; + getEdgeCounts(EdgeCounts); + + std::map InEdgeFreqs; + + BasicBlock *LastBlock = 0; + TerminatorInst *TI = 0; + for (unsigned i = 0, e = EdgeCounts.size(); i != e; ++i) { + if (EdgeCounts[i].first.first != LastBlock) { + LastBlock = EdgeCounts[i].first.first; + TI = LastBlock->getTerminator(); + Counts.push_back(std::make_pair(LastBlock, 0)); + } + Counts.back().second += EdgeCounts[i].second; + unsigned SuccNum = EdgeCounts[i].first.second; + if (SuccNum >= TI->getNumSuccessors()) { + static bool Warned = false; + if (!Warned) { + std::cerr << "WARNING: profile info doesn't seem to match" + << " the program!\n"; + Warned = true; + } + } else { + // If this successor has no successors of its own, we will never + // compute an execution count for that block. Remember the incoming + // edge frequencies to add later. + BasicBlock *Succ = TI->getSuccessor(SuccNum); + if (Succ->getTerminator()->getNumSuccessors() == 0) + InEdgeFreqs[Succ] += EdgeCounts[i].second; + } + } + + // Now we have to accumulate information for those blocks without + // successors into our table. + for (std::map::iterator I = InEdgeFreqs.begin(), + E = InEdgeFreqs.end(); I != E; ++I) { + unsigned i = 0; + for (; i != Counts.size() && Counts[i].first != I->first; ++i) + /*empty*/; + if (i == Counts.size()) Counts.push_back(std::make_pair(I->first, 0)); + Counts[i].second += I->second; + } + + } else { + std::cerr << "Block counts are not available!\n"; + } return; } From lattner at cs.uiuc.edu Mon Mar 8 14:05:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 14:05:05 2004 Subject: [llvm-commits] CVS: llvm/tools/llvm-prof/llvm-prof.cpp Message-ID: <200403082004.OAA04090@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-prof: llvm-prof.cpp updated: 1.18 -> 1.19 --- Log message: Annotate functions with edge counts as well, if they are available. --- Diffs of the changes: (+39 -6) Index: llvm/tools/llvm-prof/llvm-prof.cpp diff -u llvm/tools/llvm-prof/llvm-prof.cpp:1.18 llvm/tools/llvm-prof/llvm-prof.cpp:1.19 --- llvm/tools/llvm-prof/llvm-prof.cpp:1.18 Thu Feb 19 14:32:12 2004 +++ llvm/tools/llvm-prof/llvm-prof.cpp Mon Mar 8 14:04:32 2004 @@ -13,6 +13,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/InstrTypes.h" #include "llvm/Module.h" #include "llvm/Assembly/AsmAnnotationWriter.h" #include "llvm/Analysis/ProfileInfoLoader.h" @@ -59,21 +60,46 @@ class ProfileAnnotator : public AssemblyAnnotationWriter { std::map &FuncFreqs; std::map &BlockFreqs; + std::map &EdgeFreqs; public: ProfileAnnotator(std::map &FF, - std::map &BF) - : FuncFreqs(FF), BlockFreqs(BF) {} + std::map &BF, + std::map &EF) + : FuncFreqs(FF), BlockFreqs(BF), EdgeFreqs(EF) {} virtual void emitFunctionAnnot(const Function *F, std::ostream &OS) { OS << ";;; %" << F->getName() << " called " << FuncFreqs[F] << " times.\n;;;\n"; } - virtual void emitBasicBlockAnnot(const BasicBlock *BB, std::ostream &OS) { + virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, + std::ostream &OS) { if (BlockFreqs.empty()) return; if (unsigned Count = BlockFreqs[BB]) - OS << ";;; Executed " << Count << " times.\n"; + OS << "\t;;; Basic block executed " << Count << " times.\n"; else - OS << ";;; Never executed!\n"; + OS << "\t;;; Never executed!\n"; + } + + virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, std::ostream &OS){ + if (EdgeFreqs.empty()) return; + + // Figure out how many times each successor executed. + std::vector > SuccCounts; + const TerminatorInst *TI = BB->getTerminator(); + + std::map::iterator I = + EdgeFreqs.lower_bound(std::make_pair(const_cast(BB), 0U)); + for (; I != EdgeFreqs.end() && I->first.first == BB; ++I) + if (I->second) + SuccCounts.push_back(std::make_pair(TI->getSuccessor(I->first.second), + I->second)); + if (!SuccCounts.empty()) { + OS << "\t;;; Out-edge counts:"; + for (unsigned i = 0, e = SuccCounts.size(); i != e; ++i) + OS << " [" << SuccCounts[i].second << " -> " + << SuccCounts[i].first->getName() << "]"; + OS << "\n"; + } } }; } @@ -97,6 +123,7 @@ std::map FuncFreqs; std::map BlockFreqs; + std::map EdgeFreqs; // Output a report. Eventually, there will be multiple reports selectable on // the command line, for now, just keep things simple. @@ -177,11 +204,17 @@ BlockFreqs.insert(Counts.begin(), Counts.end()); } + if (PI.hasAccurateEdgeCounts()) { + std::vector > Counts; + PI.getEdgeCounts(Counts); + EdgeFreqs.insert(Counts.begin(), Counts.end()); + } + if (PrintAnnotatedLLVM || PrintAllCode) { std::cout << "\n===" << std::string(73, '-') << "===\n"; std::cout << "Annotated LLVM code for the module:\n\n"; - ProfileAnnotator PA(FuncFreqs, BlockFreqs); + ProfileAnnotator PA(FuncFreqs, BlockFreqs, EdgeFreqs); if (FunctionsToPrint.empty() || PrintAllCode) M->print(std::cout, &PA); From lattner at cs.uiuc.edu Mon Mar 8 14:05:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 14:05:08 2004 Subject: [llvm-commits] CVS: llvm/utils/profile.pl Message-ID: <200403082004.OAA04257@zion.cs.uiuc.edu> Changes in directory llvm/utils: profile.pl updated: 1.5 -> 1.6 --- Log message: Default to using edge counts --- Diffs of the changes: (+13 -9) Index: llvm/utils/profile.pl diff -u llvm/utils/profile.pl:1.5 llvm/utils/profile.pl:1.6 --- llvm/utils/profile.pl:1.5 Tue Feb 10 12:01:50 2004 +++ llvm/utils/profile.pl Mon Mar 8 14:04:46 2004 @@ -8,15 +8,16 @@ # Syntax: profile.pl [OPTIONS] bytecodefile # # OPTIONS may include one or more of the following: -# -block - Enable basicblock-level profiling -# -function - Enable function-level profiling +# -block - Enable basicblock profiling +# -edge - Enable edge profiling +# -function - Enable function profiling # -o - Emit profiling information to the specified file, instead # of llvmprof.out # # Any unrecognized options are passed into the invocation of llvm-prof # -my $ProfilePass = "-insert-block-profiling"; +my $ProfilePass = "-insert-edge-profiling"; my $LLVMProfOpts = ""; my $ProgramOpts = ""; @@ -28,7 +29,8 @@ last if /^--$/; # Stop processing arguments on -- # List command line options here... - if (/^-?-block$/) { $ProfilePass = "-insert-block-profiling"; next; } + if (/^-?-block$/) { $ProfilePass = "-insert-block-profiling"; next; } + if (/^-?-edge$/) { $ProfilePass = "-insert-edge-profiling"; next; } if (/^-?-function$/) { $ProfilePass = "-insert-function-profiling"; next; } if (/^-?-o$/) { # Read -o filename... die "-o option requires a filename argument!" if (!scalar(@ARGV)); @@ -41,8 +43,9 @@ print "OVERVIEW: profile.pl - Instrumentation and profile printer.\n\n"; print "USAGE: profile.pl [options] program.bc \n\n"; print "OPTIONS:\n"; - print " -block - Enable basicblock-level profiling\n"; - print " -function - Enable function-level profiling\n"; + print " -block - Enable basicblock profiling\n"; + print " -edge - Enable edge profiling\n"; + print " -function - Enable function profiling\n"; print " -o - Specify an output file other than llvm-prof.out.\n"; print " -help - Print this usage information\n"; print "\nAll other options are passed into llvm-prof.\n"; @@ -65,7 +68,8 @@ my $LibProfPath = $LLIPath . "/../../lib/Debug/libprofile_rt.so"; -system "opt -q $ProfilePass < $BytecodeFile | lli -fake-argv0 '$BytecodeFile'" . - " -load $LibProfPath -$ProgramOpts " . (join ' ', @ARGV); - +system "opt -q -f $ProfilePass $BytecodeFile -o $BytecodeFile.inst"; +system "lli -fake-argv0 '$BytecodeFile' -load $LibProfPath " . + "$BytecodeFile.inst $ProgramOpts " . (join ' ', @ARGV); +system "rm $BytecodeFile.inst"; system "llvm-prof $LLVMProfOpts $BytecodeFile $ProfileFile"; From lattner at cs.uiuc.edu Mon Mar 8 14:06:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 14:06:01 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200403082005.OAA04296@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.123 -> 1.124 --- Log message: default to gathering edge profiles --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.123 llvm/test/Programs/Makefile.programs:1.124 --- llvm/test/Programs/Makefile.programs:1.123 Sun Feb 29 01:13:16 2004 +++ llvm/test/Programs/Makefile.programs Mon Mar 8 14:04:59 2004 @@ -395,7 +395,7 @@ # $(PROGRAMS_TO_TEST:%=Output/%.llvm-prof.bc): \ Output/%.llvm-prof.bc: Output/%.llvm.bc - $(LOPT) -insert-block-profiling $< -o $@ -f + $(LOPT) -insert-edge-profiling $< -o $@ -f $(PROGRAMS_TO_TEST:%=Output/%.printprof): \ Output/%.printprof: Output/%.llvm.bc Output/%.prof $(LPROF) From lattner at cs.uiuc.edu Mon Mar 8 14:58:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 14:58:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Trace.h Message-ID: <200403082057.OAA09573@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Trace.h added (r1.1) --- Log message: Import the trace class from the reoptimizer --- Diffs of the changes: (+106 -0) Index: llvm/include/llvm/Analysis/Trace.h diff -c /dev/null llvm/include/llvm/Analysis/Trace.h:1.1 *** /dev/null Mon Mar 8 14:57:36 2004 --- llvm/include/llvm/Analysis/Trace.h Mon Mar 8 14:57:25 2004 *************** *** 0 **** --- 1,106 ---- + //===- llvm/Analysis/Trace.h - Represent one trace of LLVM code -*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This class represents a single trace of LLVM basic blocks. A trace is a + // single entry, multiple exit, region of code that is often hot. Trace-based + // optimizations treat traces almost like they are a large, strange, basic + // block: because the trace path is assumed to be hot, optimizations for the + // fall-through path are made at the expense of the non-fall-through paths. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_ANALYSIS_TRACE_H + #define LLVM_ANALYSIS_TRACE_H + + #include + #include + + namespace llvm { + class BasicBlock; + class Function; + class Module; + + class Trace { + typedef std::vector BasicBlockListType; + BasicBlockListType BasicBlocks; + + public: + /// contains - Returns true if this trace contains the given basic + /// block. + /// + inline bool contains (const BasicBlock *X) { + for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) + if (BasicBlocks[i] == X) + return true; + return false; + } + + /// Trace ctor - Make a new trace from a vector of basic blocks, + /// residing in the function which is the parent of the first + /// basic block in the vector. + /// + Trace (const std::vector &vBB) : BasicBlocks (vBB) { + } + + /// getEntryBasicBlock - Return the entry basic block (first block) + /// of the trace. + /// + BasicBlock *getEntryBasicBlock () const { return BasicBlocks[0]; } + + /// getFunction - Return this trace's parent function. + /// + Function *getFunction () const; + + /// getModule - Return this Module that contains this trace's parent + /// function. + /// + Module *getModule () const; + + /// print - Write trace to output stream. + /// + void print (std::ostream &O) const; + + /// dump - Debugger convenience method; writes trace to standard error + /// output stream. + /// + void dump () const; + + // BasicBlock iterators... + typedef BasicBlockListType::iterator iterator; + typedef BasicBlockListType::const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + iterator begin() { return BasicBlocks.begin(); } + const_iterator begin() const { return BasicBlocks.begin(); } + iterator end () { return BasicBlocks.end(); } + const_iterator end () const { return BasicBlocks.end(); } + + reverse_iterator rbegin() { return BasicBlocks.rbegin(); } + const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); } + reverse_iterator rend () { return BasicBlocks.rend(); } + const_reverse_iterator rend () const { return BasicBlocks.rend(); } + + unsigned size() const { return BasicBlocks.size(); } + bool empty() const { return BasicBlocks.empty(); } + + BasicBlock *operator[] (unsigned i) const { return BasicBlocks[i]; } + BasicBlock *getBlock (unsigned i) const { return BasicBlocks[i]; } + + /// Returns true if B1 and B2 appear on a path from START to an exit + /// block => B1 appears before B2. If START is not provided, defaults + /// to 0, which means use getEntryBasicBlock(). + /// + bool dominates (const BasicBlock *B1, const BasicBlock *B2, + const BasicBlock *start = 0); + }; + + } // end namespace llvm + + #endif // TRACE_H From lattner at cs.uiuc.edu Mon Mar 8 14:58:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 14:58:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/Trace.cpp Message-ID: <200403082057.OAA09580@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: Trace.cpp added (r1.1) --- Log message: Import the trace class from the reoptimizer --- Diffs of the changes: (+50 -0) Index: llvm/lib/Analysis/Trace.cpp diff -c /dev/null llvm/lib/Analysis/Trace.cpp:1.1 *** /dev/null Mon Mar 8 14:57:37 2004 --- llvm/lib/Analysis/Trace.cpp Mon Mar 8 14:57:27 2004 *************** *** 0 **** --- 1,50 ---- + //===- Trace.cpp - Implementation of Trace class --------------------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This class represents a single trace of LLVM basic blocks. A trace is a + // single entry, multiple exit, region of code that is often hot. Trace-based + // optimizations treat traces almost like they are a large, strange, basic + // block: because the trace path is assumed to be hot, optimizations for the + // fall-through path are made at the expense of the non-fall-through paths. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Analysis/Trace.h" + #include "llvm/Function.h" + #include "llvm/Assembly/Writer.h" + using namespace llvm; + + Function *Trace::getFunction() const { + return getEntryBasicBlock()->getParent(); + } + + + Module *Trace::getModule() const { + return getFunction()->getParent(); + } + + /// print - Write trace to output stream. + /// + void Trace::print (std::ostream &O) const { + Function *F = getFunction (); + O << "; Trace from function " << F->getName () << ", blocks:\n"; + for (const_iterator i = begin (), e = end (); i != e; ++i) { + O << "; "; + WriteAsOperand (O, *i, true, true, getModule ()); + O << "\n"; + } + O << "; Trace parent function: \n" << *F; + } + + /// dump - Debugger convenience method; writes trace to standard error + /// output stream. + /// + void Trace::dump () const { + print (std::cerr); + } From lattner at cs.uiuc.edu Mon Mar 8 15:08:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 15:08:08 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Trace.h Message-ID: <200403082107.PAA10468@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Trace.h updated: 1.1 -> 1.2 --- Log message: Rearrange some methods, implement the dominates method --- Diffs of the changes: (+34 -24) Index: llvm/include/llvm/Analysis/Trace.h diff -u llvm/include/llvm/Analysis/Trace.h:1.1 llvm/include/llvm/Analysis/Trace.h:1.2 --- llvm/include/llvm/Analysis/Trace.h:1.1 Mon Mar 8 14:57:25 2004 +++ llvm/include/llvm/Analysis/Trace.h Mon Mar 8 15:07:12 2004 @@ -20,6 +20,7 @@ #include #include +#include namespace llvm { class BasicBlock; @@ -31,28 +32,22 @@ BasicBlockListType BasicBlocks; public: - /// contains - Returns true if this trace contains the given basic - /// block. - /// - inline bool contains (const BasicBlock *X) { - for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) - if (BasicBlocks[i] == X) - return true; - return false; - } - /// Trace ctor - Make a new trace from a vector of basic blocks, /// residing in the function which is the parent of the first /// basic block in the vector. /// - Trace (const std::vector &vBB) : BasicBlocks (vBB) { - } + Trace(const std::vector &vBB) : BasicBlocks (vBB) {} /// getEntryBasicBlock - Return the entry basic block (first block) /// of the trace. /// BasicBlock *getEntryBasicBlock () const { return BasicBlocks[0]; } + /// operator[]/getBlock - Return basic block N in the trace. + /// + BasicBlock *operator[](unsigned i) const { return BasicBlocks[i]; } + BasicBlock *getBlock(unsigned i) const { return BasicBlocks[i]; } + /// getFunction - Return this trace's parent function. /// Function *getFunction () const; @@ -62,14 +57,30 @@ /// Module *getModule () const; - /// print - Write trace to output stream. + /// getBlockIndex - Return the index of the specified basic block in the + /// trace, or -1 if it is not in the trace. + int getBlockIndex(const BasicBlock *X) const { + for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) + if (BasicBlocks[i] == X) + return i; + return -1; + } + + /// contains - Returns true if this trace contains the given basic + /// block. /// - void print (std::ostream &O) const; + bool contains(const BasicBlock *X) const { + return getBlockIndex(X) != -1; + } - /// dump - Debugger convenience method; writes trace to standard error - /// output stream. + /// Returns true if B1 occurs before B2 in the trace, or if it is the same + /// block as B2.. Both blocks must be in the trace. /// - void dump () const; + bool dominates(const BasicBlock *B1, const BasicBlock *B2) const { + int B1Idx = getBlockIndex(B1), B2Idx = getBlockIndex(B2); + assert(B1Idx != -1 && B2Idx != -1 && "Block is not in the trace!"); + return B1Idx <= B2Idx; + } // BasicBlock iterators... typedef BasicBlockListType::iterator iterator; @@ -90,15 +101,14 @@ unsigned size() const { return BasicBlocks.size(); } bool empty() const { return BasicBlocks.empty(); } - BasicBlock *operator[] (unsigned i) const { return BasicBlocks[i]; } - BasicBlock *getBlock (unsigned i) const { return BasicBlocks[i]; } + /// print - Write trace to output stream. + /// + void print (std::ostream &O) const; - /// Returns true if B1 and B2 appear on a path from START to an exit - /// block => B1 appears before B2. If START is not provided, defaults - /// to 0, which means use getEntryBasicBlock(). + /// dump - Debugger convenience method; writes trace to standard error + /// output stream. /// - bool dominates (const BasicBlock *B1, const BasicBlock *B2, - const BasicBlock *start = 0); + void dump () const; }; } // end namespace llvm From lattner at cs.uiuc.edu Mon Mar 8 15:31:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 15:31:00 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ProfileInfo.h Message-ID: <200403082130.PAA16948@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ProfileInfo.h updated: 1.2 -> 1.3 --- Log message: We don't want to make this a pure interface, as it makes all implementors bear the burden of implementing what will be all exactly the same methods. They just want to provide the information in differing ways. --- Diffs of the changes: (+9 -2) Index: llvm/include/llvm/Analysis/ProfileInfo.h diff -u llvm/include/llvm/Analysis/ProfileInfo.h:1.2 llvm/include/llvm/Analysis/ProfileInfo.h:1.3 --- llvm/include/llvm/Analysis/ProfileInfo.h:1.2 Wed Feb 11 00:11:06 2004 +++ llvm/include/llvm/Analysis/ProfileInfo.h Mon Mar 8 15:30:18 2004 @@ -22,6 +22,7 @@ #define LLVM_ANALYSIS_PROFILEINFO_H #include +#include namespace llvm { class BasicBlock; @@ -32,13 +33,19 @@ /// it available to the optimizers. Pass *createProfileLoaderPass(const std::string &Filename); - struct ProfileInfo { + class ProfileInfo { + protected: + std::map ExecutionCounts; + public: virtual ~ProfileInfo(); // We want to be subclassed //===------------------------------------------------------------------===// /// Profile Information Queries /// - virtual unsigned getExecutionCount(BasicBlock *BB) = 0; + unsigned getExecutionCount(BasicBlock *BB) { + std::map::iterator I = ExecutionCounts.find(BB); + return I != ExecutionCounts.end() ? I->second : 0; + } //===------------------------------------------------------------------===// /// Analysis Update Methods From lattner at cs.uiuc.edu Mon Mar 8 15:31:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 15:31:06 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ProfileInfo.cpp ProfileInfoLoaderPass.cpp Message-ID: <200403082130.PAA17039@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ProfileInfo.cpp updated: 1.3 -> 1.4 ProfileInfoLoaderPass.cpp updated: 1.3 -> 1.4 --- Log message: Refactor implementations --- Diffs of the changes: (+3 -10) Index: llvm/lib/Analysis/ProfileInfo.cpp diff -u llvm/lib/Analysis/ProfileInfo.cpp:1.3 llvm/lib/Analysis/ProfileInfo.cpp:1.4 --- llvm/lib/Analysis/ProfileInfo.cpp:1.3 Wed Feb 11 00:10:18 2004 +++ llvm/lib/Analysis/ProfileInfo.cpp Mon Mar 8 15:30:35 2004 @@ -29,9 +29,7 @@ // namespace { - struct NoProfileInfo : public ImmutablePass, public ProfileInfo { - unsigned getExecutionCount(BasicBlock *BB) { return 0; } - }; + struct NoProfileInfo : public ImmutablePass, public ProfileInfo {}; // Register this pass... RegisterOpt Index: llvm/lib/Analysis/ProfileInfoLoaderPass.cpp diff -u llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.3 llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.4 --- llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.3 Wed Feb 11 13:14:04 2004 +++ llvm/lib/Analysis/ProfileInfoLoaderPass.cpp Mon Mar 8 15:30:35 2004 @@ -26,7 +26,6 @@ class LoaderPass : public Pass, public ProfileInfo { std::string Filename; - std::map ExecutionCounts; public: LoaderPass(const std::string &filename = "") : Filename(filename) { @@ -43,11 +42,6 @@ /// run - Load the profile information from the specified file. virtual bool run(Module &M); - - virtual unsigned getExecutionCount(BasicBlock *BB) { - std::map::iterator I = ExecutionCounts.find(BB); - return I != ExecutionCounts.end() ? I->second : 0; - } }; RegisterOpt @@ -65,7 +59,8 @@ } bool LoaderPass::run(Module &M) { - ProfileInfoLoader PIL("opt", Filename, M); + ProfileInfoLoader PIL("profile-loader", Filename, M); + ExecutionCounts.clear(); if (PIL.hasAccurateBlockCounts()) { std::vector > Counts; PIL.getBlockCounts(Counts); From lattner at cs.uiuc.edu Mon Mar 8 16:04:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 16:04:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ProfileInfo.h Message-ID: <200403082203.QAA20400@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ProfileInfo.h updated: 1.3 -> 1.4 --- Log message: Switch over to using edge profile information as the basic profiling representation, from basic block counts. --- Diffs of the changes: (+18 -10) Index: llvm/include/llvm/Analysis/ProfileInfo.h diff -u llvm/include/llvm/Analysis/ProfileInfo.h:1.3 llvm/include/llvm/Analysis/ProfileInfo.h:1.4 --- llvm/include/llvm/Analysis/ProfileInfo.h:1.3 Mon Mar 8 15:30:18 2004 +++ llvm/include/llvm/Analysis/ProfileInfo.h Mon Mar 8 16:03:45 2004 @@ -28,31 +28,39 @@ class BasicBlock; class Pass; - /// createProfileLoaderPass - This function returns a Pass that loads the - /// profiling information for the module from the specified filename, making - /// it available to the optimizers. - Pass *createProfileLoaderPass(const std::string &Filename); - + /// ProfileInfo Class - This class holds and maintains edge profiling + /// information for some unit of code. class ProfileInfo { protected: - std::map ExecutionCounts; + // EdgeCounts - Count the number of times a transition between two blocks is + // executed. As a special case, we also hold an edge from the null + // BasicBlock to the entry block to indicate how many times the function was + // entered. + std::map, unsigned> EdgeCounts; public: virtual ~ProfileInfo(); // We want to be subclassed //===------------------------------------------------------------------===// /// Profile Information Queries /// - unsigned getExecutionCount(BasicBlock *BB) { - std::map::iterator I = ExecutionCounts.find(BB); - return I != ExecutionCounts.end() ? I->second : 0; + unsigned getExecutionCount(BasicBlock *BB) const; + + unsigned getEdgeWeight(BasicBlock *Src, BasicBlock *Dest) const { + std::map, unsigned>::const_iterator I= + EdgeCounts.find(std::make_pair(Src, Dest)); + return I != EdgeCounts.end() ? I->second : 0; } - + //===------------------------------------------------------------------===// /// Analysis Update Methods /// }; + /// createProfileLoaderPass - This function returns a Pass that loads the + /// profiling information for the module from the specified filename, making + /// it available to the optimizers. + Pass *createProfileLoaderPass(const std::string &Filename); } // End llvm namespace #endif From lattner at cs.uiuc.edu Mon Mar 8 16:05:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 16:05:05 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ProfileInfo.cpp ProfileInfoLoaderPass.cpp Message-ID: <200403082204.QAA20421@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ProfileInfo.cpp updated: 1.4 -> 1.5 ProfileInfoLoaderPass.cpp updated: 1.4 -> 1.5 --- Log message: Switch to using edge profiling information as the basic source of profile info from using basic block counts. --- Diffs of the changes: (+73 -5) Index: llvm/lib/Analysis/ProfileInfo.cpp diff -u llvm/lib/Analysis/ProfileInfo.cpp:1.4 llvm/lib/Analysis/ProfileInfo.cpp:1.5 --- llvm/lib/Analysis/ProfileInfo.cpp:1.4 Mon Mar 8 15:30:35 2004 +++ llvm/lib/Analysis/ProfileInfo.cpp Mon Mar 8 16:04:08 2004 @@ -14,6 +14,8 @@ #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Pass.h" +#include "llvm/Support/CFG.h" +#include using namespace llvm; // Register the ProfileInfo interface, providing a nice name to refer to. @@ -22,6 +24,56 @@ } ProfileInfo::~ProfileInfo() {} + +unsigned ProfileInfo::getExecutionCount(BasicBlock *BB) const { + pred_iterator PI = pred_begin(BB), PE = pred_end(BB); + + // Are there zero predecessors of this block? + if (PI == PE) { + // If this is the entry block, look for the Null -> Entry edge. + if (BB == &BB->getParent()->front()) + return getEdgeWeight(0, BB); + else + return 0; // Otherwise, this is a dead block. + } + + // Otherwise, if there are predecessors, the execution count of this block is + // the sum of the edge frequencies from the incoming edges. Note that if + // there are multiple edges from a predecessor to this block that we don't + // want to count its weight multiple times. For this reason, we keep track of + // the predecessors we've seen and only count them if we haven't run into them + // yet. + // + // We don't want to create an std::set unless we are dealing with a block that + // has a LARGE number of in-edges. Handle the common case of having only a + // few in-edges with special code. + // + BasicBlock *FirstPred = *PI; + unsigned Count = getEdgeWeight(FirstPred, BB); + ++PI; + if (PI == PE) return Count; // Quick exit for single predecessor blocks + + BasicBlock *SecondPred = *PI; + if (SecondPred != FirstPred) Count += getEdgeWeight(SecondPred, BB); + ++PI; + if (PI == PE) return Count; // Quick exit for two predecessor blocks + + BasicBlock *ThirdPred = *PI; + if (ThirdPred != FirstPred && ThirdPred != SecondPred) + Count += getEdgeWeight(ThirdPred, BB); + ++PI; + if (PI == PE) return Count; // Quick exit for three predecessor blocks + + std::set ProcessedPreds; + ProcessedPreds.insert(FirstPred); + ProcessedPreds.insert(SecondPred); + ProcessedPreds.insert(ThirdPred); + for (; PI != PE; ++PI) + if (ProcessedPreds.insert(*PI).second) + Count += getEdgeWeight(*PI, BB); + return Count; +} + //===----------------------------------------------------------------------===// Index: llvm/lib/Analysis/ProfileInfoLoaderPass.cpp diff -u llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.4 llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.5 --- llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.4 Mon Mar 8 15:30:35 2004 +++ llvm/lib/Analysis/ProfileInfoLoaderPass.cpp Mon Mar 8 16:04:08 2004 @@ -12,6 +12,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/BasicBlock.h" +#include "llvm/InstrTypes.h" #include "llvm/Pass.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Analysis/ProfileInfoLoader.h" @@ -60,11 +62,25 @@ bool LoaderPass::run(Module &M) { ProfileInfoLoader PIL("profile-loader", Filename, M); - ExecutionCounts.clear(); - if (PIL.hasAccurateBlockCounts()) { - std::vector > Counts; - PIL.getBlockCounts(Counts); - ExecutionCounts.insert(Counts.begin(), Counts.end()); + EdgeCounts.clear(); + bool PrintedWarning = false; + + std::vector > ECs; + PIL.getEdgeCounts(ECs); + for (unsigned i = 0, e = ECs.size(); i != e; ++i) { + BasicBlock *BB = ECs[i].first.first; + unsigned SuccNum = ECs[i].first.second; + TerminatorInst *TI = BB->getTerminator(); + if (SuccNum >= TI->getNumSuccessors()) { + if (!PrintedWarning) { + std::cerr << "WARNING: profile information is inconsistent with " + << "the current program!\n"; + PrintedWarning = true; + } + } else { + EdgeCounts[std::make_pair(BB, TI->getSuccessor(SuccNum))]+= ECs[i].second; + } } + return false; } From lattner at cs.uiuc.edu Mon Mar 8 16:30:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 16:30:01 2004 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200403082229.QAA21473@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.15 -> 1.16 --- Log message: Update the profiling section --- Diffs of the changes: (+23 -6) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.15 llvm/docs/OpenProjects.html:1.16 --- llvm/docs/OpenProjects.html:1.15 Sun Dec 28 17:04:17 2003 +++ llvm/docs/OpenProjects.html Mon Mar 8 16:29:35 2004 @@ -229,11 +229,11 @@
-

We are getting to the point where we really need a unified infrastructure for -profile guided optimizations. It would be wonderful to be able to write profile -guided transformations which can be performed either at static compile time -(compile time or offline optimization time) or at runtime in a JIT type setup. -The LLVM transformation itself shouldn't need to know how it is being used.

+

We now have a unified infrastructure for writing profile-guided +transformations, which will work either at offline-compile-time or in the JIT, +but we don't have many transformations. We would welcome new profile-guided +transformations as well as improvements to the current profiling system. +

Ideas for profile guided transformations:

@@ -245,6 +245,23 @@
  • ...
  • +

    Improvements to the existing support:

    + +
      +
    1. The current block and edge profiling code that gets inserted is very simple +and inefficient. Through the use of control-dependence information, many fewer +counters could be inserted into the code. Also, if the execution count of a +loop is known to be a compile-time or runtime constant, all of the counters in +the loop could be avoided.
    2. + +
    3. You could implement one of the "static profiling" algorithms which analyze a +piece of code an make educated guesses about the relative execution frequencies +of various parts of the code.
    4. + +
    5. You could add path profiling support, or adapt the existing LLVM path +profiling code to work with the generic profiling interfaces.
    6. +
    +
    @@ -302,7 +319,7 @@
    Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2003/12/28 23:04:17 $ + Last modified: $Date: 2004/03/08 22:29:35 $ From gaeke at cs.uiuc.edu Mon Mar 8 16:47:27 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 16:47:27 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp Message-ID: <200403082246.QAA08995@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.cpp updated: 1.22 -> 1.23 --- Log message: Move ReturnBlockForTraceExit inside of TraceFunction. Make TF be a member of the TraceToFunction method object. Fix a bug in fixupFunctionBodyBB() where we were passing a null Function * to the BasicBlock ctor, causing us to failing an assertion. Fix some indentation. --- Diffs of the changes: (+6 -7) Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp diff -u reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.22 reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.23 --- reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.22 Tue Feb 10 13:17:15 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.cpp Mon Mar 8 16:46:29 2004 @@ -51,11 +51,10 @@ typedef std::map ValueMap; typedef std::map BranchNumberMap; -BasicBlockMap ReturnBlockForTraceExit; - class TraceToFunction { ValueToIntMap LiveInToParameterMap; BranchNumberMap BranchNumber; + TraceFunction *TF; virtual TypeVector createFunctionArgTypeVector (PointerType *ST, LiveVariableSet S); virtual void fillInFunctionBody (Trace &T, Function *F, LiveVariableSet &So); @@ -422,7 +421,7 @@ // the function. So create new entry basic block to serve as source // for old entry's initial phi node. if (srcB == T.getEntryBasicBlock ()) { - BasicBlock *FEntry = new BasicBlock ("entryfixup", 0, dstB); + BasicBlock *FEntry = new BasicBlock ("entryfixup", F, dstB); FEntry->getInstList ().push_back (new BranchInst (dstB)); // Replace the references to the trace's predecessor with a // reference to FEntry now. This is kind of a dodge because we @@ -462,9 +461,9 @@ BasicBlock *FB = new BasicBlock (name, F); // Change BI's clone's destination to FB. BIinF->setSuccessor (i, FB); - // Remember that FB's "return" instruction would involve a - // return to the off-trace successor we just found. - ReturnBlockForTraceExit[FB] = BI->getSuccessor (i); + // Remember that FB's "return" instruction would involve a + // return to the off-trace successor we just found. + TF->ReturnBlockForTraceExit[FB] = BI->getSuccessor (i); // Add the getelementptr/store instruction pairs here that // correspond to each live-out variable. unsigned Slot = 0; @@ -563,7 +562,7 @@ TraceFunction *TraceToFunction::traceToFunction (Trace &T) { // Create a TraceFunction object to hold the trace function along with // its auxiliary data structures. - TraceFunction *TF = new TraceFunction (T); + TF = new TraceFunction (T); std::string CurrentFnName = T.getFunction ()->getName (); DEBUG(std::cerr << "In traceToFunction() for " << CurrentFnName << "\n"); From gaeke at cs.uiuc.edu Mon Mar 8 16:49:11 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 16:49:11 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.h Message-ID: <200403082247.QAA09104@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.h updated: 1.4 -> 1.5 --- Log message: Move ReturnBlockForTraceExit inside of TraceFunction. Fix some comments. --- Diffs of the changes: (+8 -6) Index: reopt/lib/LightWtProfiling/TraceToFunction.h diff -u reopt/lib/LightWtProfiling/TraceToFunction.h:1.4 reopt/lib/LightWtProfiling/TraceToFunction.h:1.5 --- reopt/lib/LightWtProfiling/TraceToFunction.h:1.4 Fri Jan 16 12:44:35 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.h Mon Mar 8 16:46:54 2004 @@ -18,12 +18,9 @@ typedef std::set LiveVariableSet; typedef std::map BasicBlockMap; -// FIXME: this should definitely be part of TraceFunction. -extern BasicBlockMap ReturnBlockForTraceExit; - -// It's not clear whether this should be part of Trace or not. Logically, you -// can't have a TraceFunction without a Trace, but you might not want all the -// TraceFunction baggage if you just want a Trace. +// This class encapsulates all the TraceToFunction algorithm's saved baggage. +// You can't have a TraceFunction without a Trace, but you might be able to +// get away with using a Trace instead of this class in new code. struct TraceFunction { /// Function that contains the trace /// @@ -56,6 +53,11 @@ /// along with its Live-In and Live-Out variable sets. /// static TraceFunction *get (Trace &T); + + /// Map of basic blocks containing return instructions in TraceFn --> + /// basic blocks that they are supposed to return to in MatrixFn. + /// + BasicBlockMap ReturnBlockForTraceExit; }; class FunctionPass; From gaeke at cs.uiuc.edu Mon Mar 8 16:50:20 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 16:50:20 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Message-ID: <200403082247.QAA09111@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: UnpackTraceFunction.cpp updated: 1.40 -> 1.41 --- Log message: Make OperandAllocState's Instruction into an int, so that we can make arguments be "Instruction" number -1. Add new getNumberOfFunctionArg(). Get rid of commented-out code, incl. getSavedStateIndexOfOperandInInstruction(). Teach getValueAllocStateFromModule() and getValueAllocStateFromGlobal to get the AllocStates of Arguments. Add more DEBUG print statements. Move ReturnBlockForTraceExit inside of TraceFunction. --- Diffs of the changes: (+53 -34) Index: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp diff -u reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.40 reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.41 --- reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.40 Mon Mar 1 15:20:02 2004 +++ reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Mon Mar 8 16:46:55 2004 @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/IntrinsicLowering.h" #include "llvm/Module.h" +#include "llvm/Argument.h" #include "llvm/Support/InstIterator.h" #include "Support/Debug.h" #include "reopt/MappingInfo.h" @@ -133,7 +134,7 @@ extern "C" { struct OperandAllocState { - unsigned Instruction; + int Instruction; int Operand; unsigned AllocState; int Placement; @@ -180,17 +181,16 @@ abort (); } -#if 0 -static unsigned getSavedStateIndexOfOperandInInstruction (Function *F, Value *V, - unsigned VI) { - // FIXME; not yet implemented - DEBUG(std::cerr << "getSavedStateIndexOfOperandInInstruction(F = " - << F->getName() << "(), V = " << *V <<", VI = " << VI << ")\n"); - std::cerr - << "** getSavedStateIndexOfOperandInInstruction() NOT YET IMPLEMENTED **\n"; +static int getNumberOfFunctionArg (const Function *F, const Argument *Arg) +{ + int ArgNum = 0; + for (Function::const_aiterator i = F->abegin (), e = F->aend (); i != e; ++i){ + if (Arg == &*i) return ArgNum; + ++ArgNum; + } + std::cerr << "ERROR: getNumberOfFunctionArg couldn't find arg\n"; abort (); } -#endif /// Returns the register number or stack position where V can be found in the /// machine code for the function F, which it finds by searching the global @@ -198,22 +198,27 @@ /// previous invocation of llc. /// static AllocInfo getValueAllocStateFromModule (Function *F, Value *V) { - // Figure out the indices (FI, VI, VO) that can be used to look up V, which - // is an operand of some instruction in F, in _llvm_regAllocState: - Instruction *Instr = cast (V); unsigned FI = getLLVMFunctionPositionInfo (F); - unsigned VI = getSavedStateIndexOfInstruction (F, Instr); - //int VO = getSavedStateIndexOfOperandInInstruction (F, V, VI); + FunctionAllocState *FAllocState = _llvm_regAllocState.functions[FI]; + int InstructionKey = -1, OperandKey = -1; + if (Argument *A = dyn_cast (V)) { + // Find the alloc state of an argument. + OperandKey = getNumberOfFunctionArg (F, A); + } else { + // Figure out the indices (FI, VI, VO) that can be used to look up V, which + // is an operand of some instruction in F, in _llvm_regAllocState: + Instruction *Instr = cast (V); + InstructionKey = getSavedStateIndexOfInstruction (F, Instr); + } // Reconstruct the AllocInfo for V by searching // _llvm_regAllocState.functions[FI] for a tuple that starts with - // (VI, VO, ...): - FunctionAllocState *FAllocState = _llvm_regAllocState.functions[FI]; + // (InstructionKey, OperandKey, ...): for (unsigned i = 0; i < FAllocState->numTuples; ++i) { - OperandAllocState &T = FAllocState->tuples[VI]; - if (T.Instruction == VI && T.Operand == 0) - return AllocInfo (T.Instruction, T.Operand, - (AllocInfo::AllocStateTy) T.AllocState, - T.Placement); + OperandAllocState &T = FAllocState->tuples[i]; + if (T.Instruction == InstructionKey && T.Operand == OperandKey) + return AllocInfo (T.Instruction, T.Operand, + (AllocInfo::AllocStateTy) T.AllocState, + T.Placement); } // By this time we had better have found it, otherwise we are about to do bad // things. @@ -228,18 +233,24 @@ /// variable ExportedFnAllocState exported by PhyRegAlloc.cpp. /// static AllocInfo getValueAllocStateFromGlobal (Function *F, Value *V) { - Instruction *Instr = cast (V); + unsigned FI = getLLVMFunctionPositionInfo (F); // Get the saved PhyRegAlloc state for F out of ExportedFnAllocState: std::vector &FState = ExportedFnAllocState[F]; - // Figure out the indices (VI, VO) that can be used to look up V, which is an - // operand of some instruction in F, in FState: - unsigned VI = getSavedStateIndexOfInstruction (F, Instr); - //int VO = getSavedStateIndexOfOperandInInstruction (F, V, VI); - // Retrieve the AllocInfo for V by searching FState for a tuple that starts - // with (VI, VO, ...): + int InstructionKey = -1, OperandKey = -1; + if (Argument *A = dyn_cast (V)) { + // Find the alloc state of an argument. + OperandKey = getNumberOfFunctionArg (F, A); + } else { + // Figure out the indices (VI, VO) that can be used to look up V, + // which is an operand of some instruction in F, in FState: + Instruction *Instr = cast (V); + InstructionKey = getSavedStateIndexOfInstruction (F, Instr); + } + // Reconstruct the AllocInfo for V by searching + // FState for a tuple that starts with (InstructionKey, OperandKey, ...): for (unsigned i = 0, s = FState.size (); i < s; ++i) { AllocInfo &T = FState[i]; - if (T.Instruction == VI && T.Operand == 0) + if (T.Instruction == InstructionKey && T.Operand == OperandKey) return T; } // By this time we had better have found it, otherwise we are about to do bad @@ -250,6 +261,7 @@ abort (); } + } // end namespace llvm ///------------------End SPARC register allocator-specific code -------------/// @@ -310,26 +322,33 @@ if (MF.getFunction () != TF->TraceFn) return false; + DEBUG(std::cerr << "In UnpackTraceFunction for " << MF.getFunction()->getName() << "()\n"); + Function *TraceF = TF->TraceFn, *MatrixF = TF->MatrixFn; LiveVariableSet &Si = TF->LiveInSet, &So = TF->LiveOutSet; // Modify ENTRY MachineBasicBlock of MF MachineBasicBlock &E = MF.front (); // E = Entry MBB of MF std::vector EntryCopies; + DEBUG(std::cerr << "UnpackTraceFunction: Modifying entry BB\n"); for (LiveVariableSet::iterator SI = Si.begin (), SE = Si.end (); SI != SE; ++SI) { // Insert copies from each live-in variable's reg. in the matrix fn. // to its reg. in the trace. Value *V = *SI; + DEBUG(std::cerr << "UnpackTraceFunction: Looking for alloc state for value: \n" << *V << "\n"); AllocInfo Source = getValueAllocStateFromModule (MatrixF, V); + DEBUG(std::cerr << "UnpackTraceFunction: Source = " << Source << "\n"); AllocInfo Target = getValueAllocStateFromGlobal (TraceF, V); + DEBUG(std::cerr << "UnpackTraceFunction: Target = " << Target << "\n"); if (Source != Target) EntryCopies.push_back (CopyInfo (Source, Target, &E, V->getType ())); } + DEBUG(std::cerr << "UnpackTraceFunction: Inserting copy MachineInstrs:\n"); for (std::vector::iterator i = EntryCopies.begin (), e = EntryCopies.end (); i != e; ++i) { - DEBUG(std::cerr << *i); + DEBUG(std::cerr << "UnpackTraceFunction: " << *i); SRI.insertCopyMachineInstrs (i->Src, i->Targ, *i->Blk, i->Ty); } @@ -341,11 +360,11 @@ // code for the MachineBasicBlock in MatrixF that RI would have // returned to. Find it by using MappingInfo. BasicBlock *RBB = const_cast (MBB.getBasicBlock ()); - assert ((ReturnBlockForTraceExit.find (RBB) != - ReturnBlockForTraceExit.end ()) + assert ((TF->ReturnBlockForTraceExit.find (RBB) != + TF->ReturnBlockForTraceExit.end ()) && "Can't find matrix fn BB address to return to from trace"); uint64_t ReturnAddress = - getBasicBlockInfo(ReturnBlockForTraceExit[RBB]).first; + getBasicBlockInfo(TF->ReturnBlockForTraceExit[RBB]).first; // Erase the contents of MBB. while (!MBB.empty ()) { MachineBasicBlock::iterator MBBI = MBB.begin (); From brukman at cs.uiuc.edu Mon Mar 8 17:07:04 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Mar 8 17:07:04 2004 Subject: [llvm-commits] CVS: llvm/docs/WritingAnLLVMPass.html Message-ID: <200403082306.RAA28551@zion.cs.uiuc.edu> Changes in directory llvm/docs: WritingAnLLVMPass.html updated: 1.23 -> 1.24 --- Log message: Fix some spelling and grammar. --- Diffs of the changes: (+4 -4) Index: llvm/docs/WritingAnLLVMPass.html diff -u llvm/docs/WritingAnLLVMPass.html:1.23 llvm/docs/WritingAnLLVMPass.html:1.24 --- llvm/docs/WritingAnLLVMPass.html:1.23 Mon Jan 26 15:26:52 2004 +++ llvm/docs/WritingAnLLVMPass.html Mon Mar 8 17:06:46 2004 @@ -1381,8 +1381,8 @@ timing and debugging the actual loading of the module from disk or standard input.

    -

    To solve this problem, eventually the PassManger class will accept a -ModuleSource object instead of a Module itself. When complete, this +

    To solve this problem, eventually the PassManager class will accept +a ModuleSource object instead of a Module itself. When complete, this will also allow for streaming of functions out of the bytecode representation, allowing us to avoid holding the entire program in memory at once if we only are dealing with FunctionPasses.

    @@ -1396,7 +1396,7 @@
    @@ -1426,7 +1426,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/01/26 21:26:52 $ + Last modified: $Date: 2004/03/08 23:06:46 $ From gaeke at cs.uiuc.edu Mon Mar 8 17:23:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 17:23:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h Message-ID: <200403082322.RAA28834@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: AllocInfo.h updated: 1.6 -> 1.7 --- Log message: Make AllocInfo's Instruction an int, so that we can overload it for arguments. (Instruction #-1's operands = argument list). --- Diffs of the changes: (+4 -4) Index: llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h diff -u llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h:1.6 llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h:1.7 --- llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h:1.6 Wed Jan 28 13:05:43 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h Mon Mar 8 17:22:01 2004 @@ -26,8 +26,8 @@ /// structures to generate mapping information for this register allocator. /// struct AllocInfo { - unsigned Instruction; - int Operand; // (-1 if Instruction, or 0...n-1 for an operand.) + int Instruction; // (-1 if Argument, or 0 .. n - 1 for an instruction). + int Operand; // (-1 if Instruction, or 0 .. n-1 for an operand). enum AllocStateTy { NotAllocated = 0, Allocated, Spilled }; AllocStateTy AllocState; int Placement; @@ -41,7 +41,7 @@ /// static StructType *getConstantType () { std::vector TV; - TV.push_back (Type::UIntTy); + TV.push_back (Type::IntTy); TV.push_back (Type::IntTy); TV.push_back (Type::UIntTy); TV.push_back (Type::IntTy); @@ -54,7 +54,7 @@ Constant *toConstant () const { StructType *ST = getConstantType (); std::vector CV; - CV.push_back (ConstantUInt::get (Type::UIntTy, Instruction)); + CV.push_back (ConstantSInt::get (Type::IntTy, Instruction)); CV.push_back (ConstantSInt::get (Type::IntTy, Operand)); CV.push_back (ConstantUInt::get (Type::UIntTy, AllocState)); CV.push_back (ConstantSInt::get (Type::IntTy, Placement)); From gaeke at cs.uiuc.edu Mon Mar 8 17:23:04 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 17:23:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Message-ID: <200403082322.RAA28841@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: PhyRegAlloc.cpp updated: 1.139 -> 1.140 --- Log message: Save argument list alloc state by recording it as the operands of Instruction #-1. Other minor changes to deal with AllocInfo.Instruction becoming an int. --- Diffs of the changes: (+10 -2) Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.139 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.140 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.139 Sun Feb 29 13:12:43 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Mon Mar 8 17:22:02 2004 @@ -1125,7 +1125,7 @@ void PhyRegAlloc::saveStateForValue (std::vector &state, - const Value *V, unsigned Insn, int Opnd) { + const Value *V, int Insn, int Opnd) { LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap ()->find (V); LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end (); AllocInfo::AllocStateTy AllocState = AllocInfo::NotAllocated; @@ -1155,7 +1155,15 @@ /// void PhyRegAlloc::saveState () { std::vector &state = FnAllocState[Fn]; + unsigned ArgNum = 0; + // Arguments encoded as instruction # -1 + for (Function::const_aiterator i=Fn->abegin (), e=Fn->aend (); i != e; ++i) { + const Argument *Arg = &*i; + saveStateForValue (state, Arg, -1, ArgNum); + ++ArgNum; + } unsigned Insn = 0; + // Instructions themselves encoded as operand # -1 for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II!=IE; ++II){ saveStateForValue (state, (*II), Insn, -1); for (unsigned i = 0; i < (*II)->getNumOperands (); ++i) { @@ -1176,7 +1184,7 @@ /// void PhyRegAlloc::verifySavedState () { std::vector &state = FnAllocState[Fn]; - unsigned Insn = 0; + int Insn = 0; for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II!=IE; ++II) { const Instruction *I = *II; MachineCodeForInstruction &Instrs = MachineCodeForInstruction::get (I); From gaeke at cs.uiuc.edu Mon Mar 8 17:23:07 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 17:23:07 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h Message-ID: <200403082322.RAA28848@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: PhyRegAlloc.h updated: 1.62 -> 1.63 --- Log message: Change PhyRegAlloc::saveStateForValue()'s arg type to deal with AllocInfo.Instruction becoming an int. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.62 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.63 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.62 Tue Nov 11 16:41:33 2003 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h Mon Mar 8 17:22:03 2004 @@ -126,7 +126,7 @@ void buildInterferenceGraphs(); void saveStateForValue (std::vector &state, - const Value *V, unsigned Insn, int Opnd); + const Value *V, int Insn, int Opnd); void saveState(); void verifySavedState(); From lattner at cs.uiuc.edu Mon Mar 8 18:41:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 18:41:02 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200403090040.SAA00307@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.139 -> 1.140 --- Log message: John fixed this bug --- Diffs of the changes: (+2 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.139 llvm/docs/ReleaseNotes.html:1.140 --- llvm/docs/ReleaseNotes.html:1.139 Sun Mar 7 22:55:45 2004 +++ llvm/docs/ReleaseNotes.html Mon Mar 8 18:40:49 2004 @@ -230,6 +230,7 @@
  • [llvm-gcc] miscompilation of 'X = Y = Z' with aggregate values
  • [llvm-gcc] miscompilation when a function is re-declared as static
  • [llvmgcc] Invalid code created for complex division operation
  • +
  • [llvmgcc] Incorrect code generation for pointer subtraction
  • @@ -620,7 +621,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/08 04:55:45 $ + Last modified: $Date: 2004/03/09 00:40:49 $ From lattner at cs.uiuc.edu Mon Mar 8 18:42:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 18:42:01 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.1/docs/ReleaseNotes.html Message-ID: <200403090041.SAA00780@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.1/docs: ReleaseNotes.html updated: 1.30 -> 1.31 --- Log message: John found and fixed this bug --- Diffs of the changes: (+3 -1) Index: llvm-www/releases/1.1/docs/ReleaseNotes.html diff -u llvm-www/releases/1.1/docs/ReleaseNotes.html:1.30 llvm-www/releases/1.1/docs/ReleaseNotes.html:1.31 --- llvm-www/releases/1.1/docs/ReleaseNotes.html:1.30 Sun Mar 7 22:56:20 2004 +++ llvm-www/releases/1.1/docs/ReleaseNotes.html Mon Mar 8 18:41:04 2004 @@ -446,6 +446,8 @@
  • [llvm-gcc] miscompilation when a function is re-declared as static
  • [llvmgcc] Invalid code created for complex division operation
  • + +
  • [llvmgcc] Incorrect code generation for pointer subtraction
  • @@ -756,7 +758,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/08 04:56:20 $ + Last modified: $Date: 2004/03/09 00:41:04 $ From gaeke at cs.uiuc.edu Mon Mar 8 18:44:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 18:44:01 2004 Subject: [llvm-commits] CVS: reopt/test/TEST.reopt.Makefile Message-ID: <200403090043.SAA00831@zion.cs.uiuc.edu> Changes in directory reopt/test: TEST.reopt.Makefile updated: 1.8 -> 1.9 --- Log message: Do not strip debug info, because, well, it makes debugging impossible. What was I thinking? --- Diffs of the changes: (+1 -1) Index: reopt/test/TEST.reopt.Makefile diff -u reopt/test/TEST.reopt.Makefile:1.8 reopt/test/TEST.reopt.Makefile:1.9 --- reopt/test/TEST.reopt.Makefile:1.8 Fri Mar 5 00:00:22 2004 +++ reopt/test/TEST.reopt.Makefile Mon Mar 8 18:43:16 2004 @@ -38,7 +38,7 @@ WHOLE_REOPTIMIZER = $(DESTLIBCURRENT)/wholereoptimizer.o $(WHOLE_REOPTIMIZER): $(REOPTIMIZER_OBJS) $(REOPTIMIZER_LLVMOBJS) - /usr/ccs/bin/ld -s -r -o $@ $+ + /usr/ccs/bin/ld -r -o $@ $+ # Libraries that should be checked for freshness when doing # Reoptimizer tests (http://www.goodegg.com/eggdating.html) From lattner at cs.uiuc.edu Mon Mar 8 18:56:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 18:56:01 2004 Subject: [llvm-commits] CVS: gcc-3.4/gcc/llvm-expand.c Message-ID: <200403090055.SAA00940@zion.cs.uiuc.edu> Changes in directory gcc-3.4/gcc: llvm-expand.c updated: 1.21 -> 1.22 --- Log message: It seems that GCC defines invariants just to break them. Why require the LHS and RHS of an assignment to be the same type, that's just SOOO restricting. *sigh*. This fixes Bug 261. --- Diffs of the changes: (+5 -0) Index: gcc-3.4/gcc/llvm-expand.c diff -u gcc-3.4/gcc/llvm-expand.c:1.21 gcc-3.4/gcc/llvm-expand.c:1.22 --- gcc-3.4/gcc/llvm-expand.c:1.21 Sun Mar 7 22:50:58 2004 +++ gcc-3.4/gcc/llvm-expand.c Mon Mar 8 18:55:07 2004 @@ -5606,6 +5606,11 @@ } else if (DestLoc) { /* Generating structure, using value */ unsigned Align = TYPE_ALIGN(TREE_TYPE(exp))/8; assert(BitSize == 0 && "Invalid bitfield read of composite value!"); + + /* If the destination location is not exactly the same type as the + * source value, cast the destination pointer. + */ + DestLoc = cast_if_type_not_equal(Fn, DestLoc, op0->Ty); llvm_copy_aggregate(Fn, DestLoc, op0, expVolatile, 0, Align); } } From lattner at cs.uiuc.edu Mon Mar 8 18:57:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 18:57:00 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/2004-03-08-ReinterpretCastCopy.cpp Message-ID: <200403090056.SAA00960@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend: 2004-03-08-ReinterpretCastCopy.cpp added (r1.1) --- Log message: Checkin testcase for PR261 --- Diffs of the changes: (+19 -0) Index: llvm/test/Regression/C++Frontend/2004-03-08-ReinterpretCastCopy.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/2004-03-08-ReinterpretCastCopy.cpp:1.1 *** /dev/null Mon Mar 8 18:56:08 2004 --- llvm/test/Regression/C++Frontend/2004-03-08-ReinterpretCastCopy.cpp Mon Mar 8 18:55:58 2004 *************** *** 0 **** --- 1,19 ---- + struct A { + virtual void Method() = 0; + }; + + struct B : public A { + virtual void Method() { } + }; + + typedef void (A::*fn_type_a)(void); + typedef void (B::*fn_type_b)(void); + + int main(int argc, char **argv) + { + fn_type_a f = reinterpret_cast(&B::Method); + fn_type_b g = reinterpret_cast(f); + B b; + (b.*g)(); + return 0; + } From lattner at cs.uiuc.edu Mon Mar 8 19:00:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 19:00:02 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200403090059.SAA01498@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.140 -> 1.141 --- Log message: Bug fixed --- Diffs of the changes: (+2 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.140 llvm/docs/ReleaseNotes.html:1.141 --- llvm/docs/ReleaseNotes.html:1.140 Mon Mar 8 18:40:49 2004 +++ llvm/docs/ReleaseNotes.html Mon Mar 8 18:59:15 2004 @@ -231,6 +231,7 @@
  • [llvm-gcc] miscompilation when a function is re-declared as static
  • [llvmgcc] Invalid code created for complex division operation
  • [llvmgcc] Incorrect code generation for pointer subtraction
  • +
  • [llvmg++] Crash assigning pointers-to-members with casted types
  • @@ -621,7 +622,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/09 00:40:49 $ + Last modified: $Date: 2004/03/09 00:59:15 $ From lattner at cs.uiuc.edu Mon Mar 8 19:00:05 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 19:00:05 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.1/docs/ReleaseNotes.html Message-ID: <200403090059.SAA01955@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.1/docs: ReleaseNotes.html updated: 1.31 -> 1.32 --- Log message: Bug found --- Diffs of the changes: (+4 -1) Index: llvm-www/releases/1.1/docs/ReleaseNotes.html diff -u llvm-www/releases/1.1/docs/ReleaseNotes.html:1.31 llvm-www/releases/1.1/docs/ReleaseNotes.html:1.32 --- llvm-www/releases/1.1/docs/ReleaseNotes.html:1.31 Mon Mar 8 18:41:04 2004 +++ llvm-www/releases/1.1/docs/ReleaseNotes.html Mon Mar 8 18:59:30 2004 @@ -448,6 +448,9 @@
  • [llvmgcc] Invalid code created for complex division operation
  • [llvmgcc] Incorrect code generation for pointer subtraction
  • + +
  • [llvmg++] Crash assigning pointers-to-members with casted types
  • + @@ -758,7 +761,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/09 00:41:04 $ + Last modified: $Date: 2004/03/09 00:59:30 $ From alkis at niobe.cs.uiuc.edu Mon Mar 8 21:31:01 2004 From: alkis at niobe.cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Mar 8 21:31:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86CodeEmitter.cpp Message-ID: <200403090330.i293UMR12733@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86CodeEmitter.cpp updated: 1.55 -> 1.56 --- Log message: Constify things a bit --- Diffs of the changes: (+9 -9) Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.55 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.56 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.55 Sat Feb 28 16:02:05 2004 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Mon Mar 8 21:30:12 2004 @@ -185,10 +185,10 @@ } private: - void emitBasicBlock(MachineBasicBlock &MBB); - void emitInstruction(MachineInstr &MI); + void emitBasicBlock(const MachineBasicBlock &MBB); + void emitInstruction(const MachineInstr &MI); - void emitPCRelativeBlockAddress(BasicBlock *BB); + void emitPCRelativeBlockAddress(const BasicBlock *BB); void emitMaybePCRelativeValue(unsigned Address, bool isPCRelative); void emitGlobalAddressForCall(GlobalValue *GV); void emitGlobalAddressForPtr(GlobalValue *GV); @@ -237,11 +237,11 @@ return false; } -void Emitter::emitBasicBlock(MachineBasicBlock &MBB) { +void Emitter::emitBasicBlock(const MachineBasicBlock &MBB) { if (uint64_t Addr = MCE.getCurrentPCValue()) BasicBlockAddrs[MBB.getBasicBlock()] = Addr; - for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) + for (MachineBasicBlock::const_iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) emitInstruction(*I); } @@ -251,7 +251,7 @@ /// (because this is a forward branch), it keeps track of the information /// necessary to resolve this address later (and emits a dummy value). /// -void Emitter::emitPCRelativeBlockAddress(BasicBlock *BB) { +void Emitter::emitPCRelativeBlockAddress(const BasicBlock *BB) { // FIXME: Emit backward branches directly BBRefs.push_back(std::make_pair(BB, MCE.getCurrentPCValue())); MCE.emitWord(0); // Emit a dummy value @@ -476,7 +476,7 @@ } } -void Emitter::emitInstruction(MachineInstr &MI) { +void Emitter::emitInstruction(const MachineInstr &MI) { NumEmitted++; // Keep track of the # of mi's emitted unsigned Opcode = MI.getOpcode(); @@ -516,7 +516,7 @@ case X86II::RawFrm: MCE.emitByte(BaseOpcode); if (MI.getNumOperands() == 1) { - MachineOperand &MO = MI.getOperand(0); + const MachineOperand &MO = MI.getOperand(0); if (MO.isPCRelativeDisp()) { // Conditional branch... FIXME: this should use an MBB destination! emitPCRelativeBlockAddress(cast(MO.getVRegValue())); @@ -536,7 +536,7 @@ case X86II::AddRegFrm: MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg())); if (MI.getNumOperands() == 2) { - MachineOperand &MO1 = MI.getOperand(1); + const MachineOperand &MO1 = MI.getOperand(1); if (Value *V = MO1.getVRegValueOrNull()) { assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!"); emitGlobalAddressForPtr(cast(V)); From alkis at niobe.cs.uiuc.edu Mon Mar 8 21:36:01 2004 From: alkis at niobe.cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Mar 8 21:36:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86CodeEmitter.cpp X86TargetMachine.h Message-ID: <200403090335.i293Z3C13683@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86CodeEmitter.cpp updated: 1.56 -> 1.57 X86TargetMachine.h updated: 1.22 -> 1.23 --- Log message: Add emitInstruction() API so that we can get the bytes of a simple instruction --- Diffs of the changes: (+20 -3) Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.56 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.57 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.56 Mon Mar 8 21:30:12 2004 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Mon Mar 8 21:34:53 2004 @@ -168,7 +168,6 @@ } - namespace { class Emitter : public MachineFunctionPass { const X86InstrInfo *II; @@ -176,7 +175,9 @@ std::map BasicBlockAddrs; std::vector > BBRefs; public: - Emitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} + explicit Emitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} + Emitter(MachineCodeEmitter &mce, const X86InstrInfo& ii) + : II(&ii), MCE(mce) {} bool runOnMachineFunction(MachineFunction &MF); @@ -184,9 +185,10 @@ return "X86 Machine Code Emitter"; } + void emitInstruction(const MachineInstr &MI); + private: void emitBasicBlock(const MachineBasicBlock &MBB); - void emitInstruction(const MachineInstr &MI); void emitPCRelativeBlockAddress(const BasicBlock *BB); void emitMaybePCRelativeValue(unsigned Address, bool isPCRelative); @@ -201,6 +203,14 @@ unsigned Op, unsigned RegOpcodeField); }; +} + +// This function is required by Printer.cpp to workaround gas bugs +void llvm::X86::emitInstruction(MachineCodeEmitter& mce, + const X86InstrInfo& ii, + const MachineInstr& mi) +{ + Emitter(mce, ii).emitInstruction(mi); } /// addPassesToEmitMachineCode - Add passes to the specified pass manager to get Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.22 llvm/lib/Target/X86/X86TargetMachine.h:1.23 --- llvm/lib/Target/X86/X86TargetMachine.h:1.22 Mon Mar 1 00:43:29 2004 +++ llvm/lib/Target/X86/X86TargetMachine.h Mon Mar 8 21:34:53 2004 @@ -53,6 +53,13 @@ virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out); }; + // this is implemented in X86CodeEmitter.cpp + namespace X86 { + void emitInstruction(MachineCodeEmitter& mce, + const X86InstrInfo& ii, + const MachineInstr& MI); + } + } // End llvm namespace #endif From alkis at niobe.cs.uiuc.edu Mon Mar 8 21:36:04 2004 From: alkis at niobe.cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Mar 8 21:36:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200403090335.i293Zjt13717@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.91 -> 1.92 --- Log message: Use newly added API to emit bytes for instructions that gas misassembles --- Diffs of the changes: (+53 -66) Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.91 llvm/lib/Target/X86/Printer.cpp:1.92 --- llvm/lib/Target/X86/Printer.cpp:1.91 Mon Mar 1 17:53:11 2004 +++ llvm/lib/Target/X86/Printer.cpp Mon Mar 8 21:35:34 2004 @@ -16,12 +16,14 @@ #include "X86.h" #include "X86InstrInfo.h" +#include "X86TargetMachine.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Assembly/Writer.h" -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Mangler.h" @@ -38,6 +40,37 @@ cl::opt EmitCygwin("enable-cygwin-compatible-output", cl::Hidden, cl::desc("Emit X86 assembly code suitable for consumption by cygwin")); + struct GasBugWorkaroundEmitter : public MachineCodeEmitter { + GasBugWorkaroundEmitter(std::ostream& o) + : O(o), OldFlags(O.flags()), firstByte(true) { + O << std::hex; + } + + ~GasBugWorkaroundEmitter() { + O.flags(OldFlags); + O << "\t# "; + } + + virtual void emitByte(unsigned char B) { + if (!firstByte) O << "\n\t"; + firstByte = false; + O << ".byte 0x" << (unsigned) B; + } + + // These should never be called + virtual void emitWord(unsigned W) { assert(0); } + virtual uint64_t getGlobalValueAddress(GlobalValue *V) { assert(0); } + virtual uint64_t getGlobalValueAddress(const std::string &Name) { assert(0); } + virtual uint64_t getConstantPoolEntryAddress(unsigned Index) { assert(0); } + virtual uint64_t getCurrentPCValue() { assert(0); } + virtual uint64_t forceCompilationOf(Function *F) { assert(0); } + + private: + std::ostream& O; + std::ios::fmtflags OldFlags; + bool firstByte; + }; + struct Printer : public MachineFunctionPass { /// Output stream on which we're printing assembly code. /// @@ -768,82 +801,37 @@ const MachineOperand &Op3 = MI->getOperand(3); - // Bug: The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" + // gas bugs: + // + // The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" // is misassembled by gas in intel_syntax mode as its 32-bit // equivalent "fstp DWORD PTR [...]". Workaround: Output the raw // opcode bytes instead of the instruction. - if (MI->getOpcode() == X86::FSTP80m) { - if ((MI->getOperand(0).getReg() == X86::ESP) - && (MI->getOperand(1).getImmedValue() == 1)) { - if (Op3.isImmediate() && - Op3.getImmedValue() >= -128 && Op3.getImmedValue() <= 127) { - // 1 byte disp. - O << ".byte 0xdb, 0x7c, 0x24, 0x" << std::hex - << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# "; - } else { - O << ".byte 0xdb, 0xbc, 0x24\n\t"; - O << ".long "; - printOp(Op3); - O << "\t# "; - } - } - } - - // Bug: The 80-bit FP load instruction "fld XWORD PTR [...]" is + // + // The 80-bit FP load instruction "fld XWORD PTR [...]" is // misassembled by gas in intel_syntax mode as its 32-bit // equivalent "fld DWORD PTR [...]". Workaround: Output the raw // opcode bytes instead of the instruction. - if (MI->getOpcode() == X86::FLD80m && - MI->getOperand(0).getReg() == X86::ESP && - MI->getOperand(1).getImmedValue() == 1) { - if (Op3.isImmediate() && Op3.getImmedValue() >= -128 && - Op3.getImmedValue() <= 127) { // 1 byte displacement - O << ".byte 0xdb, 0x6c, 0x24, 0x" << std::hex - << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# "; - } else { - O << ".byte 0xdb, 0xac, 0x24\n\t"; - O << ".long "; - printOp(Op3); - O << "\t# "; - } - } - - // Bug: gas intel_syntax mode treats "fild QWORD PTR [...]" as an + // + // gas intel_syntax mode treats "fild QWORD PTR [...]" as an // invalid opcode, saying "64 bit operations are only supported in // 64 bit modes." libopcodes disassembles it as "fild DWORD PTR // [...]", which is wrong. Workaround: Output the raw opcode bytes // instead of the instruction. - if (MI->getOpcode() == X86::FILD64m && - MI->getOperand(0).getReg() == X86::ESP && - MI->getOperand(1).getImmedValue() == 1) { - if (Op3.isImmediate() && Op3.getImmedValue() >= -128 && - Op3.getImmedValue() <= 127) { // 1 byte displacement - O << ".byte 0xdf, 0x6c, 0x24, 0x" << std::hex - << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# "; - } else { - O << ".byte 0xdf, 0xac, 0x24\n\t"; - O << ".long "; - printOp(Op3); - O << std::dec << "\t# "; - } + // + // gas intel_syntax mode treats "fistp QWORD PTR [...]" as an + // invalid opcode, saying "64 bit operations are only supported in + // 64 bit modes." libopcodes disassembles it as "fistpll DWORD PTR + // [...]", which is wrong. Workaround: Output the raw opcode bytes + // instead of the instruction. + if (MI->getOpcode() == X86::FSTP80m || + MI->getOpcode() == X86::FLD80m || + MI->getOpcode() == X86::FILD64m || + MI->getOpcode() == X86::FISTP64m) { + GasBugWorkaroundEmitter gwe(O); + X86::emitInstruction(gwe, (X86InstrInfo&)TM.getInstrInfo(), *MI); } - // Bug: gas intel_syntax mode treats "fistp QWORD PTR [...]" as - // an invalid opcode, saying "64 bit operations are only - // supported in 64 bit modes." libopcodes disassembles it as - // "fistpll DWORD PTR [...]", which is wrong. Workaround: Output - // "fistpll DWORD PTR " instead, which is what libopcodes is - // expecting to see. - if (MI->getOpcode() == X86::FISTP64m) { - O << "fistpll DWORD PTR "; - printMemReference(MI, 0); - if (MI->getNumOperands() == 5) { - O << ", "; - printOp(MI->getOperand(4)); - } - O << "\t# "; - } - O << TII.getName(MI->getOpcode()) << " "; O << sizePtr(Desc) << " "; printMemReference(MI, 0); @@ -854,7 +842,6 @@ O << "\n"; return; } - default: O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, TM); break; } From alkis at niobe.cs.uiuc.edu Mon Mar 8 21:39:01 2004 From: alkis at niobe.cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Mar 8 21:39:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200403090338.i293c5H13809@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.59 -> 1.60 --- Log message: Differentiate between extended precision floats (80-bit) and double precision floats (64-bit) --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.59 llvm/lib/Target/X86/X86InstrInfo.td:1.60 --- llvm/lib/Target/X86/X86InstrInfo.td:1.59 Sat Mar 6 21:19:11 2004 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Mar 8 21:37:54 2004 @@ -53,7 +53,7 @@ def Mem16 : MemType<2>; def Mem32 : MemType<3>; def Mem64 : MemType<4>; -def Mem80 : MemType<4>; +def Mem80 : MemType<5>; def Mem128 : MemType<6>; // FPFormat - This specifies what form this FP instruction has. This is used by From gaeke at cs.uiuc.edu Mon Mar 8 22:50:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 22:50:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/InstSelectSimple.cpp Message-ID: <200403090449.WAA28188@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: InstSelectSimple.cpp updated: 1.5 -> 1.6 --- Log message: Hmm, who left this sitting around in my tree --- Diffs of the changes: (+4 -4) Index: llvm/lib/Target/SparcV8/InstSelectSimple.cpp diff -u llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.5 llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.6 --- llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.5 Fri Mar 5 23:32:28 2004 +++ llvm/lib/Target/SparcV8/InstSelectSimple.cpp Mon Mar 8 22:49:13 2004 @@ -125,10 +125,10 @@ RegMap.erase(V); // Assign a new name to this constant if ref'd again } else if (GlobalValue *GV = dyn_cast(V)) { // Move the address of the global into the register - // X86 does: - // BuildMI(*MBB, IPt, V8::ORrr, 2, Reg).addReg(G0).addGlobalAddress(GV); - // We need to use SETHI and OR. - assert (0 && "Can't move address of global yet"); + unsigned TmpReg = makeAnotherReg(V->getType()); + BuildMI (*MBB, IPt, V8::SETHIi, 1, TmpReg).addGlobalAddress (GV); + BuildMI (*MBB, IPt, V8::ORri, 2, Reg).addReg (TmpReg) + .addGlobalAddress (GV); RegMap.erase(V); // Assign a new name to this address if ref'd again } From gaeke at cs.uiuc.edu Mon Mar 8 23:23:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 23:23:01 2004 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/Intercept.cpp Message-ID: <200403090522.XAA00373@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: Intercept.cpp updated: 1.13 -> 1.14 --- Log message: Address PR274 - '[JIT] Programs cannot resolve the fstat function' by trying to get the compiler to generate an undefined reference for it and related functions which live in libc_nonshared.a on Linux. Linkers... sigh. --- Diffs of the changes: (+18 -0) Index: llvm/lib/ExecutionEngine/JIT/Intercept.cpp diff -u llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.13 llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.14 --- llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.13 Fri Dec 26 00:13:47 2003 +++ llvm/lib/ExecutionEngine/JIT/Intercept.cpp Mon Mar 8 23:22:10 2004 @@ -18,6 +18,7 @@ #include "JIT.h" #include "Support/DynamicLinker.h" #include +#include using namespace llvm; // AtExitHandlers - List of functions to call when the program exits, @@ -39,6 +40,23 @@ //===----------------------------------------------------------------------===// // Function stubs that are invoked instead of certain library calls //===----------------------------------------------------------------------===// + +// Force the following functions to be linked in to anything that uses the +// JIT. This is a hack designed to work around the all-too-clever Glibc +// strategy of making these functions work differently when inlined vs. when +// not inlined, and hiding their real definitions in a separate archive file +// that the dynamic linker can't see. For more info, search for +// 'libc_nonshared.a' on Google, or read http://llvm.cs.uiuc.edu/PR274. +void *FunctionPointers[] = { + (void *) stat, + (void *) stat64, + (void *) fstat, + (void *) fstat64, + (void *) lstat, + (void *) lstat64, + (void *) atexit, + (void *) mknod +}; // NoopFn - Used if we have nothing else to call... static void NoopFn() {} From gaeke at cs.uiuc.edu Mon Mar 8 23:41:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 23:41:01 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.1/docs/ReleaseNotes.html Message-ID: <200403090540.XAA00847@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.1/docs: ReleaseNotes.html updated: 1.32 -> 1.33 --- Log message: b00g found --- Diffs of the changes: (+2 -1) Index: llvm-www/releases/1.1/docs/ReleaseNotes.html diff -u llvm-www/releases/1.1/docs/ReleaseNotes.html:1.32 llvm-www/releases/1.1/docs/ReleaseNotes.html:1.33 --- llvm-www/releases/1.1/docs/ReleaseNotes.html:1.32 Mon Mar 8 18:59:30 2004 +++ llvm-www/releases/1.1/docs/ReleaseNotes.html Mon Mar 8 23:40:35 2004 @@ -395,6 +395,7 @@
  • [inliner] Error inlining intrinsic calls into invoke instructions
  • Linking weak and strong global variables is dependent on link order
  • [X86] Missing cast from ULong -> Double, cast FP -> bool and support for -9223372036854775808
  • +
  • [JIT] Programs cannot resolve the fstat function
  • @@ -761,7 +762,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/09 00:59:30 $ + Last modified: $Date: 2004/03/09 05:40:35 $ From lattner at cs.uiuc.edu Mon Mar 8 23:43:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 23:43:01 2004 Subject: [llvm-commits] CVS: llvm-www/Features.html Message-ID: <200403090542.XAA01473@zion.cs.uiuc.edu> Changes in directory llvm-www: Features.html updated: 1.4 -> 1.5 --- Log message: Update features --- Diffs of the changes: (+12 -5) Index: llvm-www/Features.html diff -u llvm-www/Features.html:1.4 llvm-www/Features.html:1.5 --- llvm-www/Features.html:1.4 Wed Dec 17 21:08:50 2003 +++ llvm-www/Features.html Mon Mar 8 23:42:42 2004 @@ -2,14 +2,16 @@
    LLVM Features

    -The public release of LLVM is intended to be a fully functional release of our +The public release of LLVM is a fully functional release of our compiler system for C and C++. As such, it includes the following:

    • Front-ends for C and C++ based on GCC 3.4. They support the full - ANSI-standard C and C++ languages, plus many GCC extensions. + ANSI-standard C and C++ languages, plus many GCC extensions. LLVM + also includes a front-end for "Stacker" a + Forth-like language.
    • @@ -19,7 +21,8 @@
    • A link-time interprocedural optimization framework with a rich set of analyses and transformations, including sophisticated whole-program pointer - analysis and call graph construction. + analysis, call graph construction, and support for profile-guided + optimizations.
    • @@ -36,11 +39,11 @@
    • - A simple profiling system, similar to gprof. + A profiling system similar to gprof.
    • - A test framework with a number of benchmark codes and some applications. + A test framework with a number of benchmark codes and applications.
    • @@ -77,6 +80,10 @@
    • An instructor (or other person) interested in a system for quick prototyping of compiler transformations. +
    • + +
    • + An end-user who wants to get better performance out of your code.
    From gaeke at cs.uiuc.edu Mon Mar 8 23:45:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Mar 8 23:45:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200403090544.XAA01850@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.141 -> 1.142 --- Log message: b00g fixed --- Diffs of the changes: (+2 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.141 llvm/docs/ReleaseNotes.html:1.142 --- llvm/docs/ReleaseNotes.html:1.141 Mon Mar 8 18:59:15 2004 +++ llvm/docs/ReleaseNotes.html Mon Mar 8 23:43:59 2004 @@ -215,6 +215,7 @@
  • Linking weak and strong global variables is dependent on link order
  • Variables used to define non-printable FP constants are externally visible
  • CBE gives linkonce functions wrong linkage semantics
  • +
  • [JIT] Programs cannot resolve the fstat function
  • @@ -622,7 +623,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/09 00:59:15 $ + Last modified: $Date: 2004/03/09 05:43:59 $ From lattner at cs.uiuc.edu Mon Mar 8 23:45:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 8 23:45:04 2004 Subject: [llvm-commits] CVS: llvm-www/Features.html Message-ID: <200403090544.XAA02410@zion.cs.uiuc.edu> Changes in directory llvm-www: Features.html updated: 1.5 -> 1.6 --- Log message: More updates --- Diffs of the changes: (+5 -4) Index: llvm-www/Features.html diff -u llvm-www/Features.html:1.5 llvm-www/Features.html:1.6 --- llvm-www/Features.html:1.5 Mon Mar 8 23:42:42 2004 +++ llvm-www/Features.html Mon Mar 8 23:44:19 2004 @@ -2,15 +2,16 @@
    LLVM Features

    -The public release of LLVM is a fully functional release of our -compiler system for C and C++. As such, it includes the following: +The public release of LLVM is a fully functional +release of our compiler system for C and C++. As such, it includes the +following:

    • - Front-ends for C and C++ based on GCC 3.4. They support the full + Front-ends for C and C++ based on the GCC 3.4 parser. They support the full ANSI-standard C and C++ languages, plus many GCC extensions. LLVM - also includes a front-end for "Stacker" a + also includes a front-end for "Stacker", a Forth-like language.
    • From alkis at cs.uiuc.edu Tue Mar 9 00:11:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Tue Mar 9 00:11:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200403090610.AAA02978@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.92 -> 1.93 --- Log message: Check if printing of implicit uses is required for all types of shift instructions. --- Diffs of the changes: (+3 -0) Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.92 llvm/lib/Target/X86/Printer.cpp:1.93 --- llvm/lib/Target/X86/Printer.cpp:1.92 Mon Mar 8 21:35:34 2004 +++ llvm/lib/Target/X86/Printer.cpp Tue Mar 9 00:10:15 2004 @@ -668,6 +668,7 @@ O << ", "; printOp(MI->getOperand(2)); } + checkImplUses(Desc); O << "\n"; return; } @@ -689,6 +690,7 @@ O << ", "; printOp(MI->getOperand(5)); } + checkImplUses(Desc); O << "\n"; return; } @@ -839,6 +841,7 @@ O << ", "; printOp(MI->getOperand(4)); } + checkImplUses(Desc); O << "\n"; return; } From gaeke at cs.uiuc.edu Tue Mar 9 01:21:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Mar 9 01:21:01 2004 Subject: [llvm-commits] CVS: llvm/docs/LLVMVsTheWorld.html Message-ID: <200403090720.BAA14442@zion.cs.uiuc.edu> Changes in directory llvm/docs: LLVMVsTheWorld.html updated: 1.6 -> 1.7 --- Log message: Now that I read it again, this part in particular strikes me as kind of pushy and contentious... --- Diffs of the changes: (+2 -2) Index: llvm/docs/LLVMVsTheWorld.html diff -u llvm/docs/LLVMVsTheWorld.html:1.6 llvm/docs/LLVMVsTheWorld.html:1.7 --- llvm/docs/LLVMVsTheWorld.html:1.6 Sat Feb 21 23:45:02 2004 +++ llvm/docs/LLVMVsTheWorld.html Tue Mar 9 01:20:26 2004 @@ -66,7 +66,7 @@

      GCC: Many relatively mature platform backends support assembly-language code generation from many source languages. No run-time compilation -support. Relatively weak optimization support.

      +support.

      @@ -173,7 +173,7 @@
      Brian R. Gaeke
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/02/22 05:45:02 $ + Last modified: $Date: 2004/03/09 07:20:26 $ From alkis at cs.uiuc.edu Tue Mar 9 02:36:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Tue Mar 9 02:36:01 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200403090835.CAA27990@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.10 -> 1.11 --- Log message: Spill explicit physical register defs as well. --- Diffs of the changes: (+11 -3) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.10 llvm/lib/CodeGen/VirtRegMap.cpp:1.11 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.10 Sat Mar 6 17:08:44 2004 +++ llvm/lib/CodeGen/VirtRegMap.cpp Tue Mar 9 02:35:13 2004 @@ -283,8 +283,8 @@ // the value of the spilled virtual register VirtRegMap::MI2VirtMap::const_iterator i, e; for (tie(i, e) = vrm_->getFoldedVirts(mii); i != e; ++i) { - unsigned physReg = vrm_->getPhys(i->second); - if (physReg) vacateJustPhysReg(mbb, mii, physReg); + if (vrm_->hasPhys(i->second)) + vacateJustPhysReg(mbb, mii, vrm_->getPhys(i->second)); } // rewrite all used operands @@ -304,10 +304,18 @@ } } - // spill implicit defs + // spill implicit physical register defs const TargetInstrDescriptor& tid = tii_->get(mii->getOpcode()); for (const unsigned* id = tid.ImplicitDefs; *id; ++id) vacatePhysReg(mbb, mii, *id); + + // spill explicit physical register defs + for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) { + MachineOperand& op = mii->getOperand(i); + if (op.isRegister() && op.getReg() && !op.isUse() && + MRegisterInfo::isPhysicalRegister(op.getReg())) + vacatePhysReg(mbb, mii, op.getReg()); + } // rewrite def operands (def&use was handled with the // uses so don't check for those here) From alkis at cs.uiuc.edu Tue Mar 9 04:40:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Tue Mar 9 04:40:01 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile Message-ID: <200403091039.EAA12020@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT95/124.m88ksim: Makefile updated: 1.4 -> 1.5 --- Log message: Fix benchmark. Now it should run properly on test, train and ref inputs. --- Diffs of the changes: (+8 -9) Index: llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile diff -u llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile:1.4 llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile:1.5 --- llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile:1.4 Sun Feb 29 19:30:43 2004 +++ llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile Tue Mar 9 04:39:31 2004 @@ -2,18 +2,13 @@ RUN_OPTIONS = -c ifeq ($(ENDIAN),big) -EXTENSION := big +STDIN_FILENAME := ctl.big else -EXTENSION := lit +STDIN_FILENAME := ctl.lit +CPPFLAGS += -DLEHOST endif -ifeq ($(RUN_TYPE),test) -STDIN_FILENAME := ctl.$(EXTENSION) -else -STDIN_FILENAME := dcrand.$(EXTENSION) -endif - -STDOUT_FILENAME := test.out +STDOUT_FILENAME = $(RUN_TYPE).out Source := addd.c \ adds.c \ @@ -113,3 +108,7 @@ updstat.c include ../../Makefile.spec95 + +$(REF_IN_DIR)/ctl.$(EXTENSION): $(REF_IN_DIR)/ctl.raw + $(SED) -e s/%endian%/$(EXTENSION)/ < $< > $@ + From gaeke at cs.uiuc.edu Tue Mar 9 13:29:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Mar 9 13:29:02 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp TraceToFunction.h Message-ID: <200403091918.NAA18868@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.cpp updated: 1.23 -> 1.24 TraceToFunction.h updated: 1.5 -> 1.6 --- Log message: Move ValueMap and O2CMap into class TraceFunction. Add an accessor 'getCorrespondingValue()' to dig things out of it only if they are already there. --- Diffs of the changes: (+13 -2) Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp diff -u reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.23 reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.24 --- reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.23 Mon Mar 8 16:46:29 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.cpp Tue Mar 9 13:18:26 2004 @@ -48,7 +48,6 @@ typedef std::vector TypeVector; typedef std::map ValueToIntMap; -typedef std::map ValueMap; typedef std::map BranchNumberMap; class TraceToFunction { @@ -382,7 +381,7 @@ /// void TraceToFunction::fillInFunctionBody (Trace &T, Function *F, LiveVariableSet &So) { - ValueMap O2CMap; + ValueMap &O2CMap = TF->O2CMap; // First copy the basic blocks from the trace. cloneTraceBBsIntoFunction (T, F, O2CMap); Index: reopt/lib/LightWtProfiling/TraceToFunction.h diff -u reopt/lib/LightWtProfiling/TraceToFunction.h:1.5 reopt/lib/LightWtProfiling/TraceToFunction.h:1.6 --- reopt/lib/LightWtProfiling/TraceToFunction.h:1.5 Mon Mar 8 16:46:54 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.h Tue Mar 9 13:18:27 2004 @@ -17,6 +17,7 @@ typedef std::set LiveVariableSet; typedef std::map BasicBlockMap; +typedef std::map ValueMap; // This class encapsulates all the TraceToFunction algorithm's saved baggage. // You can't have a TraceFunction without a Trace, but you might be able to @@ -58,6 +59,17 @@ /// basic blocks that they are supposed to return to in MatrixFn. /// BasicBlockMap ReturnBlockForTraceExit; + + /// Map of original values in MatrixFn --> clones in TraceFn. + /// + ValueMap O2CMap; + + Value *getCorrespondingValue (const Value *V) { + ValueMap::iterator i = O2CMap.find (V); + assert (O2CMap.end() == i + && "getCorrespondingValue called on value not in map"); + return i->second; + } }; class FunctionPass; From gaeke at cs.uiuc.edu Tue Mar 9 13:29:07 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Mar 9 13:29:07 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Message-ID: <200403091918.NAA18894@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: UnpackTraceFunction.cpp updated: 1.41 -> 1.42 --- Log message: Use TraceFunction::getCorrespondingValue() to look up values in the TraceFn. --- Diffs of the changes: (+4 -2) Index: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp diff -u reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.41 reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.42 --- reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.41 Mon Mar 8 16:46:55 2004 +++ reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Tue Mar 9 13:18:15 2004 @@ -339,7 +339,8 @@ DEBUG(std::cerr << "UnpackTraceFunction: Looking for alloc state for value: \n" << *V << "\n"); AllocInfo Source = getValueAllocStateFromModule (MatrixF, V); DEBUG(std::cerr << "UnpackTraceFunction: Source = " << Source << "\n"); - AllocInfo Target = getValueAllocStateFromGlobal (TraceF, V); + AllocInfo Target = + getValueAllocStateFromGlobal (TraceF, TF->getCorrespondingValue(V)); DEBUG(std::cerr << "UnpackTraceFunction: Target = " << Target << "\n"); if (Source != Target) EntryCopies.push_back (CopyInfo (Source, Target, &E, V->getType ())); @@ -375,7 +376,8 @@ for (LiveVariableSet::iterator SI = So.begin (), SE = So.end (); SI != SE; ++SI) { Value *V = *SI; - AllocInfo Source = getValueAllocStateFromGlobal (TraceF, V); + AllocInfo Source = + getValueAllocStateFromGlobal (TraceF, TF->getCorrespondingValue (V)); AllocInfo Target = getValueAllocStateFromModule (MatrixF, V); if (Source != Target) SRI.insertCopyMachineInstrs (Source, Target, MBB, V->getType ()); From criswell at cs.uiuc.edu Tue Mar 9 13:34:02 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Mar 9 13:34:02 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Applications/Makefile Message-ID: <200403091933.NAA23889@choi.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Applications: Makefile updated: 1.4 -> 1.5 --- Log message: Enabled d on all platforms (works on Solaris and Linux now). --- Diffs of the changes: (+1 -4) Index: llvm/test/Programs/MultiSource/Applications/Makefile diff -u llvm/test/Programs/MultiSource/Applications/Makefile:1.4 llvm/test/Programs/MultiSource/Applications/Makefile:1.5 --- llvm/test/Programs/MultiSource/Applications/Makefile:1.4 Thu Jan 1 11:14:25 2004 +++ llvm/test/Programs/MultiSource/Applications/Makefile Tue Mar 9 13:33:09 2004 @@ -4,9 +4,6 @@ include $(LEVEL)/Makefile.config -PARALLEL_DIRS = Burg aha sgefa siod lambda-0.1.3 -ifeq ($(OS),Linux) -PARALLEL_DIRS += d -endif +PARALLEL_DIRS = Burg aha sgefa siod lambda-0.1.3 d include $(LEVEL)/test/Programs/Makefile.programs From lattner at cs.uiuc.edu Tue Mar 9 13:38:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Mar 9 13:38:06 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h Message-ID: <200403091937.NAA30856@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.78 -> 1.79 --- Log message: new method --- Diffs of the changes: (+4 -0) Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.78 llvm/include/llvm/Analysis/DSGraph.h:1.79 --- llvm/include/llvm/Analysis/DSGraph.h:1.78 Wed Mar 3 16:00:20 2004 +++ llvm/include/llvm/Analysis/DSGraph.h Tue Mar 9 13:36:59 2004 @@ -360,6 +360,10 @@ /// DSCallSite getCallSiteForArguments(Function &F) const; + /// getDSCallSiteForCallSite - Given an LLVM CallSite object that is live in + /// the context of this graph, return the DSCallSite for it. + DSCallSite getDSCallSiteForCallSite(CallSite CS) const; + // Methods for checking to make sure graphs are well formed... void AssertNodeInGraph(const DSNode *N) const { assert((!N || N->getParentGraph() == this) && From lattner at cs.uiuc.edu Tue Mar 9 13:38:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Mar 9 13:38:09 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200403091937.NAA30863@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.170 -> 1.171 --- Log message: implement new method --- Diffs of the changes: (+24 -0) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.170 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.171 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.170 Sun Mar 7 21:52:24 2004 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Tue Mar 9 13:37:06 2004 @@ -1375,6 +1375,30 @@ return DSCallSite(CallSite(), getReturnNodeFor(F), &F, Args); } +/// getDSCallSiteForCallSite - Given an LLVM CallSite object that is live in +/// the context of this graph, return the DSCallSite for it. +DSCallSite DSGraph::getDSCallSiteForCallSite(CallSite CS) const { + DSNodeHandle RetVal; + Instruction *I = CS.getInstruction(); + if (isPointerType(I->getType())) + RetVal = getNodeForValue(I); + + std::vector Args; + Args.reserve(CS.arg_end()-CS.arg_begin()); + + // Calculate the arguments vector... + for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I) + if (isPointerType((*I)->getType())) + Args.push_back(getNodeForValue(*I)); + + // Add a new function call entry... + if (Function *F = CS.getCalledFunction()) + return DSCallSite(CS, RetVal, F, Args); + else + return DSCallSite(CS, RetVal, + getNodeForValue(CS.getCalledValue()).getNode(), Args); +} + // markIncompleteNodes - Mark the specified node as having contents that are not From lattner at cs.uiuc.edu Tue Mar 9 16:51:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Mar 9 16:51:01 2004 Subject: [llvm-commits] CVS: gcc-3.4/gcc/llvm-expand.c Message-ID: <200403092250.QAA09440@zion.cs.uiuc.edu> Changes in directory gcc-3.4/gcc: llvm-expand.c updated: 1.22 -> 1.23 --- Log message: Fix PR276: llvm-g++ does not mangle method names that match stdlib function names --- Diffs of the changes: (+7 -5) Index: gcc-3.4/gcc/llvm-expand.c diff -u gcc-3.4/gcc/llvm-expand.c:1.22 gcc-3.4/gcc/llvm-expand.c:1.23 --- gcc-3.4/gcc/llvm-expand.c:1.22 Mon Mar 8 18:55:07 2004 +++ gcc-3.4/gcc/llvm-expand.c Tue Mar 9 16:50:42 2004 @@ -6401,11 +6401,13 @@ if (!DECL_LLVM_SET_P(subr) || DECL_LLVM(subr)->Ty != PFnTy) { const char *ExternalName = IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(subr)); llvm_value *GlobalVal = llvm_get_global_alias(ExternalName); - if (!GlobalVal) { - ExternalName = IDENTIFIER_POINTER(DECL_NAME(subr)); - GlobalVal = llvm_get_global_alias(ExternalName); - if (!GlobalVal) - ExternalName = IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(subr)); + if (!GlobalVal && DECL_BUILT_IN(subr)) { + const char *ExternalName2 = IDENTIFIER_POINTER(DECL_NAME(subr)); + llvm_value *GlobalVal2 = llvm_get_global_alias(ExternalName2); + if (GlobalVal2) { + ExternalName = ExternalName2; + GlobalVal = GlobalVal2; + } } if (!GlobalVal || GlobalVal->Ty != PFnTy) { const char *PName = (*lang_hooks.decl_printable_name)(subr, 2); From lattner at cs.uiuc.edu Tue Mar 9 16:52:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Mar 9 16:52:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/2004-03-09-UnmangledBuiltinMethods.cpp.tr Message-ID: <200403092251.QAA09449@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend: 2004-03-09-UnmangledBuiltinMethods.cpp.tr added (r1.1) --- Log message: New testcase for PR276: llvm-g++ does not mangle method names that match stdlib function names --- Diffs of the changes: (+8 -0) Index: llvm/test/Regression/C++Frontend/2004-03-09-UnmangledBuiltinMethods.cpp.tr diff -c /dev/null llvm/test/Regression/C++Frontend/2004-03-09-UnmangledBuiltinMethods.cpp.tr:1.1 *** /dev/null Tue Mar 9 16:51:13 2004 --- llvm/test/Regression/C++Frontend/2004-03-09-UnmangledBuiltinMethods.cpp.tr Tue Mar 9 16:51:03 2004 *************** *** 0 **** --- 1,8 ---- + // RUN: %llvmgcc -xc++ -c -o - %s | llvm-dis | grep _ZN11AccessFlags6strlenEv + + struct AccessFlags { + void strlen(); + }; + + void AccessFlags::strlen() { } + From lattner at cs.uiuc.edu Tue Mar 9 20:52:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Mar 9 20:52:01 2004 Subject: [llvm-commits] CVS: gcc-3.4/gcc/llvm-representation.c llvm-representation.h Message-ID: <200403100251.UAA11115@zion.cs.uiuc.edu> Changes in directory gcc-3.4/gcc: llvm-representation.c updated: 1.4 -> 1.5 llvm-representation.h updated: 1.1 -> 1.2 --- Log message: Rename and expose function --- Diffs of the changes: (+4 -3) Index: gcc-3.4/gcc/llvm-representation.c diff -u gcc-3.4/gcc/llvm-representation.c:1.4 gcc-3.4/gcc/llvm-representation.c:1.5 --- gcc-3.4/gcc/llvm-representation.c:1.4 Sat Feb 14 21:10:29 2004 +++ gcc-3.4/gcc/llvm-representation.c Tue Mar 9 20:50:57 2004 @@ -431,7 +431,7 @@ llvm_constant_aggregate_print(CA, stderr); } -static int isNullConstant(llvm_value *V) { +int llvm_is_null_constant(llvm_value *V) { switch (V->VTy) { case ConstantAggregate: { llvm_constant_aggregate *CA = (llvm_constant_aggregate*)V; @@ -443,7 +443,7 @@ e = V->Ty->x.Array.Size; } for (i = 0; i != e; ++i) - if (!isNullConstant(CA->Initializers[i])) return 0; + if (!llvm_is_null_constant(CA->Initializers[i])) return 0; return 1; } default: return 0; @@ -459,7 +459,7 @@ llvm_type *Ty = G2V(CE)->Ty; llvm_value **Elements = CE->Initializers; - if (isNullConstant((llvm_value*)CE)) { + if (llvm_is_null_constant((llvm_value*)CE)) { fprintf(F, "zeroinitializer"); return; } Index: gcc-3.4/gcc/llvm-representation.h diff -u gcc-3.4/gcc/llvm-representation.h:1.1 gcc-3.4/gcc/llvm-representation.h:1.2 --- gcc-3.4/gcc/llvm-representation.h:1.1 Thu Jan 8 16:35:32 2004 +++ gcc-3.4/gcc/llvm-representation.h Tue Mar 9 20:50:57 2004 @@ -87,6 +87,7 @@ llvm_value *llvm_constant_new(struct llvm_type *Ty, const char *Rep); llvm_value *llvm_constant_new_integral(struct llvm_type *Ty, long long X); llvm_value *llvm_constant_get_null(struct llvm_type *Ty); +int llvm_is_null_constant(llvm_value *V); void llvm_constant_construct(llvm_constant *C, struct llvm_type *Ty, const char *Name, enum ValueType VT, const char *Rep); From lattner at cs.uiuc.edu Tue Mar 9 21:06:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Mar 9 21:06:02 2004 Subject: [llvm-commits] CVS: gcc-3.4/gcc/llvm-expand.c Message-ID: <200403100305.VAA11243@zion.cs.uiuc.edu> Changes in directory gcc-3.4/gcc: llvm-expand.c updated: 1.23 -> 1.24 --- Log message: Expand large initializers of zeros into memset calls, and large constant initializers into memcpy calls from a global. This addresses PR275. --- Diffs of the changes: (+63 -60) Index: gcc-3.4/gcc/llvm-expand.c diff -u gcc-3.4/gcc/llvm-expand.c:1.23 gcc-3.4/gcc/llvm-expand.c:1.24 --- gcc-3.4/gcc/llvm-expand.c:1.23 Tue Mar 9 16:50:42 2004 +++ gcc-3.4/gcc/llvm-expand.c Tue Mar 9 21:05:22 2004 @@ -3866,6 +3866,26 @@ } +/* llvm_count_constructor_init_elements - Given a constructor initializer, count + * how many elements are zero values and, of the remaining values, how many are + * non-zero constants. + */ +static void +llvm_count_constructor_init_elements(llvm_value **Elements, unsigned Size, + unsigned *NumConstant, unsigned *NumZero) { + unsigned Constants = 0, Zeros = 0, i; + for (i = 0; i != Size; ++i) + if (llvm_value_is_constant(Elements[i])) { + if (llvm_is_null_constant(Elements[i])) + ++Zeros; + else + ++Constants; + } + *NumConstant = Constants; + *NumZero = Zeros; +} + + /* llvm_expand_constructor - Store the value of a CONSTRUCTOR (exp) into the * LLVM value (Dest). Dest is guaranteed to be a pointer to the appropriate * memory location. @@ -3901,74 +3921,57 @@ /* Composite elements handled already */ if (!llvm_type_is_composite(Ty->Elements[0])) { - /* Lots of initializers have LARGE tails of zeros at the end of them. To - * handle this efficiently, we actually check to see if there is a large - * tail pad, and if so, emit a loop to initialize it. + /* It is very common for constructors to be fully constant, and not + * infrequent for them to be large. In this case, emit an internal global + * variable with the constructor value as its initializer, and memcpy it + * over. */ - unsigned TailStart = Size; - if (TailStart) { - do --TailStart; - while (TailStart && Elements[TailStart] == Elements[TailStart-1]); - } + if (Size > 16) { + unsigned Alignment = TYPE_ALIGN_UNIT(TREE_TYPE(exp)); + unsigned NumBytes = Size*llvm_type_get_size(Ty->Elements[0]); + unsigned NumConstants = 0, NumZeros = 0; + llvm_count_constructor_init_elements(Elements, Size, + &NumConstants, &NumZeros); + + /* If all of the elements are zeros, memset the constructor to zero. */ + if (NumZeros == Size) { + EmitMemset(Fn, target, llvm_constant_ubyte_0, + llvm_constant_new_integral(LongTy, NumBytes), Alignment); + free(Elements); + return; + } else if (NumZeros+NumConstants == Size) { + /* Otherwise, if all of the elements are constants, initialize a + * global variable with the constant value, and memcpy it into the + * current location. + */ + llvm_constant *C = G2C(llvm_constant_aggregate_new(Ty, Elements)); + llvm_global *G; + static int CtorCounter = 0; + char Name[20]; + sprintf(Name, ".ctor_%d", ++CtorCounter); + G = llvm_global_new(D2V(C)->Ty, Name); + G->Init = C; + llvm_ilist_push_back(llvm_global, TheProgram.Globals, G); + EmitMemCpyMove(Fn, target, G2V(G), + llvm_constant_new_integral(LongTy, NumBytes), + Alignment, 0); + return; + } - /* Only do this for substantial tails. */ - if (Size-TailStart < 16) - TailStart = Size; + /* FIXME: MORE CASES WE COULD HANDLE EFFICIENTLY: + * - When the init is mostly zeros but not all constant, memset, then + * fill in elements. + * - When the constant is mostly zeros, we could use memset to set + * it to zero, then memcpy the smaller non-zero portion. + */ + } - /* FIXME: If tailstart is obscenely large, we are better off starting with - * an initialized global and memcpy'ing it over. - */ - for (i = 0; i != TailStart; ++i) { + for (i = 0; i != Size; ++i) { /* Make a getelementptr instruction that addresses the field */ OffsetInst = create_gep3(target, llvm_constant_long_0, llvm_constant_new_integral(LongTy, i)); Offset = append_inst(Fn, OffsetInst); /* Add it to the program */ append_inst(Fn, create_store_inst(Elements[i], Offset, isVolatile)); - } - - /* If there is tail padding to emit, add the loop or memset call now. */ - if (TailStart != Size) { - llvm_value *Val = Elements[i]; - if (llvm_type_get_size(Val->Ty) == 1) { - llvm_value *DestPtr = - append_inst(Fn, create_gep3(target, llvm_constant_long_0, - llvm_constant_new_integral(LongTy, TailStart))); - EmitMemset(Fn, DestPtr, Val, - llvm_constant_new_integral(LongTy, Size-TailStart), 1); - } else { - llvm_basicblock *FromBlock = - llvm_ilist_back(llvm_basicblock, Fn->BasicBlocks); - llvm_basicblock *Loop = llvm_basicblock_new("initializeloop"); - llvm_basicblock *After = llvm_basicblock_new("continue"); - llvm_instruction *PHI; - llvm_value *SetNE; - - /* Output the branch to the loop block, and the loop block itself. */ - append_inst(Fn, create_uncond_branch(Loop)); - llvm_emit_label(Fn, Loop); - - /* Create the PHI node now */ - PHI = llvm_instruction_new(LongTy, "idx", O_PHINode, 4); - PHI->Operands[0] = llvm_constant_new_integral(LongTy, TailStart); - PHI->Operands[1] = D2V(FromBlock); - PHI->Operands[3] = D2V(Loop); - append_inst(Fn, PHI); - - /* Make a getelementptr & store to the fields */ - OffsetInst = create_gep3(target, llvm_constant_long_0, D2V(PHI)); - Offset = append_inst(Fn, OffsetInst); /* Add it to the program */ - append_inst(Fn, create_store_inst(Val, Offset, isVolatile)); - - /* Add one to the counter, add it to the PHI operand */ - PHI->Operands[2] = - append_inst(Fn, create_binary_inst("tmp", O_Add, D2V(PHI), - llvm_constant_new_integral(LongTy, 1))); - /* Add a setne instruction to test for loop termination */ - SetNE = append_inst(Fn, create_binary_inst("hasmore",O_SetNE,D2V(PHI), - llvm_constant_new_integral(LongTy, Size-1))); - append_inst(Fn, create_cond_branch(SetNE, Loop, After)); - llvm_emit_label(Fn, After); - } } } } From lattner at cs.uiuc.edu Tue Mar 9 21:08:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Mar 9 21:08:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2004-03-09-LargeArrayInitializers.c Message-ID: <200403100307.VAA11272@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2004-03-09-LargeArrayInitializers.c added (r1.1) --- Log message: New testcase for PR275 --- Diffs of the changes: (+30 -0) Index: llvm/test/Regression/CFrontend/2004-03-09-LargeArrayInitializers.c diff -c /dev/null llvm/test/Regression/CFrontend/2004-03-09-LargeArrayInitializers.c:1.1 *** /dev/null Tue Mar 9 21:07:55 2004 --- llvm/test/Regression/CFrontend/2004-03-09-LargeArrayInitializers.c Tue Mar 9 21:07:45 2004 *************** *** 0 **** --- 1,30 ---- + // Test that these initializers are handled efficiently + + int test(int x) { + const int XX[1000] = { 0, 0 }; + const char S [1000] = "foo"; + + const int array[] = { + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + }; + return array[x]; + } From gaeke at cs.uiuc.edu Wed Mar 10 11:39:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 11:39:01 2004 Subject: [llvm-commits] CVS: llvm/Makefile.config.in Message-ID: <200403101738.LAA17407@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.config.in updated: 1.24 -> 1.25 --- Log message: Fix up a seriously outdated comment. --- Diffs of the changes: (+2 -2) Index: llvm/Makefile.config.in diff -u llvm/Makefile.config.in:1.24 llvm/Makefile.config.in:1.25 --- llvm/Makefile.config.in:1.24 Wed Feb 25 17:47:17 2004 +++ llvm/Makefile.config.in Wed Mar 10 11:37:50 2004 @@ -65,8 +65,8 @@ # object files. OBJ_ROOT := . -# Path to location for LLVM front-end this should only be specified here if you -# want to override the value set in Makefile.$(uname) +# Path to location for LLVM C/C++ front-end. You can modify this if you +# want to override the value set by configure. LLVMGCCDIR := @LLVMGCCDIR@ # When this variable is set to 1, programs in the llvm/test/Programs hierarchy From gaeke at cs.uiuc.edu Wed Mar 10 11:39:05 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 11:39:05 2004 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200403101738.LAA17447@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.179 -> 1.180 --- Log message: Add support for 'install-bytecode' target, used for ONLY installing bytecode-libs. --- Diffs of the changes: (+8 -3) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.179 llvm/Makefile.rules:1.180 --- llvm/Makefile.rules:1.179 Fri Feb 13 14:05:44 2004 +++ llvm/Makefile.rules Wed Mar 10 11:38:01 2004 @@ -78,6 +78,7 @@ # if BYTECODE_LIBRARY is specified, the default is to build the bytecode lib all:: bytecodelib install:: install-bytecode-library +install-bytecode:: install-bytecode-library endif # Default Rule: Make sure it's also a :: rule @@ -92,6 +93,9 @@ # Default rule for building only bytecode. bytecode:: +# Default rule for installing only bytecode. +install-bytecode:: + # Print out the directories used for building prdirs:: @${ECHO} "Build Source Root: " $(BUILD_SRC_ROOT) @@ -391,7 +395,7 @@ #--------------------------------------------------------- ifdef DIRS -all install clean test bytecode stripped-bytecode:: +all install clean test bytecode stripped-bytecode install-bytecode:: $(VERB) for dir in ${DIRS}; do \ if [ ! -f $$dir/Makefile ]; \ then \ @@ -410,8 +414,9 @@ test :: $(addsuffix /.maketest , $(PARALLEL_DIRS)) bytecode :: $(addsuffix /.makebytecode, $(PARALLEL_DIRS)) stripped-bytecode :: $(addsuffix /.makestripped-bytecode, $(PARALLEL_DIRS)) +install-bytecode :: $(addsuffix /.makeinstall-bytecode, $(PARALLEL_DIRS)) -%/.makeall %/.makeinstall %/.makeclean %/.maketest %/.makebytecode %/.makestripped-bytecode: +%/.makeall %/.makeinstall %/.makeclean %/.maketest %/.makebytecode %/.makestripped-bytecode %/.makeinstall-bytecode: $(VERB) if [ ! -f $(@D)/Makefile ]; \ then \ $(MKDIR) $(@D); \ @@ -422,7 +427,7 @@ # Handle directories that may or may not exist ifdef OPTIONAL_DIRS -all install clean test bytecode stripped-bytecode:: +all install clean test bytecode stripped-bytecode install-bytecode:: $(VERB) for dir in ${OPTIONAL_DIRS}; do \ if [ -d $(SourceDir)/$$dir ]; \ then\ From gaeke at cs.uiuc.edu Wed Mar 10 11:39:15 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 11:39:15 2004 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/Intercept.cpp Message-ID: <200403101738.LAA17488@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: Intercept.cpp updated: 1.14 -> 1.15 --- Log message: My fix for PR274 broke the build on Darwin/PPC. As I'm fairly certain this bug only affects Linux systems that use GLIBC, I'm going to put ifdefs around the array. --- Diffs of the changes: (+4 -2) Index: llvm/lib/ExecutionEngine/JIT/Intercept.cpp diff -u llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.14 llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.15 --- llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.14 Mon Mar 8 23:22:10 2004 +++ llvm/lib/ExecutionEngine/JIT/Intercept.cpp Wed Mar 10 11:38:28 2004 @@ -47,16 +47,18 @@ // not inlined, and hiding their real definitions in a separate archive file // that the dynamic linker can't see. For more info, search for // 'libc_nonshared.a' on Google, or read http://llvm.cs.uiuc.edu/PR274. +#if defined(__linux__) void *FunctionPointers[] = { (void *) stat, - (void *) stat64, (void *) fstat, - (void *) fstat64, (void *) lstat, + (void *) stat64, + (void *) fstat64, (void *) lstat64, (void *) atexit, (void *) mknod }; +#endif // __linux__ // NoopFn - Used if we have nothing else to call... static void NoopFn() {} From gaeke at cs.uiuc.edu Wed Mar 10 13:04:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 13:04:01 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp Message-ID: <200403101903.NAA22414@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.cpp updated: 1.24 -> 1.25 --- Log message: Move ValueToIntMap and LiveInToParameterMap into TraceFunction.h. Fix up some comments. Don't let O2CMap contain things which were deleted. Remove a DEBUG printout which wasn't working anyway. When debugging, print out O2CMap just before returning from TraceToFunction. --- Diffs of the changes: (+33 -20) Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp diff -u reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.24 reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.25 --- reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.24 Tue Mar 9 13:18:26 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.cpp Wed Mar 10 13:03:43 2004 @@ -47,11 +47,9 @@ namespace llvm { typedef std::vector TypeVector; -typedef std::map ValueToIntMap; typedef std::map BranchNumberMap; class TraceToFunction { - ValueToIntMap LiveInToParameterMap; BranchNumberMap BranchNumber; TraceFunction *TF; virtual TypeVector createFunctionArgTypeVector (PointerType *ST, @@ -206,23 +204,23 @@ /// create a parameter list containing a parameter for each of the /// variables in S as well as a pointer-to-structure type PST to fill /// in which contains the live-outs. As a side effect, fill in the -/// mapping between live-ins and parameters in the global map named -/// LiveInToParameterMap. +/// mapping between live-ins and parameters in +/// TF->LiveInToParameterMap. /// TypeVector TraceToFunction::createFunctionArgTypeVector (PointerType *PST, LiveVariableSet S) { TypeVector P; P.push_back (PST); - LiveInToParameterMap.clear (); + TF->LiveInToParameterMap.clear (); for (LiveVariableSet::iterator I = S.begin (), E = S.end (); I != E; ++I) { Value *V = *I; P.push_back (V->getType ()); - LiveInToParameterMap[V] = P.size () - 1; + TF->LiveInToParameterMap[V] = P.size () - 1; } // Print out mapping of instructions to arg numbers. - DEBUG(for (ValueToIntMap::iterator I = LiveInToParameterMap.begin (), - E = LiveInToParameterMap.end (); I != E; ++I) + DEBUG(for (ValueToIntMap::iterator I = TF->LiveInToParameterMap.begin (), + E = TF->LiveInToParameterMap.end (); I != E; ++I) std::cerr << I->first << " is parameter " << I->second << "\n"); return P; } @@ -291,7 +289,7 @@ } } -static void fixupPhisAndCalls (BasicBlock *dstB) { +static void fixupPhisAndCalls (BasicBlock *dstB, ValueMap &O2CMap) { std::vector goners; Function *F = dstB->getParent (); // Fix up Phi nodes: @@ -370,6 +368,12 @@ assert (goners.back ()->use_size () == 0 && "Whoops, I was going to delete something which still has uses"); dstB->getInstList ().erase (goners.back ()); + for (ValueMap::iterator i = O2CMap.begin(), e = O2CMap.end(); i != e; ++i) { + if (i->second == goners.back ()) { + O2CMap.erase (i); + break; + } + } goners.pop_back (); } } @@ -397,7 +401,7 @@ fixupFunctionBodyBB (T, F, srcB, dstB, O2CMap, So); } for (Function::iterator FI = F->begin (), FE = F->end (); FI != FE; ++FI) - fixupPhisAndCalls (FI); + fixupPhisAndCalls (FI, O2CMap); } /// fixupFunctionBodyBB - Given srcB in T and its clone dstB in F, and @@ -515,20 +519,15 @@ // set of the trace, then we must replace that operand with // the corresponding argument of F. We can find out which // operands to replace by looking them up in - // LiveInToParameterMap. - if (LiveInToParameterMap.find (V) != LiveInToParameterMap.end ()) { + // TF->LiveInToParameterMap. + if (TF->LiveInToParameterMap.find (V) != TF->LiveInToParameterMap.end ()) { DEBUG(std::cerr << *V << " in instruction " << I - << " is argument " << LiveInToParameterMap[V] + << " is argument " << TF->LiveInToParameterMap[V] << " in new function\n"); - DEBUG(std::cerr << " -- V's type is " << V->getType () << "\n"); - DEBUG(std::cerr << " -- Argument " << LiveInToParameterMap[V] - << "'s type is " - << getFunctionArg (F, LiveInToParameterMap[V])->getType () - << "\n"); assert (V->getType () == - getFunctionArg (F, LiveInToParameterMap[V])->getType () + getFunctionArg (F, TF->LiveInToParameterMap[V])->getType () && "Live-in Value's type doesn't match corresponding arg type"); - I.setOperand(i, getFunctionArg (F, LiveInToParameterMap[V])); + I.setOperand(i, getFunctionArg (F, TF->LiveInToParameterMap[V])); } // If the instruction I has an operand which is in the // trace, that operand will have been cloned into the @@ -558,6 +557,18 @@ } } +/// Dump out the O2CMap for the given TraceFunction to stderr. +/// Only called when debugging. +/// +static void cloneMapDump (TraceFunction *TF) { + for (ValueMap::const_iterator i = TF->O2CMap.begin(), e = TF->O2CMap.end(); + i != e; ++i) { + const std::pair &elem = *i; + std::cerr << "Original value: " << i->first << "\nmaps to: " + << i->second << "\n"; + } +} + TraceFunction *TraceToFunction::traceToFunction (Trace &T) { // Create a TraceFunction object to hold the trace function along with // its auxiliary data structures. @@ -582,6 +593,8 @@ T.getModule ()); DEBUG(giveNamesToFunctionArgs (TF->LiveInSet, TF->TraceFn)); fillInFunctionBody (T, TF->TraceFn, TF->LiveOutSet); + + DEBUG(cloneMapDump(TF)); return TF; } From gaeke at cs.uiuc.edu Wed Mar 10 13:04:06 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 13:04:06 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.h Message-ID: <200403101903.NAA22421@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.h updated: 1.6 -> 1.7 --- Log message: Move ValueToIntMap and LiveInToParameterMap into TraceFunction.h. Fix up some comments. --- Diffs of the changes: (+6 -0) Index: reopt/lib/LightWtProfiling/TraceToFunction.h diff -u reopt/lib/LightWtProfiling/TraceToFunction.h:1.6 reopt/lib/LightWtProfiling/TraceToFunction.h:1.7 --- reopt/lib/LightWtProfiling/TraceToFunction.h:1.6 Tue Mar 9 13:18:27 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.h Wed Mar 10 13:03:44 2004 @@ -18,6 +18,7 @@ typedef std::set LiveVariableSet; typedef std::map BasicBlockMap; typedef std::map ValueMap; +typedef std::map ValueToIntMap; // This class encapsulates all the TraceToFunction algorithm's saved baggage. // You can't have a TraceFunction without a Trace, but you might be able to @@ -63,6 +64,11 @@ /// Map of original values in MatrixFn --> clones in TraceFn. /// ValueMap O2CMap; + + /// Map of Trace's live-in values in the MatrixFn --> parameter numbers in + /// TraceFn. + /// + ValueToIntMap LiveInToParameterMap; Value *getCorrespondingValue (const Value *V) { ValueMap::iterator i = O2CMap.find (V); From gaeke at cs.uiuc.edu Wed Mar 10 13:04:10 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 13:04:10 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Message-ID: <200403101903.NAA22428@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: UnpackTraceFunction.cpp updated: 1.42 -> 1.43 --- Log message: Try printing out the values that we can't look up alloc state for. --- Diffs of the changes: (+4 -0) Index: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp diff -u reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.42 reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.43 --- reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.42 Tue Mar 9 13:18:15 2004 +++ reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Wed Mar 10 13:03:45 2004 @@ -241,6 +241,10 @@ // Find the alloc state of an argument. OperandKey = getNumberOfFunctionArg (F, A); } else { + if (! isa (V)) { + std::cerr << "ERROR: Don't know how to look up alloc state for this Value:\n\t" << *V << "\n"; + abort (); + } // Figure out the indices (VI, VO) that can be used to look up V, // which is an operand of some instruction in F, in FState: Instruction *Instr = cast (V); From gaeke at cs.uiuc.edu Wed Mar 10 13:10:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 13:10:01 2004 Subject: [llvm-commits] CVS: llvm/docs/CFEBuildInstrs.html Message-ID: <200403101909.NAA11119@zion.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.12 -> 1.13 --- Log message: Recommend using install-bytecode target --- Diffs of the changes: (+2 -2) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.12 llvm/docs/CFEBuildInstrs.html:1.13 --- llvm/docs/CFEBuildInstrs.html:1.12 Wed Jan 28 14:54:41 2004 +++ llvm/docs/CFEBuildInstrs.html Wed Mar 10 13:08:52 2004 @@ -185,7 +185,7 @@
        % gmake -C runtime
        % mkdir $CFEINSTALL/bytecode-libs
      - % gmake -C runtime install
      + % gmake -C runtime install-bytecode
        % setenv LLVM_LIB_SEARCH_PATH $CFEINSTALL/bytecode-libs
       
      @@ -250,7 +250,7 @@
      Brian Gaeke
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/01/28 20:54:41 $ + Last modified: $Date: 2004/03/10 19:08:52 $ From gaeke at cs.uiuc.edu Wed Mar 10 13:16:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 13:16:02 2004 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200403101916.NAA11263@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.16 -> 1.17 --- Log message: Add brainstorm for a random test vector generator --- Diffs of the changes: (+5 -1) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.16 llvm/docs/OpenProjects.html:1.17 --- llvm/docs/OpenProjects.html:1.16 Mon Mar 8 16:29:35 2004 +++ llvm/docs/OpenProjects.html Wed Mar 10 13:15:50 2004 @@ -308,6 +308,10 @@
      1. Write a new frontend for some language (Java? OCaml? Forth?)
      2. Write a new backend for a target (IA64? MIPS? MMIX?)
      3. +
      4. Random test vector generator: Use a C grammar to generate random C code; +run it through llvm-gcc, then run a random set of passes on it using opt. +Try to crash opt. When opt crashes, use bugpoint to reduce the test case and +mail the result to yourself. Repeat ad infinitum.
      @@ -319,7 +323,7 @@
      Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/03/08 22:29:35 $ + Last modified: $Date: 2004/03/10 19:15:50 $ From brukman at cs.uiuc.edu Wed Mar 10 13:23:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 13:23:01 2004 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200403101922.NAA17503@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.17 -> 1.18 --- Log message: We need a logo. --- Diffs of the changes: (+2 -1) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.17 llvm/docs/OpenProjects.html:1.18 --- llvm/docs/OpenProjects.html:1.17 Wed Mar 10 13:15:50 2004 +++ llvm/docs/OpenProjects.html Wed Mar 10 13:22:29 2004 @@ -312,6 +312,7 @@ run it through llvm-gcc, then run a random set of passes on it using opt. Try to crash opt. When opt crashes, use bugpoint to reduce the test case and mail the result to yourself. Repeat ad infinitum. +
    • Design a simple, recognizable logo.
    • @@ -323,7 +324,7 @@
      Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/03/10 19:15:50 $ + Last modified: $Date: 2004/03/10 19:22:29 $ From alkis at cs.uiuc.edu Wed Mar 10 13:39:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Mar 10 13:39:01 2004 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200403101938.NAA17748@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.18 -> 1.19 --- Log message: Add link to bugzilla query of unassigned enhancements. Specific open projects like 'port glibc to llvm' or 'improve nightly tester', should have an unassigned enhancement bug opened for them so that they can be tracked more easily. Open projects should only list generic projects like 'compile programs with the LLVM compiler' or 'write a new backend for target'. --- Diffs of the changes: (+2 -2) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.18 llvm/docs/OpenProjects.html:1.19 --- llvm/docs/OpenProjects.html:1.18 Wed Mar 10 13:22:29 2004 +++ llvm/docs/OpenProjects.html Wed Mar 10 13:38:33 2004 @@ -54,7 +54,7 @@ Additionally this is a good way to get more information about a specific project or to suggest other projects to add to this page. Another good place to look for ideas is the LLVM bug -tracker.

      +tracker by querying for unassigned enhancements.

      @@ -324,7 +324,7 @@
      Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/03/10 19:22:29 $ + Last modified: $Date: 2004/03/10 19:38:33 $ From criswell at cs.uiuc.edu Wed Mar 10 13:39:05 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Mar 10 13:39:05 2004 Subject: [llvm-commits] CVS: gcc-3.4/gcc/llvm-types.c Message-ID: <200403101938.NAA16869@choi.cs.uiuc.edu> Changes in directory gcc-3.4/gcc: llvm-types.c updated: 1.1 -> 1.2 --- Log message: Adjusted static arrays so that they can handle the maximum size structure that the LLVM assembly representation can handle. Added code that will assert() that a structure is compilable with LLVM. This should hopefull fix PR#281. --- Diffs of the changes: (+6 -4) Index: gcc-3.4/gcc/llvm-types.c diff -u gcc-3.4/gcc/llvm-types.c:1.1 gcc-3.4/gcc/llvm-types.c:1.2 --- gcc-3.4/gcc/llvm-types.c:1.1 Thu Jan 8 16:35:32 2004 +++ gcc-3.4/gcc/llvm-types.c Wed Mar 10 13:38:33 2004 @@ -1185,10 +1185,11 @@ tree BaseTypes = TYPE_BINFO(type) ? BINFO_BASETYPES(TYPE_BINFO(type)) : 0; tree Field = TYPE_FIELDS(type); unsigned Idx, Size; + unsigned fieldcount; PtrPtrTableEntry **HTEP, *HTE; - llvm_type *StructElements[200]; /* FIXME: Fixed size buffers are bad. */ - unsigned ElementOffsets[200]; - unsigned ElementAlignments[200]; + llvm_type *StructElements[256]; /* FIXME: Fixed size buffers are bad. */ + unsigned ElementOffsets[256]; + unsigned ElementAlignments[256]; /* Is it a forward declaration? */ if (TYPE_SIZE(type) == 0) { /* Yes, handle this. */ @@ -1269,7 +1270,8 @@ /* Process all of the fields. */ if (Field && TREE_CODE(Field) != FIELD_DECL) Field = GetNextFieldDecl(Field); - for (; Field; Field = GetNextFieldDecl(Field)) { + for (fieldcount = 0; Field; fieldcount++,Field = GetNextFieldDecl(Field)) { + assert ((fieldcount<256) && "LLVM can only have 255 structure members!"); DecodeFieldDecl(Field, StructElements, ElementOffsets, ElementAlignments, &Idx, &Size); From lattner at cs.uiuc.edu Wed Mar 10 15:43:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Mar 10 15:43:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IndVarsSimplify/2004-03-10-PHIInsertionBug.ll Message-ID: <200403102141.PAA23538@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IndVarsSimplify: 2004-03-10-PHIInsertionBug.ll added (r1.1) --- Log message: New testcase for PR284: [indvars] Induction variable analysis violates LLVM invariants --- Diffs of the changes: (+27 -0) Index: llvm/test/Regression/Transforms/IndVarsSimplify/2004-03-10-PHIInsertionBug.ll diff -c /dev/null llvm/test/Regression/Transforms/IndVarsSimplify/2004-03-10-PHIInsertionBug.ll:1.1 *** /dev/null Wed Mar 10 15:41:59 2004 --- llvm/test/Regression/Transforms/IndVarsSimplify/2004-03-10-PHIInsertionBug.ll Wed Mar 10 15:41:47 2004 *************** *** 0 **** --- 1,27 ---- + ; RUN: llvm-as < %s | opt -indvars -disable-output + + implementation ; Functions: + + void %test() { + br label %endif.0.i + + endif.0.i: ; preds = %then.0.i + br bool false, label %then.3.i, label %endif.3.i + + then.3.i: ; preds = %endif.0.i + br label %endif.3.i + + endif.3.i: ; preds = %endif.0.i, %then.3.i + %inxm.0.i = phi int [ 8, %then.3.i ], [ 0, %endif.0.i ] + %doinner.1.i = phi int [ 0, %then.3.i ], [ 0, %endif.0.i ] + br label %loopentry.2.i + + loopentry.2.i: ; preds = %endif.3.i, %no_exit.2.i + %inxk.0.i = phi int [ %tmp.210.i, %no_exit.2.i ], [ 0, %endif.3.i ] + br label %no_exit.2.i + + no_exit.2.i: ; preds = %loopentry.2.i + %tmp.210.i = sub int %inxk.0.i, %inxm.0.i + %tmp.213.i = add int %tmp.210.i, 0 + br label %loopentry.2.i + } From lattner at cs.uiuc.edu Wed Mar 10 15:43:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Mar 10 15:43:10 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/InductionVariable.cpp Message-ID: <200403102142.PAA23552@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: InductionVariable.cpp updated: 1.34 -> 1.35 --- Log message: Fix PR284: [indvars] Induction variable analysis violates LLVM invariants --- Diffs of the changes: (+5 -1) Index: llvm/lib/Analysis/InductionVariable.cpp diff -u llvm/lib/Analysis/InductionVariable.cpp:1.34 llvm/lib/Analysis/InductionVariable.cpp:1.35 --- llvm/lib/Analysis/InductionVariable.cpp:1.34 Tue Dec 23 02:04:02 2003 +++ llvm/lib/Analysis/InductionVariable.cpp Wed Mar 10 15:42:19 2004 @@ -136,10 +136,14 @@ if (Constant *CV = dyn_cast(V)) Step = ConstantExpr::get(Instruction::Sub, Zero, CV); else if (Instruction *I = dyn_cast(V)) { + BasicBlock::iterator InsertPt = I; + for (++InsertPt; isa(InsertPt); ++InsertPt) + /*empty*/; Step = BinaryOperator::create(Instruction::Sub, Zero, V, - V->getName()+".neg", I->getNext()); + V->getName()+".neg", InsertPt); } else { + // Must be loop invariant Step = BinaryOperator::create(Instruction::Sub, Zero, V, V->getName()+".neg", Phi->getParent()->getParent()->begin()->begin()); From lattner at cs.uiuc.edu Wed Mar 10 15:44:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Mar 10 15:44:00 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200403102143.PAA23782@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.142 -> 1.143 --- Log message: Bugz fixed --- Diffs of the changes: (+3 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.142 llvm/docs/ReleaseNotes.html:1.143 --- llvm/docs/ReleaseNotes.html:1.142 Mon Mar 8 23:43:59 2004 +++ llvm/docs/ReleaseNotes.html Wed Mar 10 15:43:47 2004 @@ -158,6 +158,7 @@
    • [llvmgcc] C front-end does not emit 'zeroinitializer' when possible
    • [llvmgcc] Structure copies result in a LOT of code
    • LLVM is now much more memory efficient when handling large zero initialized arrays
    • +
    • [llvmgcc] Local array initializers are expanded into large amounts of code
    • @@ -216,6 +217,7 @@
    • Variables used to define non-printable FP constants are externally visible
    • CBE gives linkonce functions wrong linkage semantics
    • [JIT] Programs cannot resolve the fstat function
    • +
    • [indvars] Induction variable analysis violates LLVM invariants
    • @@ -623,7 +625,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/03/09 05:43:59 $ + Last modified: $Date: 2004/03/10 21:43:47 $ From lattner at cs.uiuc.edu Wed Mar 10 15:46:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Mar 10 15:46:04 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.1/docs/ReleaseNotes.html Message-ID: <200403102145.PAA24517@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.1/docs: ReleaseNotes.html updated: 1.33 -> 1.34 --- Log message: Bug found --- Diffs of the changes: (+2 -1) Index: llvm-www/releases/1.1/docs/ReleaseNotes.html diff -u llvm-www/releases/1.1/docs/ReleaseNotes.html:1.33 llvm-www/releases/1.1/docs/ReleaseNotes.html:1.34 --- llvm-www/releases/1.1/docs/ReleaseNotes.html:1.33 Mon Mar 8 23:40:35 2004 +++ llvm-www/releases/1.1/docs/ReleaseNotes.html Wed Mar 10 15:45:43 2004 @@ -396,6 +396,7 @@
    • Linking weak and strong global variables is dependent on link order
    • [X86] Missing cast from ULong -> Double, cast FP -> bool and support for -9223372036854775808
    • [JIT] Programs cannot resolve the fstat function
    • +
    • [indvars] Induction variable analysis violates LLVM invariants
    @@ -762,7 +763,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/09 05:40:35 $ + Last modified: $Date: 2004/03/10 21:45:43 $ From gaeke at cs.uiuc.edu Wed Mar 10 15:55:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 15:55:01 2004 Subject: [llvm-commits] CVS: reopt/test/TEST.reopt.Makefile Message-ID: <200403102154.PAA23838@kain.cs.uiuc.edu> Changes in directory reopt/test: TEST.reopt.Makefile updated: 1.9 -> 1.10 --- Log message: Update head-of-file comment --- Diffs of the changes: (+7 -1) Index: reopt/test/TEST.reopt.Makefile diff -u reopt/test/TEST.reopt.Makefile:1.9 reopt/test/TEST.reopt.Makefile:1.10 --- reopt/test/TEST.reopt.Makefile:1.9 Mon Mar 8 18:43:16 2004 +++ reopt/test/TEST.reopt.Makefile Wed Mar 10 15:54:19 2004 @@ -1,4 +1,4 @@ -##===- test/Programs/TEST.reopt.Makefile -------------------*- Makefile -*-===## +##===- reopt/test/TEST.reopt.Makefile ----------------------*- Makefile -*-===## # # Do a reoptimizer build for each program; then run the program. The expected # output is 1) any debug output the reoptimizer outputs, if its debug flags @@ -8,6 +8,12 @@ # This makefile will check 3) for you, which effectively implies checking # 2); it will (erroneously) assume things have broken if you turn on # debug flags, though. +# +# To try one program at a time, say, for example: +# % gmake SUBDIR=MultiSource/Applications/Burg +# To set command-line options for the Reoptimizer, set your LLVM_REOPT +# environment variable; for example: +# % setenv LLVM_REOPT '--debug' # ##===----------------------------------------------------------------------===## From gaeke at cs.uiuc.edu Wed Mar 10 16:03:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 16:03:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Message-ID: <200403102202.QAA23864@kain.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: PhyRegAlloc.cpp updated: 1.140 -> 1.141 --- Log message: Only call verifySavedState if SaveRegAllocState is set AND debugging flag is on. --- Diffs of the changes: (+4 -3) Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.140 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.141 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.140 Mon Mar 8 17:22:02 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Wed Mar 10 16:01:59 2004 @@ -1355,10 +1355,11 @@ colorIncomingArgs(); // Save register allocation state for this function in a Constant. - if (SaveRegAllocState) + if (SaveRegAllocState) { saveState(); - if (DEBUG_RA) { // Check our work. - verifySavedState (); + if (DEBUG_RA) { // Check our work. + verifySavedState (); + } } // Now update the machine code with register names and add any additional From gaeke at cs.uiuc.edu Wed Mar 10 16:22:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 16:22:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Message-ID: <200403102221.QAA25472@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: PhyRegAlloc.cpp updated: 1.141 -> 1.142 --- Log message: Move all the SaveState options and stuff inton one spot at the top of the file. De-constify SaveStateToModule; we have to set both it and SaveRegAllocState explicitly in the reoptimizer. Make SaveRegAllocState an 'external location' option. --- Diffs of the changes: (+10 -8) Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.141 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.142 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.141 Wed Mar 10 16:01:59 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Wed Mar 10 16:21:03 2004 @@ -51,12 +51,6 @@ RegAllocDebugLevel_t DEBUG_RA; -/// The reoptimizer wants to be able to grovel through the register -/// allocator's state after it has done its job. This is a hack. -/// -PhyRegAlloc::SavedStateMapTy ExportedFnAllocState; -const bool SaveStateToModule = true; - static cl::opt DRA_opt("dregalloc", cl::Hidden, cl::location(DEBUG_RA), cl::desc("enable register allocation debugging information"), @@ -69,8 +63,16 @@ clEnumValN(RA_DEBUG_Verbose, "v", "extra debug output"), 0)); -static cl::opt -SaveRegAllocState("save-ra-state", cl::Hidden, +/// The reoptimizer wants to be able to grovel through the register +/// allocator's state after it has done its job. This is a hack. +/// +PhyRegAlloc::SavedStateMapTy ExportedFnAllocState; +bool SaveRegAllocState = false; +bool SaveStateToModule = true; +static cl::opt +SaveRegAllocStateOpt("save-ra-state", cl::Hidden, + cl::location (SaveRegAllocState), + cl::init(false), cl::desc("write reg. allocator state into module")); FunctionPass *getRegisterAllocator(TargetMachine &T) { From gaeke at cs.uiuc.edu Wed Mar 10 16:22:05 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 16:22:05 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Message-ID: <200403102221.QAA25481@zion.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: RuntimeOptimizations.cpp updated: 1.21 -> 1.22 --- Log message: Set SaveStateToModule and SaveRegAllocState explicitly before running any code generation passes, so that we capture the alloc state for use by UnpackTraceFunction. --- Diffs of the changes: (+8 -0) Index: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp diff -u reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.21 reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.22 --- reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.21 Mon Mar 1 15:20:02 2004 +++ reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Wed Mar 10 16:21:12 2004 @@ -34,6 +34,9 @@ static TargetMachine *Target = 0; static IntrinsicLowering *IL = 0; +extern bool SaveStateToModule; +extern bool SaveRegAllocState; + /// This method is called when we have finally constructed a /// trace. The first parameter is the vector of basic blocks that form /// the trace; the second parameter is presumably one of the starting @@ -57,6 +60,11 @@ // a TraceFunction. Trace T (vBB); TraceFunction *TF = TraceFunction::get (T); + + // Force the SPARCv9 register allocator to save its state into a global + // variable + SaveRegAllocState = true; + SaveStateToModule = false; // Verify that the generated function's bytecode is good, then compile it // down to machine code. Then, "unpack" it back into its matrix function. From gaeke at cs.uiuc.edu Wed Mar 10 16:22:09 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 16:22:09 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp TraceToFunction.h Message-ID: <200403102221.QAA25490@zion.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.cpp updated: 1.25 -> 1.26 TraceToFunction.h updated: 1.7 -> 1.8 --- Log message: Constify the keys of ValueToIntMap...why not? :-) Make getFunctionArg() into a 'static inline' function in TraceToFunction.h. Make getCorrespondingValue() look in LiveInToParameterMap first before O2CMap. --- Diffs of the changes: (+13 -10) Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp diff -u reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.25 reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.26 --- reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.25 Wed Mar 10 13:03:43 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.cpp Wed Mar 10 16:21:13 2004 @@ -260,14 +260,6 @@ } } -/// getFunctionArg - Return a pointer to F's ARGNOth argument. -/// -static Argument *getFunctionArg (Function *F, unsigned argno) { - Function::aiterator ai = F->abegin (); - while (argno) { ++ai; --argno; } - return &*ai; -} - /// cloneTraceBBsIntoFunction - Copy the BasicBlocks of the trace T into /// the new Function F, which should be initially empty. Correspondences /// between Original instructions (in T) and their Clones (in F) are added Index: reopt/lib/LightWtProfiling/TraceToFunction.h diff -u reopt/lib/LightWtProfiling/TraceToFunction.h:1.7 reopt/lib/LightWtProfiling/TraceToFunction.h:1.8 --- reopt/lib/LightWtProfiling/TraceToFunction.h:1.7 Wed Mar 10 13:03:44 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.h Wed Mar 10 16:21:13 2004 @@ -18,7 +18,15 @@ typedef std::set LiveVariableSet; typedef std::map BasicBlockMap; typedef std::map ValueMap; -typedef std::map ValueToIntMap; +typedef std::map ValueToIntMap; + +/// getFunctionArg - Return a pointer to F's ARGNOth argument. +/// +static inline Argument *getFunctionArg (Function *F, unsigned argno) { + Function::aiterator ai = F->abegin (); + while (argno) { ++ai; --argno; } + return &*ai; +} // This class encapsulates all the TraceToFunction algorithm's saved baggage. // You can't have a TraceFunction without a Trace, but you might be able to @@ -71,8 +79,11 @@ ValueToIntMap LiveInToParameterMap; Value *getCorrespondingValue (const Value *V) { + if (LiveInToParameterMap.find (V) != LiveInToParameterMap.end ()) { + return getFunctionArg (TraceFn, LiveInToParameterMap[V]); + } ValueMap::iterator i = O2CMap.find (V); - assert (O2CMap.end() == i + assert (O2CMap.end() != i && "getCorrespondingValue called on value not in map"); return i->second; } From lattner at cs.uiuc.edu Wed Mar 10 18:52:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Mar 10 18:52:00 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200403110051.SAA27644@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.143 -> 1.144 --- Log message: Minor additions and cleanups --- Diffs of the changes: (+10 -9) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.143 llvm/docs/ReleaseNotes.html:1.144 --- llvm/docs/ReleaseNotes.html:1.143 Wed Mar 10 15:43:47 2004 +++ llvm/docs/ReleaseNotes.html Wed Mar 10 18:50:54 2004 @@ -96,7 +96,7 @@
    1. A new LLVM source-level debugger has been started.
    2. LLVM 1.2 encodes bytecode files for large programs in 10-30% less space.
    3. -
    4. LLVM can now feed profile information back into optimizers for Profile Guided Optimization, and includes a simple basic block reordering pass.
    5. +
    6. LLVM can now feed profile information back into optimizers for Profile Guided Optimization, includes a simple basic block reordering pass, and supports edge profiling as well as function and block-level profiling.
    7. The LLVM JIT lazily initializes global variables, reducing startup time for programs with lots of globals (like C++ programs).
    8. The build and installation infrastructure in this release is dramatically @@ -109,14 +109,14 @@ href="http://llvm.cs.uiuc.edu/PR203">RPM package generation.
    9. The "tblgen" tool is now documented.
    10. -
    11. The LLVM code generator got a multitude of improvements: +
    12. The target-independent code generator got several improvements:
        -
      • It can now fold spill code into instructions on targets that support it.
      • -
      • A generic machine code spiller/rewriter was added. It provides an API for -global register allocators to eliminate virtual registers and add the -appropriate spill code.
      • -
      • The represenation of machine basic blocks got cleaned up and improved to -allow easier development and more efficient implementation.
      • +
      • It can now fold spill code into instructions (on targets that support it).
      • +
      • A generic machine code spiller/rewriter was added. It provides an API for + global register allocators to eliminate virtual registers and add the + appropriate spill code.
      • +
      • The represenation of machine code basic blocks is more efficient and has + an easier to use interface.
    13. LLVM now no longer depends on the boost library.
    14. @@ -125,6 +125,7 @@ tool. You can activate it with "llc -march=c foo.bc -o foo.c".
    15. LLVM includes a new interprocedural optimization that marks global variables "constant" when they are provably never written to.
    16. +
    17. LLVM now includes a new interprocedural optimization that converts small "by reference" arguments to "by value" arguments, which is often improve the performance of C++ programs substantially.
    @@ -625,7 +626,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/10 21:43:47 $ + Last modified: $Date: 2004/03/11 00:50:54 $ From brukman at cs.uiuc.edu Wed Mar 10 19:02:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:02:00 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Printer.cpp X86CodeEmitter.cpp X86InstrBuilder.h X86InstrInfo.td X86RegisterInfo.cpp X86TargetMachine.cpp X86TargetMachine.h Message-ID: <200403110101.TAA27786@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.149.2.1 -> 1.149.2.2 Printer.cpp updated: 1.76.2.1 -> 1.76.2.2 X86CodeEmitter.cpp updated: 1.46.2.1 -> 1.46.2.2 X86InstrBuilder.h updated: 1.9.4.1 -> 1.9.4.2 X86InstrInfo.td updated: 1.15.2.1 -> 1.15.2.2 X86RegisterInfo.cpp updated: 1.40.4.1 -> 1.40.4.2 X86TargetMachine.cpp updated: 1.44.2.1 -> 1.44.2.2 X86TargetMachine.h updated: 1.21.2.1 -> 1.21.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+306 -202) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.149.2.1 llvm/lib/Target/X86/InstSelectSimple.cpp:1.149.2.2 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.149.2.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Mar 10 19:01:46 2004 @@ -107,6 +107,7 @@ /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the /// function, lowering any calls to unknown intrinsic functions into the /// equivalent LLVM code. + /// void LowerUnknownIntrinsicFunctionCalls(Function &F); /// LoadArgumentsToVirtualRegs - Load all of the arguments to this function @@ -198,8 +199,14 @@ /// void promote32(unsigned targetReg, const ValueRecord &VR); - // getGEPIndex - This is used to fold GEP instructions into X86 addressing - // expressions. + /// getAddressingMode - Get the addressing mode to use to address the + /// specified value. The returned value should be used with addFullAddress. + void getAddressingMode(Value *Addr, unsigned &BaseReg, unsigned &Scale, + unsigned &IndexReg, unsigned &Disp); + + + /// getGEPIndex - This is used to fold GEP instructions into X86 addressing + /// expressions. void getGEPIndex(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP, std::vector &GEPOps, std::vector &GEPTypes, unsigned &BaseReg, @@ -221,11 +228,13 @@ /// emitCastOperation - Common code shared between visitCastInst and /// constant expression cast support. + /// void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP, Value *Src, const Type *DestTy, unsigned TargetReg); /// emitSimpleBinaryOperation - Common code shared between visitSimpleBinary /// and constant expression support. + /// void emitSimpleBinaryOperation(MachineBasicBlock *BB, MachineBasicBlock::iterator IP, Value *Op0, Value *Op1, @@ -238,6 +247,7 @@ /// emitSetCCOperation - Common code shared between visitSetCondInst and /// constant expression support. + /// void emitSetCCOperation(MachineBasicBlock *BB, MachineBasicBlock::iterator IP, Value *Op0, Value *Op1, unsigned Opcode, @@ -245,6 +255,7 @@ /// emitShiftOperation - Common code shared between visitShiftInst and /// constant expression support. + /// void emitShiftOperation(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP, Value *Op, Value *ShiftAmount, bool isLeftShift, @@ -709,9 +720,13 @@ ++NumFPKill; } } + // If we got this far, there is no need to insert the kill instruction. + return false; +#else + return true; +#endif } - // canFoldSetCCIntoBranch - Return the setcc instruction if we can fold it into // the conditional branch instruction which is the only user of the cc // instruction. This is the case if the conditional branch is the only user of @@ -887,6 +902,7 @@ /// emitSetCCOperation - Common code shared between visitSetCondInst and /// constant expression support. +/// void ISel::emitSetCCOperation(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP, Value *Op0, Value *Op1, unsigned Opcode, @@ -913,6 +929,7 @@ /// promote32 - Emit instructions to turn a narrow operand into a 32-bit-wide /// operand, in the specified target register. +/// void ISel::promote32(unsigned targetReg, const ValueRecord &VR) { bool isUnsigned = VR.Ty->isUnsigned(); @@ -1221,6 +1238,7 @@ /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the /// function, lowering any calls to unknown intrinsic functions into the /// equivalent LLVM code. +/// void ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) { for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) @@ -1400,15 +1418,67 @@ } } +static bool isSafeToFoldLoadIntoInstruction(LoadInst &LI, Instruction &User) { + if (LI.getParent() != User.getParent()) + return false; + BasicBlock::iterator It = &LI; + // Check all of the instructions between the load and the user. We should + // really use alias analysis here, but for now we just do something simple. + for (++It; It != BasicBlock::iterator(&User); ++It) { + switch (It->getOpcode()) { + case Instruction::Store: + case Instruction::Call: + case Instruction::Invoke: + return false; + } + } + return true; +} + /// visitSimpleBinary - Implement simple binary operators for integral types... /// OperatorClass is one of: 0 for Add, 1 for Sub, 2 for And, 3 for Or, 4 for /// Xor. +/// void ISel::visitSimpleBinary(BinaryOperator &B, unsigned OperatorClass) { unsigned DestReg = getReg(B); MachineBasicBlock::iterator MI = BB->end(); - emitSimpleBinaryOperation(BB, MI, B.getOperand(0), B.getOperand(1), - OperatorClass, DestReg); + Value *Op0 = B.getOperand(0), *Op1 = B.getOperand(1); + + // Special case: op Reg, load [mem] + if (isa(Op0) && !isa(Op1)) + if (!B.swapOperands()) + std::swap(Op0, Op1); // Make sure any loads are in the RHS. + + unsigned Class = getClassB(B.getType()); + if (isa(Op1) && Class < cFP && + isSafeToFoldLoadIntoInstruction(*cast(Op1), B)) { + + static const unsigned OpcodeTab[][3] = { + // Arithmetic operators + { X86::ADD8rm, X86::ADD16rm, X86::ADD32rm }, // ADD + { X86::SUB8rm, X86::SUB16rm, X86::SUB32rm }, // SUB + + // Bitwise operators + { X86::AND8rm, X86::AND16rm, X86::AND32rm }, // AND + { X86:: OR8rm, X86:: OR16rm, X86:: OR32rm }, // OR + { X86::XOR8rm, X86::XOR16rm, X86::XOR32rm }, // XOR + }; + + assert(Class < cFP && "General code handles 64-bit integer types!"); + unsigned Opcode = OpcodeTab[OperatorClass][Class]; + + unsigned BaseReg, Scale, IndexReg, Disp; + getAddressingMode(cast(Op1)->getOperand(0), BaseReg, + Scale, IndexReg, Disp); + + unsigned Op0r = getReg(Op0); + addFullAddress(BuildMI(BB, Opcode, 2, DestReg).addReg(Op0r), + BaseReg, Scale, IndexReg, Disp); + return; + } + + emitSimpleBinaryOperation(BB, MI, Op0, Op1, OperatorClass, DestReg); } /// emitSimpleBinaryOperation - Implement simple binary operators for integral @@ -1450,83 +1520,82 @@ return; } - if (!isa(Op1) || Class == cLong) { - static const unsigned OpcodeTab[][4] = { - // Arithmetic operators - { X86::ADD8rr, X86::ADD16rr, X86::ADD32rr, X86::FpADD }, // ADD - { X86::SUB8rr, X86::SUB16rr, X86::SUB32rr, X86::FpSUB }, // SUB - - // Bitwise operators - { X86::AND8rr, X86::AND16rr, X86::AND32rr, 0 }, // AND - { X86:: OR8rr, X86:: OR16rr, X86:: OR32rr, 0 }, // OR - { X86::XOR8rr, X86::XOR16rr, X86::XOR32rr, 0 }, // XOR - }; - - bool isLong = false; - if (Class == cLong) { - isLong = true; - Class = cInt; // Bottom 32 bits are handled just like ints - } - - unsigned Opcode = OpcodeTab[OperatorClass][Class]; - assert(Opcode && "Floating point arguments to logical inst?"); + // Special case: op Reg, + if (Class != cLong && isa(Op1)) { + ConstantInt *Op1C = cast(Op1); unsigned Op0r = getReg(Op0, MBB, IP); - unsigned Op1r = getReg(Op1, MBB, IP); - BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r); - - if (isLong) { // Handle the upper 32 bits of long values... - static const unsigned TopTab[] = { - X86::ADC32rr, X86::SBB32rr, X86::AND32rr, X86::OR32rr, X86::XOR32rr - }; - BuildMI(*MBB, IP, TopTab[OperatorClass], 2, - DestReg+1).addReg(Op0r+1).addReg(Op1r+1); + + // xor X, -1 -> not X + if (OperatorClass == 4 && Op1C->isAllOnesValue()) { + static unsigned const NOTTab[] = { X86::NOT8r, X86::NOT16r, X86::NOT32r }; + BuildMI(*MBB, IP, NOTTab[Class], 1, DestReg).addReg(Op0r); + return; } - return; - } - // Special case: op Reg, - ConstantInt *Op1C = cast(Op1); - unsigned Op0r = getReg(Op0, MBB, IP); + // add X, -1 -> dec X + if (OperatorClass == 0 && Op1C->isAllOnesValue()) { + static unsigned const DECTab[] = { X86::DEC8r, X86::DEC16r, X86::DEC32r }; + BuildMI(*MBB, IP, DECTab[Class], 1, DestReg).addReg(Op0r); + return; + } - // xor X, -1 -> not X - if (OperatorClass == 4 && Op1C->isAllOnesValue()) { - static unsigned const NOTTab[] = { X86::NOT8r, X86::NOT16r, X86::NOT32r }; - BuildMI(*MBB, IP, NOTTab[Class], 1, DestReg).addReg(Op0r); - return; - } + // add X, 1 -> inc X + if (OperatorClass == 0 && Op1C->equalsInt(1)) { + static unsigned const DECTab[] = { X86::INC8r, X86::INC16r, X86::INC32r }; + BuildMI(*MBB, IP, DECTab[Class], 1, DestReg).addReg(Op0r); + return; + } + + static const unsigned OpcodeTab[][3] = { + // Arithmetic operators + { X86::ADD8ri, X86::ADD16ri, X86::ADD32ri }, // ADD + { X86::SUB8ri, X86::SUB16ri, X86::SUB32ri }, // SUB + + // Bitwise operators + { X86::AND8ri, X86::AND16ri, X86::AND32ri }, // AND + { X86:: OR8ri, X86:: OR16ri, X86:: OR32ri }, // OR + { X86::XOR8ri, X86::XOR16ri, X86::XOR32ri }, // XOR + }; + + assert(Class < cFP && "General code handles 64-bit integer types!"); + unsigned Opcode = OpcodeTab[OperatorClass][Class]; - // add X, -1 -> dec X - if (OperatorClass == 0 && Op1C->isAllOnesValue()) { - static unsigned const DECTab[] = { X86::DEC8r, X86::DEC16r, X86::DEC32r }; - BuildMI(*MBB, IP, DECTab[Class], 1, DestReg).addReg(Op0r); + uint64_t Op1v = cast(Op1C)->getRawValue(); + BuildMI(*MBB, IP, Opcode, 5, DestReg).addReg(Op0r).addImm(Op1v); return; } - // add X, 1 -> inc X - if (OperatorClass == 0 && Op1C->equalsInt(1)) { - static unsigned const DECTab[] = { X86::INC8r, X86::INC16r, X86::INC32r }; - BuildMI(*MBB, IP, DECTab[Class], 1, DestReg).addReg(Op0r); - return; - } - - static const unsigned OpcodeTab[][3] = { + // Finally, handle the general case now. + static const unsigned OpcodeTab[][4] = { // Arithmetic operators - { X86::ADD8ri, X86::ADD16ri, X86::ADD32ri }, // ADD - { X86::SUB8ri, X86::SUB16ri, X86::SUB32ri }, // SUB - + { X86::ADD8rr, X86::ADD16rr, X86::ADD32rr, X86::FpADD }, // ADD + { X86::SUB8rr, X86::SUB16rr, X86::SUB32rr, X86::FpSUB }, // SUB + // Bitwise operators - { X86::AND8ri, X86::AND16ri, X86::AND32ri }, // AND - { X86:: OR8ri, X86:: OR16ri, X86:: OR32ri }, // OR - { X86::XOR8ri, X86::XOR16ri, X86::XOR32ri }, // XOR + { X86::AND8rr, X86::AND16rr, X86::AND32rr, 0 }, // AND + { X86:: OR8rr, X86:: OR16rr, X86:: OR32rr, 0 }, // OR + { X86::XOR8rr, X86::XOR16rr, X86::XOR32rr, 0 }, // XOR }; - - assert(Class < 3 && "General code handles 64-bit integer types!"); + + bool isLong = false; + if (Class == cLong) { + isLong = true; + Class = cInt; // Bottom 32 bits are handled just like ints + } + unsigned Opcode = OpcodeTab[OperatorClass][Class]; - uint64_t Op1v = cast(Op1C)->getRawValue(); - - // Mask off any upper bits of the constant, if there are any... - Op1v &= (1ULL << (8 << Class)) - 1; - BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1v); + assert(Opcode && "Floating point arguments to logical inst?"); + unsigned Op0r = getReg(Op0, MBB, IP); + unsigned Op1r = getReg(Op1, MBB, IP); + BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addReg(Op1r); + + if (isLong) { // Handle the upper 32 bits of long values... + static const unsigned TopTab[] = { + X86::ADC32rr, X86::SBB32rr, X86::AND32rr, X86::OR32rr, X86::XOR32rr + }; + BuildMI(*MBB, IP, TopTab[OperatorClass], 2, + DestReg+1).addReg(Op0r+1).addReg(Op1r+1); + } } /// doMultiply - Emit appropriate instructions to multiply together the @@ -1895,31 +1964,66 @@ } -/// visitLoadInst - Implement LLVM load instructions in terms of the x86 'mov' -/// instruction. The load and store instructions are the only place where we -/// need to worry about the memory layout of the target machine. -/// -void ISel::visitLoadInst(LoadInst &I) { - unsigned DestReg = getReg(I); - unsigned BaseReg = 0, Scale = 1, IndexReg = 0, Disp = 0; - Value *Addr = I.getOperand(0); +void ISel::getAddressingMode(Value *Addr, unsigned &BaseReg, unsigned &Scale, + unsigned &IndexReg, unsigned &Disp) { + BaseReg = 0; Scale = 1; IndexReg = 0; Disp = 0; if (GetElementPtrInst *GEP = dyn_cast(Addr)) { if (isGEPFoldable(BB, GEP->getOperand(0), GEP->op_begin()+1, GEP->op_end(), BaseReg, Scale, IndexReg, Disp)) - Addr = 0; // Address is consumed! + return; } else if (ConstantExpr *CE = dyn_cast(Addr)) { if (CE->getOpcode() == Instruction::GetElementPtr) if (isGEPFoldable(BB, CE->getOperand(0), CE->op_begin()+1, CE->op_end(), BaseReg, Scale, IndexReg, Disp)) - Addr = 0; + return; } - if (Addr) { - // If it's not foldable, reset addr mode. - BaseReg = getReg(Addr); - Scale = 1; IndexReg = 0; Disp = 0; + // If it's not foldable, reset addr mode. + BaseReg = getReg(Addr); + Scale = 1; IndexReg = 0; Disp = 0; +} + + +/// visitLoadInst - Implement LLVM load instructions in terms of the x86 'mov' +/// instruction. The load and store instructions are the only place where we +/// need to worry about the memory layout of the target machine. +/// +void ISel::visitLoadInst(LoadInst &I) { + // Check to see if this load instruction is going to be folded into a binary + // instruction, like add. If so, we don't want to emit it. Wouldn't a real + // pattern matching instruction selector be nice? + if (I.hasOneUse() && getClassB(I.getType()) < cFP) { + Instruction *User = cast(I.use_back()); + switch (User->getOpcode()) { + default: User = 0; break; + case Instruction::Add: + case Instruction::Sub: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + break; + } + + if (User) { + // Okay, we found a user. If the load is the first operand and there is + // no second operand load, reverse the operand ordering. Note that this + // can fail for a subtract (ie, no change will be made). + if (!isa(User->getOperand(1))) + cast(User)->swapOperands(); + + // Okay, now that everything is set up, if this load is used by the second + // operand, and if there are no instructions that invalidate the load + // before the binary operator, eliminate the load. + if (User->getOperand(1) == &I && + isSafeToFoldLoadIntoInstruction(I, *User)) + return; // Eliminate the load! + } } + unsigned DestReg = getReg(I); + unsigned BaseReg = 0, Scale = 1, IndexReg = 0, Disp = 0; + getAddressingMode(I.getOperand(0), BaseReg, Scale, IndexReg, Disp); + unsigned Class = getClassB(I.getType()); if (Class == cLong) { addFullAddress(BuildMI(BB, X86::MOV32rm, 4, DestReg), @@ -1942,24 +2046,8 @@ /// instruction. /// void ISel::visitStoreInst(StoreInst &I) { - unsigned BaseReg = 0, Scale = 1, IndexReg = 0, Disp = 0; - Value *Addr = I.getOperand(1); - if (GetElementPtrInst *GEP = dyn_cast(Addr)) { - if (isGEPFoldable(BB, GEP->getOperand(0), GEP->op_begin()+1, GEP->op_end(), - BaseReg, Scale, IndexReg, Disp)) - Addr = 0; // Address is consumed! - } else if (ConstantExpr *CE = dyn_cast(Addr)) { - if (CE->getOpcode() == Instruction::GetElementPtr) - if (isGEPFoldable(BB, CE->getOperand(0), CE->op_begin()+1, CE->op_end(), - BaseReg, Scale, IndexReg, Disp)) - Addr = 0; - } - - if (Addr) { - // If it's not foldable, reset addr mode. - BaseReg = getReg(Addr); - Scale = 1; IndexReg = 0; Disp = 0; - } + unsigned BaseReg, Scale, IndexReg, Disp; + getAddressingMode(I.getOperand(1), BaseReg, Scale, IndexReg, Disp); const Type *ValTy = I.getOperand(0)->getType(); unsigned Class = getClassB(ValTy); @@ -2003,8 +2091,9 @@ } -/// visitCastInst - Here we have various kinds of copying with or without -/// sign extension going on. +/// visitCastInst - Here we have various kinds of copying with or without sign +/// extension going on. +/// void ISel::visitCastInst(CastInst &CI) { Value *Op = CI.getOperand(0); // If this is a cast from a 32-bit integer to a Long type, and the only uses @@ -2028,8 +2117,9 @@ emitCastOperation(BB, MI, Op, CI.getType(), DestReg); } -/// emitCastOperation - Common code shared between visitCastInst and -/// constant expression cast support. +/// emitCastOperation - Common code shared between visitCastInst and constant +/// expression cast support. +/// void ISel::emitCastOperation(MachineBasicBlock *BB, MachineBasicBlock::iterator IP, Value *Src, const Type *DestTy, @@ -2371,7 +2461,8 @@ } } - +/// visitGetElementPtrInst - instruction-select GEP instructions +/// void ISel::visitGetElementPtrInst(GetElementPtrInst &I) { // If this GEP instruction will be folded into all of its users, we don't need // to explicitly calculate it! Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.76.2.1 llvm/lib/Target/X86/Printer.cpp:1.76.2.2 --- llvm/lib/Target/X86/Printer.cpp:1.76.2.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/X86/Printer.cpp Wed Mar 10 19:01:46 2004 @@ -7,21 +7,23 @@ // //===----------------------------------------------------------------------===// // -// This file contains a printer that converts from our internal -// representation of machine-dependent LLVM code to Intel-format -// assembly language. This printer is the output mechanism used -// by `llc' and `lli -print-machineinstrs' on X86. +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to Intel-format assembly language. This +// printer is the output mechanism used by `llc' and `lli -print-machineinstrs' +// on X86. // //===----------------------------------------------------------------------===// #include "X86.h" #include "X86InstrInfo.h" +#include "X86TargetMachine.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Assembly/Writer.h" -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Mangler.h" @@ -38,6 +40,37 @@ cl::opt EmitCygwin("enable-cygwin-compatible-output", cl::Hidden, cl::desc("Emit X86 assembly code suitable for consumption by cygwin")); + struct GasBugWorkaroundEmitter : public MachineCodeEmitter { + GasBugWorkaroundEmitter(std::ostream& o) + : O(o), OldFlags(O.flags()), firstByte(true) { + O << std::hex; + } + + ~GasBugWorkaroundEmitter() { + O.flags(OldFlags); + O << "\t# "; + } + + virtual void emitByte(unsigned char B) { + if (!firstByte) O << "\n\t"; + firstByte = false; + O << ".byte 0x" << (unsigned) B; + } + + // These should never be called + virtual void emitWord(unsigned W) { assert(0); } + virtual uint64_t getGlobalValueAddress(GlobalValue *V) { assert(0); } + virtual uint64_t getGlobalValueAddress(const std::string &Name) { assert(0); } + virtual uint64_t getConstantPoolEntryAddress(unsigned Index) { assert(0); } + virtual uint64_t getCurrentPCValue() { assert(0); } + virtual uint64_t forceCompilationOf(Function *F) { assert(0); } + + private: + std::ostream& O; + std::ios::fmtflags OldFlags; + bool firstByte; + }; + struct Printer : public MachineFunctionPass { /// Output stream on which we're printing assembly code. /// @@ -635,6 +668,7 @@ O << ", "; printOp(MI->getOperand(2)); } + checkImplUses(Desc); O << "\n"; return; } @@ -656,6 +690,7 @@ O << ", "; printOp(MI->getOperand(5)); } + checkImplUses(Desc); O << "\n"; return; } @@ -768,82 +803,37 @@ const MachineOperand &Op3 = MI->getOperand(3); - // Bug: The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" + // gas bugs: + // + // The 80-bit FP store-pop instruction "fstp XWORD PTR [...]" // is misassembled by gas in intel_syntax mode as its 32-bit // equivalent "fstp DWORD PTR [...]". Workaround: Output the raw // opcode bytes instead of the instruction. - if (MI->getOpcode() == X86::FSTP80m) { - if ((MI->getOperand(0).getReg() == X86::ESP) - && (MI->getOperand(1).getImmedValue() == 1)) { - if (Op3.isImmediate() && - Op3.getImmedValue() >= -128 && Op3.getImmedValue() <= 127) { - // 1 byte disp. - O << ".byte 0xdb, 0x7c, 0x24, 0x" << std::hex - << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# "; - } else { - O << ".byte 0xdb, 0xbc, 0x24\n\t"; - O << ".long "; - printOp(Op3); - O << "\t# "; - } - } - } - - // Bug: The 80-bit FP load instruction "fld XWORD PTR [...]" is + // + // The 80-bit FP load instruction "fld XWORD PTR [...]" is // misassembled by gas in intel_syntax mode as its 32-bit // equivalent "fld DWORD PTR [...]". Workaround: Output the raw // opcode bytes instead of the instruction. - if (MI->getOpcode() == X86::FLD80m && - MI->getOperand(0).getReg() == X86::ESP && - MI->getOperand(1).getImmedValue() == 1) { - if (Op3.isImmediate() && Op3.getImmedValue() >= -128 && - Op3.getImmedValue() <= 127) { // 1 byte displacement - O << ".byte 0xdb, 0x6c, 0x24, 0x" << std::hex - << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# "; - } else { - O << ".byte 0xdb, 0xac, 0x24\n\t"; - O << ".long "; - printOp(Op3); - O << "\t# "; - } - } - - // Bug: gas intel_syntax mode treats "fild QWORD PTR [...]" as an + // + // gas intel_syntax mode treats "fild QWORD PTR [...]" as an // invalid opcode, saying "64 bit operations are only supported in // 64 bit modes." libopcodes disassembles it as "fild DWORD PTR // [...]", which is wrong. Workaround: Output the raw opcode bytes // instead of the instruction. - if (MI->getOpcode() == X86::FILD64m && - MI->getOperand(0).getReg() == X86::ESP && - MI->getOperand(1).getImmedValue() == 1) { - if (Op3.isImmediate() && Op3.getImmedValue() >= -128 && - Op3.getImmedValue() <= 127) { // 1 byte displacement - O << ".byte 0xdf, 0x6c, 0x24, 0x" << std::hex - << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# "; - } else { - O << ".byte 0xdf, 0xac, 0x24\n\t"; - O << ".long "; - printOp(Op3); - O << std::dec << "\t# "; - } + // + // gas intel_syntax mode treats "fistp QWORD PTR [...]" as an + // invalid opcode, saying "64 bit operations are only supported in + // 64 bit modes." libopcodes disassembles it as "fistpll DWORD PTR + // [...]", which is wrong. Workaround: Output the raw opcode bytes + // instead of the instruction. + if (MI->getOpcode() == X86::FSTP80m || + MI->getOpcode() == X86::FLD80m || + MI->getOpcode() == X86::FILD64m || + MI->getOpcode() == X86::FISTP64m) { + GasBugWorkaroundEmitter gwe(O); + X86::emitInstruction(gwe, (X86InstrInfo&)TM.getInstrInfo(), *MI); } - // Bug: gas intel_syntax mode treats "fistp QWORD PTR [...]" as - // an invalid opcode, saying "64 bit operations are only - // supported in 64 bit modes." libopcodes disassembles it as - // "fistpll DWORD PTR [...]", which is wrong. Workaround: Output - // "fistpll DWORD PTR " instead, which is what libopcodes is - // expecting to see. - if (MI->getOpcode() == X86::FISTP64m) { - O << "fistpll DWORD PTR "; - printMemReference(MI, 0); - if (MI->getNumOperands() == 5) { - O << ", "; - printOp(MI->getOperand(4)); - } - O << "\t# "; - } - O << TII.getName(MI->getOpcode()) << " "; O << sizePtr(Desc) << " "; printMemReference(MI, 0); @@ -851,10 +841,10 @@ O << ", "; printOp(MI->getOperand(4)); } + checkImplUses(Desc); O << "\n"; return; } - default: O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, TM); break; } Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.46.2.1 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.46.2.2 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.46.2.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Wed Mar 10 19:01:46 2004 @@ -168,7 +168,6 @@ } - namespace { class Emitter : public MachineFunctionPass { const X86InstrInfo *II; @@ -176,7 +175,9 @@ std::map BasicBlockAddrs; std::vector > BBRefs; public: - Emitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} + explicit Emitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} + Emitter(MachineCodeEmitter &mce, const X86InstrInfo& ii) + : II(&ii), MCE(mce) {} bool runOnMachineFunction(MachineFunction &MF); @@ -184,11 +185,12 @@ return "X86 Machine Code Emitter"; } + void emitInstruction(const MachineInstr &MI); + private: - void emitBasicBlock(MachineBasicBlock &MBB); - void emitInstruction(MachineInstr &MI); + void emitBasicBlock(const MachineBasicBlock &MBB); - void emitPCRelativeBlockAddress(BasicBlock *BB); + void emitPCRelativeBlockAddress(const BasicBlock *BB); void emitMaybePCRelativeValue(unsigned Address, bool isPCRelative); void emitGlobalAddressForCall(GlobalValue *GV); void emitGlobalAddressForPtr(GlobalValue *GV); @@ -203,6 +205,14 @@ }; } +// This function is required by Printer.cpp to workaround gas bugs +void llvm::X86::emitInstruction(MachineCodeEmitter& mce, + const X86InstrInfo& ii, + const MachineInstr& mi) +{ + Emitter(mce, ii).emitInstruction(mi); +} + /// addPassesToEmitMachineCode - Add passes to the specified pass manager to get /// machine code emitted. This uses a MachineCodeEmitter object to handle /// actually outputting the machine code and resolving things like the address @@ -237,11 +247,11 @@ return false; } -void Emitter::emitBasicBlock(MachineBasicBlock &MBB) { +void Emitter::emitBasicBlock(const MachineBasicBlock &MBB) { if (uint64_t Addr = MCE.getCurrentPCValue()) BasicBlockAddrs[MBB.getBasicBlock()] = Addr; - for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) + for (MachineBasicBlock::const_iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) emitInstruction(*I); } @@ -251,7 +261,7 @@ /// (because this is a forward branch), it keeps track of the information /// necessary to resolve this address later (and emits a dummy value). /// -void Emitter::emitPCRelativeBlockAddress(BasicBlock *BB) { +void Emitter::emitPCRelativeBlockAddress(const BasicBlock *BB) { // FIXME: Emit backward branches directly BBRefs.push_back(std::make_pair(BB, MCE.getCurrentPCValue())); MCE.emitWord(0); // Emit a dummy value @@ -476,7 +486,7 @@ } } -void Emitter::emitInstruction(MachineInstr &MI) { +void Emitter::emitInstruction(const MachineInstr &MI) { NumEmitted++; // Keep track of the # of mi's emitted unsigned Opcode = MI.getOpcode(); @@ -516,7 +526,7 @@ case X86II::RawFrm: MCE.emitByte(BaseOpcode); if (MI.getNumOperands() == 1) { - MachineOperand &MO = MI.getOperand(0); + const MachineOperand &MO = MI.getOperand(0); if (MO.isPCRelativeDisp()) { // Conditional branch... FIXME: this should use an MBB destination! emitPCRelativeBlockAddress(cast(MO.getVRegValue())); @@ -536,7 +546,7 @@ case X86II::AddRegFrm: MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg())); if (MI.getNumOperands() == 2) { - MachineOperand &MO1 = MI.getOperand(1); + const MachineOperand &MO1 = MI.getOperand(1); if (Value *V = MO1.getVRegValueOrNull()) { assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!"); emitGlobalAddressForPtr(cast(V)); Index: llvm/lib/Target/X86/X86InstrBuilder.h diff -u llvm/lib/Target/X86/X86InstrBuilder.h:1.9.4.1 llvm/lib/Target/X86/X86InstrBuilder.h:1.9.4.2 --- llvm/lib/Target/X86/X86InstrBuilder.h:1.9.4.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/X86/X86InstrBuilder.h Wed Mar 10 19:01:46 2004 @@ -54,6 +54,7 @@ unsigned Scale, unsigned IndexReg, unsigned Disp) { + assert (Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8); return MIB.addReg(BaseReg).addZImm(Scale).addReg(IndexReg).addSImm(Disp); } Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.15.2.1 llvm/lib/Target/X86/X86InstrInfo.td:1.15.2.2 --- llvm/lib/Target/X86/X86InstrInfo.td:1.15.2.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Mar 10 19:01:46 2004 @@ -53,7 +53,7 @@ def Mem16 : MemType<2>; def Mem32 : MemType<3>; def Mem64 : MemType<4>; -def Mem80 : MemType<4>; +def Mem80 : MemType<5>; def Mem128 : MemType<6>; // FPFormat - This specifies what form this FP instruction has. This is used by @@ -294,9 +294,12 @@ // Conditional moves. These are modelled as X = cmovXX Y, Z. Eventually // register allocated to cmovXX XY, Z -def CMOVE16rr : I<"cmove", 0x44, MRMSrcReg>, TB, OpSize; // if ==, R16 = R16 -def CMOVNE32rr: I<"cmovne",0x45, MRMSrcReg>, TB; // if !=, R32 = R32 -def CMOVS32rr : I<"cmovs", 0x48, MRMSrcReg>, TB; // if signed, R32 = R32 +def CMOVE16rr : I <"cmove", 0x44, MRMSrcReg>, TB, OpSize; // if ==, R16 = R16 +def CMOVE16rm : Im16<"cmove", 0x44, MRMSrcMem>, TB, OpSize; // if ==, R16 = [mem16] +def CMOVNE32rr: I <"cmovne",0x45, MRMSrcReg>, TB; // if !=, R32 = R32 +def CMOVNE32rm: Im32<"cmovne",0x45, MRMSrcMem>, TB; // if !=, R32 = [mem32] +def CMOVS32rr : I <"cmovs", 0x48, MRMSrcReg>, TB; // if signed, R32 = R32 +def CMOVS32rm : Im32<"cmovs", 0x48, MRMSrcMem>, TB; // if signed, R32 = [mem32] // unary instructions def NEG8r : I <"neg", 0xF6, MRM3r>; // R8 = -R8 = 0-R8 @@ -397,6 +400,7 @@ def XOR32mi8 : Im32i8<"xor", 0x83, MRM6m >; // [mem32] ^= imm8 // Shift instructions +// FIXME: provide shorter instructions when imm8 == 1 def SHL8rCL : I <"shl", 0xD2, MRM4r > , UsesCL; // R8 <<= cl def SHL16rCL : I <"shl", 0xD3, MRM4r >, OpSize, UsesCL; // R16 <<= cl def SHL32rCL : I <"shl", 0xD3, MRM4r > , UsesCL; // R32 <<= cl Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.40.4.1 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.40.4.2 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.40.4.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Mar 10 19:01:46 2004 @@ -260,6 +260,9 @@ case X86::MOV8rr: NI = MakeRMInst(X86::MOV8rm , FrameIndex, MI); break; case X86::MOV16rr: NI = MakeRMInst(X86::MOV16rm, FrameIndex, MI); break; case X86::MOV32rr: NI = MakeRMInst(X86::MOV32rm, FrameIndex, MI); break; + case X86::CMOVE16rr: NI = MakeRMInst(X86::CMOVE16rm , FrameIndex, MI); break; + case X86::CMOVNE32rr: NI = MakeRMInst(X86::CMOVNE32rm, FrameIndex, MI); break; + case X86::CMOVS32rr: NI = MakeRMInst(X86::CMOVS32rm , FrameIndex, MI); break; case X86::ADD8rr: NI = MakeRMInst(X86::ADD8rm , FrameIndex, MI); break; case X86::ADD16rr: NI = MakeRMInst(X86::ADD16rm, FrameIndex, MI); break; case X86::ADD32rr: NI = MakeRMInst(X86::ADD32rm, FrameIndex, MI); break; Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.44.2.1 llvm/lib/Target/X86/X86TargetMachine.cpp:1.44.2.2 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.44.2.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Wed Mar 10 19:01:46 2004 @@ -25,8 +25,6 @@ using namespace llvm; namespace { - cl::opt PrintCode("print-machineinstrs", - cl::desc("Print generated machine code")); cl::opt NoPatternISel("disable-pattern-isel", cl::init(true), cl::desc("Use the 'simple' X86 instruction selector")); cl::opt NoSSAPeephole("disable-ssa-peephole", cl::init(true), @@ -79,18 +77,18 @@ PM.add(createX86SSAPeepholeOptimizerPass()); // Print the instruction selected machine code... - if (PrintCode) + if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); // Perform register allocation to convert to a concrete x86 representation PM.add(createRegisterAllocator()); - if (PrintCode) + if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); PM.add(createX86FloatingPointStackifierPass()); - if (PrintCode) + if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); // Insert prolog/epilog code. Eliminate abstract frame index references... @@ -98,7 +96,7 @@ PM.add(createX86PeepholeOptimizerPass()); - if (PrintCode) // Print the register-allocated code + if (PrintMachineCode) // Print the register-allocated code PM.add(createX86CodePrinterPass(std::cerr, *this)); if (!DisableOutput) @@ -138,18 +136,18 @@ // FIXME: Add SSA based peephole optimizer here. // Print the instruction selected machine code... - if (PrintCode) + if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); // Perform register allocation to convert to a concrete x86 representation PM.add(createRegisterAllocator()); - if (PrintCode) + if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); PM.add(createX86FloatingPointStackifierPass()); - if (PrintCode) + if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); // Insert prolog/epilog code. Eliminate abstract frame index references... @@ -157,7 +155,7 @@ PM.add(createX86PeepholeOptimizerPass()); - if (PrintCode) // Print the register-allocated code + if (PrintMachineCode) // Print the register-allocated code PM.add(createX86CodePrinterPass(std::cerr, TM)); } Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.21.2.1 llvm/lib/Target/X86/X86TargetMachine.h:1.21.2.2 --- llvm/lib/Target/X86/X86TargetMachine.h:1.21.2.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/X86/X86TargetMachine.h Wed Mar 10 19:01:46 2004 @@ -53,6 +53,13 @@ virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out); }; + // this is implemented in X86CodeEmitter.cpp + namespace X86 { + void emitInstruction(MachineCodeEmitter& mce, + const X86InstrInfo& ii, + const MachineInstr& MI); + } + } // End llvm namespace #endif From brukman at cs.uiuc.edu Wed Mar 10 19:04:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:04:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200403110103.TAA27882@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.21.2.1 -> 1.21.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+20 -0) Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.21.2.1 llvm/lib/Target/TargetMachine.cpp:1.21.2.2 --- llvm/lib/Target/TargetMachine.cpp:1.21.2.1 Mon Mar 1 17:58:13 2004 +++ llvm/lib/Target/TargetMachine.cpp Wed Mar 10 19:03:49 2004 @@ -14,9 +14,23 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Type.h" #include "llvm/IntrinsicLowering.h" +#include "Support/CommandLine.h" using namespace llvm; //--------------------------------------------------------------------------- +// Command-line options that tend to be useful on more than one back-end. +// + +namespace llvm { + bool PrintMachineCode; +}; +namespace { + cl::opt PrintCode("print-machineinstrs", + cl::desc("Print generated machine code"), + cl::location(PrintMachineCode), cl::init(false)); +}; + +//--------------------------------------------------------------------------- // TargetMachine Class // TargetMachine::TargetMachine(const std::string &name, IntrinsicLowering *il, @@ -28,6 +42,12 @@ : Name(name), DataLayout(name, LittleEndian, PtrSize, PtrAl, DoubleAl, FloatAl, LongAl, IntAl, ShortAl, ByteAl) { + IL = il ? il : new DefaultIntrinsicLowering(); +} + +TargetMachine::TargetMachine(const std::string &name, IntrinsicLowering *il, + const Module &M) + : Name(name), DataLayout(name, &M) { IL = il ? il : new DefaultIntrinsicLowering(); } From brukman at cs.uiuc.edu Wed Mar 10 19:05:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/utils/RegressionFinder.pl llvm-native-gcc profile.pl Message-ID: <200403110104.TAA27944@zion.cs.uiuc.edu> Changes in directory llvm/utils: RegressionFinder.pl added (r1.2.2.1) llvm-native-gcc updated: 1.1.4.1 -> 1.1.4.2 profile.pl updated: 1.4.4.1 -> 1.4.4.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+204 -14) Index: llvm/utils/RegressionFinder.pl diff -c /dev/null llvm/utils/RegressionFinder.pl:1.2.2.1 *** /dev/null Wed Mar 10 19:04:07 2004 --- llvm/utils/RegressionFinder.pl Wed Mar 10 19:03:57 2004 *************** *** 0 **** --- 1,186 ---- + #! /usr/bin/perl + # Script to find regressions by binary-searching a time interval in the + # CVS tree. Written by Brian Gaeke on 2-Mar-2004. + # + + require 5.6.0; # NOTE: This script not tested with earlier versions. + use Getopt::Std; + use POSIX; + use Time::Local; + use IO::Handle; + + sub usage { + print STDERR <) { + if (/$regex/) { + close FILE; + return 1; + } + } + close FILE; + return 0; + } + + sub updateSources { + my ($time) = @_; + my $inst = "include/llvm/Instruction.h"; + unlink($inst); + run( "cvs update -D'" . timeAsString($time) . "'" ); + if ( !contains( $inst, 'class Instruction.*Annotable' ) ) { + run("patch -F100 -p0 < makeInstructionAnnotable.patch"); + } + } + + sub regressionPresentAt { + my ($time) = @_; + + updateSources($time); + buildLibrariesAndTools(); + my $rc = run($SCRIPT); + if ($rc) { + print LOG "** Found that regression was PRESENT at " + . timeAsString($time) . "\n"; + return 1; + } + else { + print LOG "** Found that regression was ABSENT at " + . timeAsString($time) . "\n"; + return 0; + } + } + + sub regressionAbsentAt { + my ($time) = @_; + return !regressionPresentAt($time); + } + + sub closeTo { + my ( $time1, $time2 ) = @_; + return abs( $time1 - $time2 ) < 600; # 10 minutes seems reasonable. + } + + sub halfWayPoint { + my ( $time1, $time2 ) = @_; + my $halfSpan = int( abs( $time1 - $time2 ) / 2 ); + if ( $time1 < $time2 ) { + return $time1 + $halfSpan; + } + else { + return $time2 + $halfSpan; + } + } + + sub checkBoundaryConditions { + print LOG "** Checking for presence of regression at ", timeAsString($DTIME), + "\n"; + if ( !regressionPresentAt($DTIME) ) { + die ( "** Can't help you; $SCRIPT says regression absent at dtime: " + . timeAsString($DTIME) + . "\n" ); + } + print LOG "** Checking for absence of regression at ", timeAsString($WTIME), + "\n"; + if ( !regressionAbsentAt($WTIME) ) { + die ( "** Can't help you; $SCRIPT says regression present at wtime: " + . timeAsString($WTIME) + . "\n" ); + } + } + + ############################################################################## + + # Set up log files + open (STDERR, ">&STDOUT") || die "** Can't redirect std.err: $!\n"; + autoflush STDOUT 1; + autoflush STDERR 1; + open (LOG, ">RegFinder.log") || die "** can't write RegFinder.log: $!\n"; + autoflush LOG 1; + # Check command line arguments and environment variables + getopts('Iw:d:t:c:'); + if ( !( $opt_w && $opt_d && $opt_t && $opt_c ) ) { + usage; + } + $MAKE = $ENV{'MAKE'}; + $MAKE = 'gmake' unless $MAKE; + $WTIME = timeAsSeconds($opt_w); + print LOG "** Assuming worked at ", timeAsString($WTIME), "\n"; + $DTIME = timeAsSeconds($opt_d); + print LOG "** Assuming didn't work at ", timeAsString($DTIME), "\n"; + $opt_t =~ s/\s*//g; + $SCRIPT = $opt_c; + die "** $SCRIPT is not executable or not found\n" unless -x $SCRIPT; + print LOG "** Checking for the regression using $SCRIPT\n"; + @TOOLS = split ( /,/, $opt_t ); + print LOG ( + "** Going to rebuild: ", + ( join ", ", @TOOLS ), + " before each $SCRIPT run\n" + ); + if ($opt_I) { checkBoundaryConditions(); } + # do the dirty work: + while ( !closeTo( $DTIME, $WTIME ) ) { + my $halfPt = halfWayPoint( $DTIME, $WTIME ); + print LOG "** Checking whether regression is present at ", + timeAsString($halfPt), "\n"; + if ( regressionPresentAt($halfPt) ) { + $DTIME = $halfPt; + } + else { + $WTIME = $halfPt; + } + } + # Tell them what we found + print LOG "** Narrowed it down to:\n"; + print LOG "** Worked at: ", timeAsString($WTIME), "\n"; + print LOG "** Did not work at: ", timeAsString($DTIME), "\n"; + close LOG; + exit 0; Index: llvm/utils/llvm-native-gcc diff -u llvm/utils/llvm-native-gcc:1.1.4.1 llvm/utils/llvm-native-gcc:1.1.4.2 --- llvm/utils/llvm-native-gcc:1.1.4.1 Mon Mar 1 17:59:25 2004 +++ llvm/utils/llvm-native-gcc Wed Mar 10 19:03:57 2004 @@ -4,7 +4,7 @@ # set up defaults. $Verbose = 0; -$SaveTemps = 0; +$SaveTemps = 1; $PreprocessOnly = 0; $CompileDontLink = 0; $Backend = 'cbe'; @@ -114,14 +114,14 @@ } else { $GeneratedCode = "/tmp/nativebuild-$$.c"; } - run "llc -march=c -f -o $GeneratedCode $BCFile"; + run "llc -enable-correct-eh-support -march=c -f -o $GeneratedCode $BCFile"; } elsif ($Backend eq 'llc') { if ($SaveTemps) { $GeneratedCode = "${OutputFile}.s"; } else { $GeneratedCode = "/tmp/nativebuild-$$.s"; } - run "llc -f -o $GeneratedCode $BCFile"; + run "llc -enable-correct-eh-support -f -o $GeneratedCode $BCFile"; } my $LibDirs = join (" ", @LibDirs); my $Libs = join (" ", @Libs); @@ -145,10 +145,10 @@ my $GeneratedCode; if ($Backend eq 'cbe') { $GeneratedCode = "${OutputFile}.cbe.c"; - run "llc -march=c -f -o $GeneratedCode $BCFile"; + run "llc -enable-correct-eh-support -march=c -f -o $GeneratedCode $BCFile"; } elsif ($Backend eq 'llc') { $GeneratedCode = "${OutputFile}.llc.s"; - run "llc -f -o $GeneratedCode $BCFile"; + run "llc -enable-correct-eh-support -f -o $GeneratedCode $BCFile"; } my $NativeGCCOptions = ""; if ($CompileDontLink) { Index: llvm/utils/profile.pl diff -u llvm/utils/profile.pl:1.4.4.1 llvm/utils/profile.pl:1.4.4.2 --- llvm/utils/profile.pl:1.4.4.1 Mon Mar 1 17:59:25 2004 +++ llvm/utils/profile.pl Wed Mar 10 19:03:57 2004 @@ -8,15 +8,16 @@ # Syntax: profile.pl [OPTIONS] bytecodefile # # OPTIONS may include one or more of the following: -# -block - Enable basicblock-level profiling -# -function - Enable function-level profiling +# -block - Enable basicblock profiling +# -edge - Enable edge profiling +# -function - Enable function profiling # -o - Emit profiling information to the specified file, instead # of llvmprof.out # # Any unrecognized options are passed into the invocation of llvm-prof # -my $ProfilePass = "-insert-block-profiling"; +my $ProfilePass = "-insert-edge-profiling"; my $LLVMProfOpts = ""; my $ProgramOpts = ""; @@ -28,7 +29,8 @@ last if /^--$/; # Stop processing arguments on -- # List command line options here... - if (/^-?-block$/) { $ProfilePass = "-insert-block-profiling"; next; } + if (/^-?-block$/) { $ProfilePass = "-insert-block-profiling"; next; } + if (/^-?-edge$/) { $ProfilePass = "-insert-edge-profiling"; next; } if (/^-?-function$/) { $ProfilePass = "-insert-function-profiling"; next; } if (/^-?-o$/) { # Read -o filename... die "-o option requires a filename argument!" if (!scalar(@ARGV)); @@ -41,8 +43,9 @@ print "OVERVIEW: profile.pl - Instrumentation and profile printer.\n\n"; print "USAGE: profile.pl [options] program.bc \n\n"; print "OPTIONS:\n"; - print " -block - Enable basicblock-level profiling\n"; - print " -function - Enable function-level profiling\n"; + print " -block - Enable basicblock profiling\n"; + print " -edge - Enable edge profiling\n"; + print " -function - Enable function profiling\n"; print " -o - Specify an output file other than llvm-prof.out.\n"; print " -help - Print this usage information\n"; print "\nAll other options are passed into llvm-prof.\n"; @@ -65,7 +68,8 @@ my $LibProfPath = $LLIPath . "/../../lib/Debug/libprofile_rt.so"; -system "opt -q $ProfilePass < $BytecodeFile | lli -fake-argv0 '$BytecodeFile'" . - " -load $LibProfPath -$ProgramOpts " . (join ' ', @ARGV); - +system "opt -q -f $ProfilePass $BytecodeFile -o $BytecodeFile.inst"; +system "lli -fake-argv0 '$BytecodeFile' -load $LibProfPath " . + "$BytecodeFile.inst $ProgramOpts " . (join ' ', @ARGV); +system "rm $BytecodeFile.inst"; system "llvm-prof $LLVMProfOpts $BytecodeFile $ProfileFile"; From brukman at cs.uiuc.edu Wed Mar 10 19:05:05 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:05 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Target/CBackend/CTargetMachine.h Message-ID: <200403110103.TAA27890@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: CTargetMachine.h updated: 1.2.2.1 -> 1.2.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/CBackend/CTargetMachine.h diff -u llvm/lib/Target/CBackend/CTargetMachine.h:1.2.2.1 llvm/lib/Target/CBackend/CTargetMachine.h:1.2.2.2 --- llvm/lib/Target/CBackend/CTargetMachine.h:1.2.2.1 Mon Mar 1 17:58:13 2004 +++ llvm/lib/Target/CBackend/CTargetMachine.h Wed Mar 10 19:03:49 2004 @@ -21,7 +21,7 @@ struct CTargetMachine : public TargetMachine { CTargetMachine(const Module &M, IntrinsicLowering *IL) : - TargetMachine("CBackend", IL) {} + TargetMachine("CBackend", IL, M) {} virtual const TargetInstrInfo &getInstrInfo() const { abort(); } virtual const TargetFrameInfo &getFrameInfo() const { abort(); } From brukman at cs.uiuc.edu Wed Mar 10 19:05:10 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:10 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp InstSelectSimple.cpp SparcV8.h SparcV8InstrInfo.td SparcV8RegisterInfo.cpp SparcV8RegisterInfo.td SparcV8TargetMachine.cpp Message-ID: <200403110103.TAA27909@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8AsmPrinter.cpp added (r1.3.2.1) InstSelectSimple.cpp updated: 1.1.2.1 -> 1.1.2.2 SparcV8.h updated: 1.2.2.1 -> 1.2.2.2 SparcV8InstrInfo.td updated: 1.1.2.1 -> 1.1.2.2 SparcV8RegisterInfo.cpp updated: 1.3.2.1 -> 1.3.2.2 SparcV8RegisterInfo.td updated: 1.3.2.1 -> 1.3.2.2 SparcV8TargetMachine.cpp updated: 1.4.2.1 -> 1.4.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+828 -38) Index: llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp diff -c /dev/null llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp:1.3.2.1 *** /dev/null Wed Mar 10 19:03:59 2004 --- llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp Wed Mar 10 19:03:49 2004 *************** *** 0 **** --- 1,529 ---- + //===-- SparcV8AsmPrinter.cpp - SparcV8 LLVM assembly writer --------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file contains a printer that converts from our internal representation + // of machine-dependent LLVM code to GAS-format Sparc V8 assembly language. + // + //===----------------------------------------------------------------------===// + + #include "SparcV8.h" + #include "SparcV8InstrInfo.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Module.h" + #include "llvm/Assembly/Writer.h" + #include "llvm/CodeGen/MachineFunctionPass.h" + #include "llvm/CodeGen/MachineConstantPool.h" + #include "llvm/CodeGen/MachineInstr.h" + #include "llvm/Target/TargetMachine.h" + #include "llvm/Support/Mangler.h" + #include "Support/Statistic.h" + #include "Support/StringExtras.h" + #include "Support/CommandLine.h" + #include + using namespace llvm; + + namespace { + Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); + + struct V8Printer : public MachineFunctionPass { + /// Output stream on which we're printing assembly code. + /// + std::ostream &O; + + /// Target machine description which we query for reg. names, data + /// layout, etc. + /// + TargetMachine &TM; + + /// Name-mangler for global names. + /// + Mangler *Mang; + + V8Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { } + + /// We name each basic block in a Function with a unique number, so + /// that we can consistently refer to them later. This is cleared + /// at the beginning of each call to runOnMachineFunction(). + /// + typedef std::map ValueMapTy; + ValueMapTy NumberForBB; + + /// Cache of mangled name for current function. This is + /// recalculated at the beginning of each call to + /// runOnMachineFunction(). + /// + std::string CurrentFnName; + + virtual const char *getPassName() const { + return "SparcV8 Assembly Printer"; + } + + void emitConstantValueOnly(const Constant *CV); + void emitGlobalConstant(const Constant *CV); + void printConstantPool(MachineConstantPool *MCP); + void printOperand(const MachineOperand &MI); + void printMachineInstruction(const MachineInstr *MI); + bool runOnMachineFunction(MachineFunction &F); + bool doInitialization(Module &M); + bool doFinalization(Module &M); + }; + } // end of anonymous namespace + + /// createSparcV8CodePrinterPass - Returns a pass that prints the SparcV8 + /// assembly code for a MachineFunction to the given output stream, + /// using the given target machine description. This should work + /// regardless of whether the function is in SSA form. + /// + FunctionPass *llvm::createSparcV8CodePrinterPass (std::ostream &o, + TargetMachine &tm) { + return new V8Printer(o, tm); + } + + /// toOctal - Convert the low order bits of X into an octal digit. + /// + static inline char toOctal(int X) { + return (X&7)+'0'; + } + + /// getAsCString - Return the specified array as a C compatible + /// string, only if the predicate isStringCompatible is true. + /// + static void printAsCString(std::ostream &O, const ConstantArray *CVA) { + assert(CVA->isString() && "Array is not string compatible!"); + + O << "\""; + for (unsigned i = 0; i != CVA->getNumOperands(); ++i) { + unsigned char C = cast(CVA->getOperand(i))->getRawValue(); + + if (C == '"') { + O << "\\\""; + } else if (C == '\\') { + O << "\\\\"; + } else if (isprint(C)) { + O << C; + } else { + switch(C) { + case '\b': O << "\\b"; break; + case '\f': O << "\\f"; break; + case '\n': O << "\\n"; break; + case '\r': O << "\\r"; break; + case '\t': O << "\\t"; break; + default: + O << '\\'; + O << toOctal(C >> 6); + O << toOctal(C >> 3); + O << toOctal(C >> 0); + break; + } + } + } + O << "\""; + } + + // Print out the specified constant, without a storage class. Only the + // constants valid in constant expressions can occur here. + void V8Printer::emitConstantValueOnly(const Constant *CV) { + if (CV->isNullValue()) + O << "0"; + else if (const ConstantBool *CB = dyn_cast(CV)) { + assert(CB == ConstantBool::True); + O << "1"; + } else if (const ConstantSInt *CI = dyn_cast(CV)) + if (((CI->getValue() << 32) >> 32) == CI->getValue()) + O << CI->getValue(); + else + O << (unsigned long long)CI->getValue(); + else if (const ConstantUInt *CI = dyn_cast(CV)) + O << CI->getValue(); + else if (const ConstantPointerRef *CPR = dyn_cast(CV)) + // This is a constant address for a global variable or function. Use the + // name of the variable or function as the address value. + O << Mang->getValueName(CPR->getValue()); + else if (const ConstantExpr *CE = dyn_cast(CV)) { + const TargetData &TD = TM.getTargetData(); + switch(CE->getOpcode()) { + case Instruction::GetElementPtr: { + // generate a symbolic expression for the byte address + const Constant *ptrVal = CE->getOperand(0); + std::vector idxVec(CE->op_begin()+1, CE->op_end()); + if (unsigned Offset = TD.getIndexedOffset(ptrVal->getType(), idxVec)) { + O << "("; + emitConstantValueOnly(ptrVal); + O << ") + " << Offset; + } else { + emitConstantValueOnly(ptrVal); + } + break; + } + case Instruction::Cast: { + // Support only non-converting or widening casts for now, that is, ones + // that do not involve a change in value. This assertion is really gross, + // and may not even be a complete check. + Constant *Op = CE->getOperand(0); + const Type *OpTy = Op->getType(), *Ty = CE->getType(); + + // Pointers on ILP32 machines can be losslessly converted back and + // forth into 32-bit or wider integers, regardless of signedness. + assert(((isa(OpTy) + && (Ty == Type::LongTy || Ty == Type::ULongTy + || Ty == Type::IntTy || Ty == Type::UIntTy)) + || (isa(Ty) + && (OpTy == Type::LongTy || OpTy == Type::ULongTy + || OpTy == Type::IntTy || OpTy == Type::UIntTy)) + || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy)) + && OpTy->isLosslesslyConvertibleTo(Ty)))) + && "FIXME: Don't yet support this kind of constant cast expr"); + O << "("; + emitConstantValueOnly(Op); + O << ")"; + break; + } + case Instruction::Add: + O << "("; + emitConstantValueOnly(CE->getOperand(0)); + O << ") + ("; + emitConstantValueOnly(CE->getOperand(1)); + O << ")"; + break; + default: + assert(0 && "Unsupported operator!"); + } + } else { + assert(0 && "Unknown constant value!"); + } + } + + // Print a constant value or values, with the appropriate storage class as a + // prefix. + void V8Printer::emitGlobalConstant(const Constant *CV) { + const TargetData &TD = TM.getTargetData(); + + if (CV->isNullValue()) { + O << "\t.zero\t " << TD.getTypeSize(CV->getType()) << "\n"; + return; + } else if (const ConstantArray *CVA = dyn_cast(CV)) { + if (CVA->isString()) { + O << "\t.ascii\t"; + printAsCString(O, CVA); + O << "\n"; + } else { // Not a string. Print the values in successive locations + const std::vector &constValues = CVA->getValues(); + for (unsigned i=0; i < constValues.size(); i++) + emitGlobalConstant(cast(constValues[i].get())); + } + return; + } else if (const ConstantStruct *CVS = dyn_cast(CV)) { + // Print the fields in successive locations. Pad to align if needed! + const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType()); + const std::vector& constValues = CVS->getValues(); + unsigned sizeSoFar = 0; + for (unsigned i=0, N = constValues.size(); i < N; i++) { + const Constant* field = cast(constValues[i].get()); + + // Check if padding is needed and insert one or more 0s. + unsigned fieldSize = TD.getTypeSize(field->getType()); + unsigned padSize = ((i == N-1? cvsLayout->StructSize + : cvsLayout->MemberOffsets[i+1]) + - cvsLayout->MemberOffsets[i]) - fieldSize; + sizeSoFar += fieldSize + padSize; + + // Now print the actual field value + emitGlobalConstant(field); + + // Insert the field padding unless it's zero bytes... + if (padSize) + O << "\t.zero\t " << padSize << "\n"; + } + assert(sizeSoFar == cvsLayout->StructSize && + "Layout of constant struct may be incorrect!"); + return; + } else if (const ConstantFP *CFP = dyn_cast(CV)) { + // FP Constants are printed as integer constants to avoid losing + // precision... + double Val = CFP->getValue(); + switch (CFP->getType()->getPrimitiveID()) { + default: assert(0 && "Unknown floating point type!"); + case Type::FloatTyID: { + union FU { // Abide by C TBAA rules + float FVal; + unsigned UVal; + } U; + U.FVal = Val; + O << ".long\t" << U.UVal << "\t# float " << Val << "\n"; + return; + } + case Type::DoubleTyID: { + union DU { // Abide by C TBAA rules + double FVal; + uint64_t UVal; + } U; + U.FVal = Val; + O << ".quad\t" << U.UVal << "\t# double " << Val << "\n"; + return; + } + } + } + + const Type *type = CV->getType(); + O << "\t"; + switch (type->getPrimitiveID()) { + case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID: + O << ".byte"; + break; + case Type::UShortTyID: case Type::ShortTyID: + O << ".word"; + break; + case Type::FloatTyID: case Type::PointerTyID: + case Type::UIntTyID: case Type::IntTyID: + O << ".long"; + break; + case Type::DoubleTyID: + case Type::ULongTyID: case Type::LongTyID: + O << ".quad"; + break; + default: + assert (0 && "Can't handle printing this type of thing"); + break; + } + O << "\t"; + emitConstantValueOnly(CV); + O << "\n"; + } + + /// printConstantPool - Print to the current output stream assembly + /// representations of the constants in the constant pool MCP. This is + /// used to print out constants which have been "spilled to memory" by + /// the code generator. + /// + void V8Printer::printConstantPool(MachineConstantPool *MCP) { + const std::vector &CP = MCP->getConstants(); + const TargetData &TD = TM.getTargetData(); + + if (CP.empty()) return; + + for (unsigned i = 0, e = CP.size(); i != e; ++i) { + O << "\t.section .rodata\n"; + O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) + << "\n"; + O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t#" + << *CP[i] << "\n"; + emitGlobalConstant(CP[i]); + } + } + + /// runOnMachineFunction - This uses the printMachineInstruction() + /// method to print assembly for each instruction. + /// + bool V8Printer::runOnMachineFunction(MachineFunction &MF) { + // BBNumber is used here so that a given Printer will never give two + // BBs the same name. (If you have a better way, please let me know!) + static unsigned BBNumber = 0; + + O << "\n\n"; + // What's my mangled name? + CurrentFnName = Mang->getValueName(MF.getFunction()); + + // Print out constants referenced by the function + printConstantPool(MF.getConstantPool()); + + // Print out labels for the function. + O << "\t.text\n"; + O << "\t.align 16\n"; + O << "\t.globl\t" << CurrentFnName << "\n"; + O << "\t.type\t" << CurrentFnName << ", @function\n"; + O << CurrentFnName << ":\n"; + + // Number each basic block so that we can consistently refer to them + // in PC-relative references. + NumberForBB.clear(); + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + NumberForBB[I->getBasicBlock()] = BBNumber++; + } + + // Print out code for the function. + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + // Print a label for the basic block. + O << ".LBB" << NumberForBB[I->getBasicBlock()] << ":\t# " + << I->getBasicBlock()->getName() << "\n"; + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) { + // Print the assembly for the instruction. + O << "\t"; + printMachineInstruction(II); + } + } + + // We didn't modify anything. + return false; + } + + + std::string LowercaseString (const std::string &S) { + std::string result (S); + for (unsigned i = 0; i < S.length(); ++i) + if (isupper (result[i])) + result[i] = tolower(result[i]); + return result; + } + + void V8Printer::printOperand(const MachineOperand &MO) { + const MRegisterInfo &RI = *TM.getRegisterInfo(); + switch (MO.getType()) { + case MachineOperand::MO_VirtualRegister: + if (Value *V = MO.getVRegValueOrNull()) { + O << "<" << V->getName() << ">"; + return; + } + // FALLTHROUGH + case MachineOperand::MO_MachineRegister: + if (MRegisterInfo::isPhysicalRegister(MO.getReg())) + O << "%" << LowercaseString (RI.get(MO.getReg()).Name); + else + O << "%reg" << MO.getReg(); + return; + + case MachineOperand::MO_SignExtendedImmed: + case MachineOperand::MO_UnextendedImmed: + O << (int)MO.getImmedValue(); + return; + case MachineOperand::MO_PCRelativeDisp: { + ValueMapTy::const_iterator i = NumberForBB.find(MO.getVRegValue()); + assert (i != NumberForBB.end() + && "Could not find a BB in the NumberForBB map!"); + O << ".LBB" << i->second << " # PC rel: " << MO.getVRegValue()->getName(); + return; + } + case MachineOperand::MO_GlobalAddress: + O << Mang->getValueName(MO.getGlobal()); + return; + case MachineOperand::MO_ExternalSymbol: + O << MO.getSymbolName(); + return; + default: + O << ""; return; + } + } + + /// printMachineInstruction -- Print out a single SparcV8 LLVM instruction + /// MI in GAS syntax to the current output stream. + /// + void V8Printer::printMachineInstruction(const MachineInstr *MI) { + unsigned Opcode = MI->getOpcode(); + const TargetInstrInfo &TII = TM.getInstrInfo(); + const TargetInstrDescriptor &Desc = TII.get(Opcode); + O << Desc.Name << " "; + + // print non-immediate, non-register-def operands + // then print immediate operands + // then print register-def operands. + std::vector print_order; + for (unsigned i = 0; i < MI->getNumOperands (); ++i) + if (!(MI->getOperand (i).isImmediate () + || (MI->getOperand (i).isRegister () + && MI->getOperand (i).isDef ()))) + print_order.push_back (MI->getOperand (i)); + for (unsigned i = 0; i < MI->getNumOperands (); ++i) + if (MI->getOperand (i).isImmediate ()) + print_order.push_back (MI->getOperand (i)); + for (unsigned i = 0; i < MI->getNumOperands (); ++i) + if (MI->getOperand (i).isRegister () && MI->getOperand (i).isDef ()) + print_order.push_back (MI->getOperand (i)); + for (unsigned i = 0, e = print_order.size (); i != e; ++i) { + printOperand (print_order[i]); + if (i != (print_order.size () - 1)) + O << ", "; + } + O << "\n"; + } + + bool V8Printer::doInitialization(Module &M) { + Mang = new Mangler(M); + return false; // success + } + + // SwitchSection - Switch to the specified section of the executable if we are + // not already in it! + // + static void SwitchSection(std::ostream &OS, std::string &CurSection, + const char *NewSection) { + if (CurSection != NewSection) { + CurSection = NewSection; + if (!CurSection.empty()) + OS << "\t" << NewSection << "\n"; + } + } + + bool V8Printer::doFinalization(Module &M) { + const TargetData &TD = TM.getTargetData(); + std::string CurSection; + + // Print out module-level global variables here. + for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) + if (I->hasInitializer()) { // External global require no code + O << "\n\n"; + std::string name = Mang->getValueName(I); + Constant *C = I->getInitializer(); + unsigned Size = TD.getTypeSize(C->getType()); + unsigned Align = TD.getTypeAlignment(C->getType()); + + if (C->isNullValue() && + (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || + I->hasWeakLinkage() /* FIXME: Verify correct */)) { + SwitchSection(O, CurSection, ".data"); + if (I->hasInternalLinkage()) + O << "\t.local " << name << "\n"; + + O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) + << "," << (unsigned)TD.getTypeAlignment(C->getType()); + O << "\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << "\n"; + } else { + switch (I->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. + // Nonnull linkonce -> weak + O << "\t.weak " << name << "\n"; + SwitchSection(O, CurSection, ""); + O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\", at progbits\n"; + break; + + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << "\t.globl " << name << "\n"; + // FALL THROUGH + case GlobalValue::InternalLinkage: + if (C->isNullValue()) + SwitchSection(O, CurSection, ".bss"); + else + SwitchSection(O, CurSection, ".data"); + break; + } + + O << "\t.align " << Align << "\n"; + O << "\t.type " << name << ", at object\n"; + O << "\t.size " << name << "," << Size << "\n"; + O << name << ":\t\t\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << " = "; + WriteAsOperand(O, C, false, false, &M); + O << "\n"; + emitGlobalConstant(C); + } + } + + delete Mang; + return false; // success + } Index: llvm/lib/Target/SparcV8/InstSelectSimple.cpp diff -u llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.1.2.1 llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.1.2.2 --- llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.1.2.1 Mon Mar 1 17:58:14 2004 +++ llvm/lib/Target/SparcV8/InstSelectSimple.cpp Wed Mar 10 19:03:49 2004 @@ -12,11 +12,14 @@ //===----------------------------------------------------------------------===// #include "SparcV8.h" +#include "SparcV8InstrInfo.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicLowering.h" #include "llvm/Pass.h" +#include "llvm/Constants.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/InstVisitor.h" @@ -54,6 +57,7 @@ BB = MBBMap[&LLVM_BB]; } + void visitBinaryOperator(BinaryOperator &I); void visitReturnInst(ReturnInst &RI); void visitInstruction(Instruction &I) { @@ -65,9 +69,71 @@ /// function, lowering any calls to unknown intrinsic functions into the /// equivalent LLVM code. void LowerUnknownIntrinsicFunctionCalls(Function &F); + void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI); + /// copyConstantToRegister - Output the instructions required to put the + /// specified constant into the specified register. + /// + void copyConstantToRegister(MachineBasicBlock *MBB, + MachineBasicBlock::iterator IP, + Constant *C, unsigned R); - void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI); + /// makeAnotherReg - This method returns the next register number we haven't + /// yet used. + /// + /// Long values are handled somewhat specially. They are always allocated + /// as pairs of 32 bit integer values. The register number returned is the + /// lower 32 bits of the long value, and the regNum+1 is the upper 32 bits + /// of the long value. + /// + unsigned makeAnotherReg(const Type *Ty) { + assert(dynamic_cast(TM.getRegisterInfo()) && + "Current target doesn't have SparcV8 reg info??"); + const SparcV8RegisterInfo *MRI = + static_cast(TM.getRegisterInfo()); + if (Ty == Type::LongTy || Ty == Type::ULongTy) { + const TargetRegisterClass *RC = MRI->getRegClassForType(Type::IntTy); + // Create the lower part + F->getSSARegMap()->createVirtualRegister(RC); + // Create the upper part. + return F->getSSARegMap()->createVirtualRegister(RC)-1; + } + + // Add the mapping of regnumber => reg class to MachineFunction + const TargetRegisterClass *RC = MRI->getRegClassForType(Ty); + return F->getSSARegMap()->createVirtualRegister(RC); + } + + unsigned getReg(Value &V) { return getReg (&V); } // allow refs. + unsigned getReg(Value *V) { + // Just append to the end of the current bb. + MachineBasicBlock::iterator It = BB->end(); + return getReg(V, BB, It); + } + unsigned getReg(Value *V, MachineBasicBlock *MBB, + MachineBasicBlock::iterator IPt) { + unsigned &Reg = RegMap[V]; + if (Reg == 0) { + Reg = makeAnotherReg(V->getType()); + RegMap[V] = Reg; + } + // If this operand is a constant, emit the code to copy the constant into + // the register here... + // + if (Constant *C = dyn_cast(V)) { + copyConstantToRegister(MBB, IPt, C, Reg); + RegMap.erase(V); // Assign a new name to this constant if ref'd again + } else if (GlobalValue *GV = dyn_cast(V)) { + // Move the address of the global into the register + unsigned TmpReg = makeAnotherReg(V->getType()); + BuildMI (*MBB, IPt, V8::SETHIi, 1, TmpReg).addGlobalAddress (GV); + BuildMI (*MBB, IPt, V8::ORri, 2, Reg).addReg (TmpReg) + .addGlobalAddress (GV); + RegMap.erase(V); // Assign a new name to this address if ref'd again + } + + return Reg; + } }; } @@ -76,6 +142,55 @@ return new V8ISel(TM); } +enum TypeClass { + cByte, cShort, cInt, cFloat, cDouble +}; + +static TypeClass getClass (const Type *T) { + switch (T->getPrimitiveID ()) { + case Type::UByteTyID: case Type::SByteTyID: return cByte; + case Type::UShortTyID: case Type::ShortTyID: return cShort; + case Type::UIntTyID: case Type::IntTyID: return cInt; + case Type::FloatTyID: return cFloat; + case Type::DoubleTyID: return cDouble; + default: + assert (0 && "Type of unknown class passed to getClass?"); + return cByte; + } +} + +/// copyConstantToRegister - Output the instructions required to put the +/// specified constant into the specified register. +/// +void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB, + MachineBasicBlock::iterator IP, + Constant *C, unsigned R) { + if (ConstantInt *CI = dyn_cast (C)) { + unsigned Class = getClass(C->getType()); + switch (Class) { + case cByte: + BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addImm ((uint8_t) CI->getRawValue ()); + return; + case cShort: { + unsigned TmpReg = makeAnotherReg (C->getType ()); + BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addImm (((uint16_t) CI->getRawValue ()) >> 10); + BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg).addImm (((uint16_t) CI->getRawValue ()) & 0x03ff); + return; + } + case cInt: { + unsigned TmpReg = makeAnotherReg (C->getType ()); + BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addImm (((uint32_t) CI->getRawValue ()) >> 10); + BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg).addImm (((uint32_t) CI->getRawValue ()) & 0x03ff); + return; + } + default: + assert (0 && "Can't copy this kind of constant into register yet"); + return; + } + } + + assert (0 && "Can't copy this kind of constant into register yet"); +} bool V8ISel::runOnFunction(Function &Fn) { // First pass over the function, lower any unknown intrinsic functions @@ -112,12 +227,73 @@ void V8ISel::visitReturnInst(ReturnInst &I) { - if (I.getNumOperands() == 0) { - // Just emit a 'ret' instruction - BuildMI(BB, V8::JMPLi, 2, V8::G0).addZImm(8).addReg(V8::I7); - return; + if (I.getNumOperands () == 1) { + unsigned RetValReg = getReg (I.getOperand (0)); + switch (getClass (I.getOperand (0)->getType ())) { + case cByte: + case cShort: + case cInt: + // Schlep it over into i0 (where it will become o0 after restore). + BuildMI (BB, V8::ORrr, 2, V8::I0).addReg(V8::G0).addReg(RetValReg); + break; + default: + visitInstruction (I); + return; + } + } else if (I.getNumOperands () != 1) { + visitInstruction (I); + } + // Just emit a 'retl' instruction to return. + BuildMI(BB, V8::RETL, 0); + return; +} + +void V8ISel::visitBinaryOperator (BinaryOperator &I) { + unsigned DestReg = getReg (I); + unsigned Op0Reg = getReg (I.getOperand (0)); + unsigned Op1Reg = getReg (I.getOperand (1)); + + unsigned ResultReg = makeAnotherReg (I.getType ()); + switch (I.getOpcode ()) { + case Instruction::Add: + BuildMI (BB, V8::ADDrr, 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg); + break; + case Instruction::Sub: + BuildMI (BB, V8::SUBrr, 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg); + break; + default: + visitInstruction (I); + return; + } + + switch (getClass (I.getType ())) { + case cByte: + if (I.getType ()->isSigned ()) { // add byte + BuildMI (BB, V8::ANDri, 2, DestReg).addReg (ResultReg).addZImm (0xff); + } else { // add ubyte + unsigned TmpReg = makeAnotherReg (I.getType ()); + BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (24); + BuildMI (BB, V8::SRAri, 2, DestReg).addReg (TmpReg).addZImm (24); + } + break; + case cShort: + if (I.getType ()->isSigned ()) { // add short + unsigned TmpReg = makeAnotherReg (I.getType ()); + BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (16); + BuildMI (BB, V8::SRAri, 2, DestReg).addReg (TmpReg).addZImm (16); + } else { // add ushort + unsigned TmpReg = makeAnotherReg (I.getType ()); + BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (24); + BuildMI (BB, V8::SRLri, 2, DestReg).addReg (TmpReg).addZImm (24); + } + break; + case cInt: + BuildMI (BB, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (ResultReg); + break; + default: + visitInstruction (I); + return; } - visitInstruction(I); } Index: llvm/lib/Target/SparcV8/SparcV8.h diff -u llvm/lib/Target/SparcV8/SparcV8.h:1.2.2.1 llvm/lib/Target/SparcV8/SparcV8.h:1.2.2.2 --- llvm/lib/Target/SparcV8/SparcV8.h:1.2.2.1 Mon Mar 1 17:58:14 2004 +++ llvm/lib/Target/SparcV8/SparcV8.h Wed Mar 10 19:03:49 2004 @@ -23,8 +23,8 @@ class TargetMachine; FunctionPass *createSparcV8SimpleInstructionSelector(TargetMachine &TM); -// FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS, -// TargetMachine &TM); + FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS, + TargetMachine &TM); } // end namespace llvm; Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.1.2.1 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.1.2.2 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.1.2.1 Mon Mar 1 17:58:14 2004 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Wed Mar 10 19:03:49 2004 @@ -46,23 +46,48 @@ let Name = "ADJCALLSTACKUP"; } -// Section B.20: SAVE and RESTORE - p117 -def SAVEr : F3_1<2, 0b111100, "save">; // save r, r, r -def SAVEi : F3_2<2, 0b111100, "save">; // save r, i, r -def RESTOREr : F3_1<2, 0b111101, "restore">; // restore r, r, r -def RESTOREi : F3_2<2, 0b111101, "restore">; // restore r, i, r +// Section A.3 - Synthetic Instructions, p. 85 +let isReturn = 1, isTerminator = 1, simm13 = 8 in + def RET : F3_2<2, 0b111000, "ret">; +let isReturn = 1, isTerminator = 1, simm13 = 8 in + def RETL : F3_2<2, 0b111000, "retl">; -// Section B.24: Call and Link - p125 +// Section B.9 - SETHI Instruction, p. 104 +def SETHIi: F2_1<0b100, "sethi">; + +// Section B.11 - Logical Instructions, p. 106 +def ANDri : F3_2<2, 0b000001, "and">; +def ORrr : F3_1<2, 0b000010, "or">; +def ORri : F3_2<2, 0b000010, "or">; + +// Section B.12 - Shift Instructions, p. 107 +def SLLri : F3_1<2, 0b100101, "sll">; +def SRLri : F3_1<2, 0b100110, "srl">; +def SRAri : F3_1<2, 0b100111, "sra">; + +// Section B.13 - Add Instructions, p. 108 +def ADDrr : F3_1<2, 0b000000, "add">; + +// Section B.15 - Subtract Instructions, p. 110 +def SUBrr : F3_1<2, 0b000100, "sub">; + +// Section B.20 - SAVE and RESTORE, p. 117 +def SAVErr : F3_1<2, 0b111100, "save">; // save r, r, r +def SAVEri : F3_2<2, 0b111100, "save">; // save r, i, r +def RESTORErr : F3_1<2, 0b111101, "restore">; // restore r, r, r +def RESTOREri : F3_2<2, 0b111101, "restore">; // restore r, i, r + +// Section B.24 - Call and Link, p. 125 // This is the only Format 1 instruction def CALL : InstV8 { bits<30> disp; - let op = 1; let Inst{29-0} = disp; let Name = "call"; + let isCall = 1; } -// Section B.25: Jump and Link - p126 -def JMPLr : F3_1<2, 0b111000, "jmpl">; // jmpl [rs1+rs2], rd -def JMPLi : F3_2<2, 0b111000, "jmpl">; // jmpl [rs1+imm], rd +// Section B.25 - Jump and Link, p. 126 +def JMPLrr : F3_1<2, 0b111000, "jmpl">; // jmpl [rs1+rs2], rd +def JMPLri : F3_2<2, 0b111000, "jmpl">; // jmpl [rs1+imm], rd Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.3.2.1 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.3.2.2 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.3.2.1 Mon Mar 1 17:58:14 2004 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp Wed Mar 10 19:03:49 2004 @@ -71,15 +71,15 @@ // Eventually this should emit the correct save instruction based on the // number of bytes in the frame. For now we just hardcode it. - BuildMI(MBB, MBB.begin(), V8::SAVEi, 2, V8::SP).addImm(-122).addReg(V8::SP); + BuildMI(MBB, MBB.begin(), V8::SAVEri, 2, V8::SP).addImm(-112).addReg(V8::SP); } void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = prior(MBB.end()); - assert(MBBI->getOpcode() == V8::JMPLi && - "Can only put epilog before return instruction!"); - BuildMI(MBB, MBBI, V8::RESTOREi, 2, V8::O0).addImm(0).addReg(V8::L7); + assert(MBBI->getOpcode() == V8::RETL && + "Can only put epilog before 'retl' instruction!"); + BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0); } @@ -88,9 +88,8 @@ const TargetRegisterClass* SparcV8RegisterInfo::getRegClassForType(const Type* Ty) const { switch (Ty->getPrimitiveID()) { - case Type::FloatTyID: - case Type::DoubleTyID: - assert(0 && "Floating point registers not supported yet!"); + case Type::FloatTyID: return &FPRegsInstance; + case Type::DoubleTyID: return &DFPRegsInstance; case Type::LongTyID: case Type::ULongTyID: assert(0 && "Long values can't fit in registers!"); default: assert(0 && "Invalid type to getClass!"); Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.3.2.1 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.3.2.2 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.3.2.1 Mon Mar 1 17:58:14 2004 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td Wed Mar 10 19:03:49 2004 @@ -11,9 +11,18 @@ // //===----------------------------------------------------------------------===// +// Registers are identified with 5-bit ID numbers. // Ri - 32-bit integer registers class Ri num> : Register { - field bits<5> Num = num; // Numbers are identified with a 5 bit ID + field bits<5> Num = num; +} +// Rf - 32-bit floating-point registers +class Rf num> : Register { + field bits<5> Num = num; +} +// Rd - Slots in the FP register file for 64-bit floating-point values. +class Rd num> : Register { + field bits<5> Num = num; } let Namespace = "V8" in { @@ -29,17 +38,64 @@ // Standard register aliases. def SP : Ri<14>; def FP : Ri<30>; - // Floating-point registers? - // ... + // Floating-point registers: + def F0 : Rf< 0>; def F1 : Rf< 1>; def F2 : Rf< 2>; def F3 : Rf< 3>; + def F4 : Rf< 4>; def F5 : Rf< 5>; def F6 : Rf< 6>; def F7 : Rf< 7>; + def F8 : Rf< 8>; def F9 : Rf< 9>; def F10 : Rf<10>; def F11 : Rf<11>; + def F12 : Rf<12>; def F13 : Rf<13>; def F14 : Rf<14>; def F15 : Rf<15>; + def F16 : Rf<16>; def F17 : Rf<17>; def F18 : Rf<18>; def F19 : Rf<19>; + def F20 : Rf<20>; def F21 : Rf<21>; def F22 : Rf<22>; def F23 : Rf<23>; + def F24 : Rf<24>; def F25 : Rf<25>; def F26 : Rf<26>; def F27 : Rf<27>; + def F28 : Rf<28>; def F29 : Rf<29>; def F30 : Rf<30>; def F31 : Rf<31>; + + // Aliases of the F* registers used to hold 64-bit fp values (doubles). + def D0 : Rd< 0>; def D1 : Rd< 2>; def D2 : Rd< 4>; def D3 : Rd< 6>; + def D4 : Rd< 8>; def D5 : Rd<10>; def D6 : Rd<12>; def D7 : Rd<14>; + def D8 : Rd<16>; def D9 : Rd<18>; def D10 : Rd<20>; def D11 : Rd<22>; + def D12 : Rd<24>; def D13 : Rd<26>; def D14 : Rd<28>; def D15 : Rd<30>; } -// For fun, specify a register class. +// Register classes. // // FIXME: the register order should be defined in terms of the preferred // allocation order... // -def IntRegs : RegisterClass; + I0, I1, I2, I3, I4, I5, + // Non-allocatable regs + O6, I6, I7, G0]> { + let Methods = [{ + iterator allocation_order_end(MachineFunction &MF) const { + return end()-4; // Don't allocate special registers + } + }]; +} + +def FPRegs : RegisterClass; + +def DFPRegs : RegisterClass; + +// Tell the register file generator that the double-fp pseudo-registers +// alias the registers used for single-fp values. +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; +def : RegisterAliases; Index: llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp diff -u llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.4.2.1 llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.4.2.2 --- llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.4.2.1 Mon Mar 1 17:58:14 2004 +++ llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp Wed Mar 10 19:03:49 2004 @@ -42,17 +42,22 @@ std::ostream &Out) { PM.add(createSparcV8SimpleInstructionSelector(*this)); - // Print machine instructions as they are created. - PM.add(createMachineFunctionPrinterPass(&std::cerr)); + // Print machine instructions as they were initially generated. + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(&std::cerr)); PM.add(createRegisterAllocator()); PM.add(createPrologEpilogCodeInserter()); - // - // This is not a correct asm writer by any means, but at least we see what we - // are producing. - PM.add(createMachineFunctionPrinterPass(&Out)); + // Print machine instructions after register allocation and prolog/epilog + // insertion. + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(&std::cerr)); + // Output assembly language. + PM.add(createSparcV8CodePrinterPass(Out, *this)); + + // Delete the MachineInstrs we generated, since they're no longer needed. PM.add(createMachineCodeDeleter()); return false; } From brukman at cs.uiuc.edu Wed Mar 10 19:05:16 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:16 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Message-ID: <200403110104.TAA27917@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9TargetMachine.cpp updated: 1.98.2.1 -> 1.98.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+4 -0) Index: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp diff -u llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.98.2.1 llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.98.2.2 --- llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.98.2.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Wed Mar 10 19:03:49 2004 @@ -162,6 +162,10 @@ PM.add(createInstructionSchedulingWithSSAPass(*this)); PM.add(getRegisterAllocator(*this)); + + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(&std::cerr)); + PM.add(createPrologEpilogInsertionPass()); if (!DisablePeephole) From brukman at cs.uiuc.edu Wed Mar 10 19:05:21 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:21 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h PhyRegAlloc.cpp PhyRegAlloc.h Message-ID: <200403110104.TAA27928@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: AllocInfo.h updated: 1.5.4.1 -> 1.5.4.2 PhyRegAlloc.cpp updated: 1.131.2.1 -> 1.131.2.2 PhyRegAlloc.h updated: 1.62 -> 1.62.4.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+29 -18) Index: llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h diff -u llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h:1.5.4.1 llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h:1.5.4.2 --- llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h:1.5.4.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/AllocInfo.h Wed Mar 10 19:03:50 2004 @@ -26,8 +26,8 @@ /// structures to generate mapping information for this register allocator. /// struct AllocInfo { - unsigned Instruction; - int Operand; // (-1 if Instruction, or 0...n-1 for an operand.) + int Instruction; // (-1 if Argument, or 0 .. n - 1 for an instruction). + int Operand; // (-1 if Instruction, or 0 .. n-1 for an operand). enum AllocStateTy { NotAllocated = 0, Allocated, Spilled }; AllocStateTy AllocState; int Placement; @@ -41,7 +41,7 @@ /// static StructType *getConstantType () { std::vector TV; - TV.push_back (Type::UIntTy); + TV.push_back (Type::IntTy); TV.push_back (Type::IntTy); TV.push_back (Type::UIntTy); TV.push_back (Type::IntTy); @@ -54,7 +54,7 @@ Constant *toConstant () const { StructType *ST = getConstantType (); std::vector CV; - CV.push_back (ConstantUInt::get (Type::UIntTy, Instruction)); + CV.push_back (ConstantSInt::get (Type::IntTy, Instruction)); CV.push_back (ConstantSInt::get (Type::IntTy, Operand)); CV.push_back (ConstantUInt::get (Type::UIntTy, AllocState)); CV.push_back (ConstantSInt::get (Type::IntTy, Placement)); Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.131.2.1 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.131.2.2 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.131.2.1 Mon Mar 1 17:58:15 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Wed Mar 10 19:03:50 2004 @@ -51,12 +51,6 @@ RegAllocDebugLevel_t DEBUG_RA; -/// The reoptimizer wants to be able to grovel through the register -/// allocator's state after it has done its job. This is a hack. -/// -PhyRegAlloc::SavedStateMapTy ExportedFnAllocState; -const bool SaveStateToModule = true; - static cl::opt DRA_opt("dregalloc", cl::Hidden, cl::location(DEBUG_RA), cl::desc("enable register allocation debugging information"), @@ -69,8 +63,16 @@ clEnumValN(RA_DEBUG_Verbose, "v", "extra debug output"), 0)); -static cl::opt -SaveRegAllocState("save-ra-state", cl::Hidden, +/// The reoptimizer wants to be able to grovel through the register +/// allocator's state after it has done its job. This is a hack. +/// +PhyRegAlloc::SavedStateMapTy ExportedFnAllocState; +bool SaveRegAllocState = false; +bool SaveStateToModule = true; +static cl::opt +SaveRegAllocStateOpt("save-ra-state", cl::Hidden, + cl::location (SaveRegAllocState), + cl::init(false), cl::desc("write reg. allocator state into module")); FunctionPass *getRegisterAllocator(TargetMachine &T) { @@ -1125,7 +1127,7 @@ void PhyRegAlloc::saveStateForValue (std::vector &state, - const Value *V, unsigned Insn, int Opnd) { + const Value *V, int Insn, int Opnd) { LiveRangeMapType::const_iterator HMI = LRI->getLiveRangeMap ()->find (V); LiveRangeMapType::const_iterator HMIEnd = LRI->getLiveRangeMap ()->end (); AllocInfo::AllocStateTy AllocState = AllocInfo::NotAllocated; @@ -1155,7 +1157,15 @@ /// void PhyRegAlloc::saveState () { std::vector &state = FnAllocState[Fn]; + unsigned ArgNum = 0; + // Arguments encoded as instruction # -1 + for (Function::const_aiterator i=Fn->abegin (), e=Fn->aend (); i != e; ++i) { + const Argument *Arg = &*i; + saveStateForValue (state, Arg, -1, ArgNum); + ++ArgNum; + } unsigned Insn = 0; + // Instructions themselves encoded as operand # -1 for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II!=IE; ++II){ saveStateForValue (state, (*II), Insn, -1); for (unsigned i = 0; i < (*II)->getNumOperands (); ++i) { @@ -1176,7 +1186,7 @@ /// void PhyRegAlloc::verifySavedState () { std::vector &state = FnAllocState[Fn]; - unsigned Insn = 0; + int Insn = 0; for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II!=IE; ++II) { const Instruction *I = *II; MachineCodeForInstruction &Instrs = MachineCodeForInstruction::get (I); @@ -1347,10 +1357,11 @@ colorIncomingArgs(); // Save register allocation state for this function in a Constant. - if (SaveRegAllocState) + if (SaveRegAllocState) { saveState(); - if (DEBUG_RA) { // Check our work. - verifySavedState (); + if (DEBUG_RA) { // Check our work. + verifySavedState (); + } } // Now update the machine code with register names and add any additional Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.62 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.62.4.1 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.62 Tue Nov 11 16:41:33 2003 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h Wed Mar 10 19:03:50 2004 @@ -126,7 +126,7 @@ void buildInterferenceGraphs(); void saveStateForValue (std::vector &state, - const Value *V, unsigned Insn, int Opnd); + const Value *V, int Insn, int Opnd); void saveState(); void verifySavedState(); From brukman at cs.uiuc.edu Wed Mar 10 19:05:25 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:25 2004 Subject: [llvm-commits] [parallel] CVS: llvm/tools/llvm-prof/llvm-prof.cpp Message-ID: <200403110104.TAA27958@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-prof: llvm-prof.cpp updated: 1.16.4.1 -> 1.16.4.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+39 -6) Index: llvm/tools/llvm-prof/llvm-prof.cpp diff -u llvm/tools/llvm-prof/llvm-prof.cpp:1.16.4.1 llvm/tools/llvm-prof/llvm-prof.cpp:1.16.4.2 --- llvm/tools/llvm-prof/llvm-prof.cpp:1.16.4.1 Mon Mar 1 17:59:18 2004 +++ llvm/tools/llvm-prof/llvm-prof.cpp Wed Mar 10 19:04:03 2004 @@ -13,6 +13,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/InstrTypes.h" #include "llvm/Module.h" #include "llvm/Assembly/AsmAnnotationWriter.h" #include "llvm/Analysis/ProfileInfoLoader.h" @@ -59,21 +60,46 @@ class ProfileAnnotator : public AssemblyAnnotationWriter { std::map &FuncFreqs; std::map &BlockFreqs; + std::map &EdgeFreqs; public: ProfileAnnotator(std::map &FF, - std::map &BF) - : FuncFreqs(FF), BlockFreqs(BF) {} + std::map &BF, + std::map &EF) + : FuncFreqs(FF), BlockFreqs(BF), EdgeFreqs(EF) {} virtual void emitFunctionAnnot(const Function *F, std::ostream &OS) { OS << ";;; %" << F->getName() << " called " << FuncFreqs[F] << " times.\n;;;\n"; } - virtual void emitBasicBlockAnnot(const BasicBlock *BB, std::ostream &OS) { + virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, + std::ostream &OS) { if (BlockFreqs.empty()) return; if (unsigned Count = BlockFreqs[BB]) - OS << ";;; Executed " << Count << " times.\n"; + OS << "\t;;; Basic block executed " << Count << " times.\n"; else - OS << ";;; Never executed!\n"; + OS << "\t;;; Never executed!\n"; + } + + virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, std::ostream &OS){ + if (EdgeFreqs.empty()) return; + + // Figure out how many times each successor executed. + std::vector > SuccCounts; + const TerminatorInst *TI = BB->getTerminator(); + + std::map::iterator I = + EdgeFreqs.lower_bound(std::make_pair(const_cast(BB), 0U)); + for (; I != EdgeFreqs.end() && I->first.first == BB; ++I) + if (I->second) + SuccCounts.push_back(std::make_pair(TI->getSuccessor(I->first.second), + I->second)); + if (!SuccCounts.empty()) { + OS << "\t;;; Out-edge counts:"; + for (unsigned i = 0, e = SuccCounts.size(); i != e; ++i) + OS << " [" << SuccCounts[i].second << " -> " + << SuccCounts[i].first->getName() << "]"; + OS << "\n"; + } } }; } @@ -97,6 +123,7 @@ std::map FuncFreqs; std::map BlockFreqs; + std::map EdgeFreqs; // Output a report. Eventually, there will be multiple reports selectable on // the command line, for now, just keep things simple. @@ -177,11 +204,17 @@ BlockFreqs.insert(Counts.begin(), Counts.end()); } + if (PI.hasAccurateEdgeCounts()) { + std::vector > Counts; + PI.getEdgeCounts(Counts); + EdgeFreqs.insert(Counts.begin(), Counts.end()); + } + if (PrintAnnotatedLLVM || PrintAllCode) { std::cout << "\n===" << std::string(73, '-') << "===\n"; std::cout << "Annotated LLVM code for the module:\n\n"; - ProfileAnnotator PA(FuncFreqs, BlockFreqs); + ProfileAnnotator PA(FuncFreqs, BlockFreqs, EdgeFreqs); if (FunctionsToPrint.empty() || PrintAllCode) M->print(std::cout, &PA); From brukman at cs.uiuc.edu Wed Mar 10 19:05:30 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:30 2004 Subject: [llvm-commits] [parallel] CVS: llvm/tools/gccld/GenerateCode.cpp Message-ID: <200403110104.TAA27951@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.17.2.1 -> 1.17.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+4 -0) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.17.2.1 llvm/tools/gccld/GenerateCode.cpp:1.17.2.2 --- llvm/tools/gccld/GenerateCode.cpp:1.17.2.1 Mon Mar 1 17:59:18 2004 +++ llvm/tools/gccld/GenerateCode.cpp Wed Mar 10 19:04:03 2004 @@ -111,6 +111,10 @@ if (!DisableInline) addPass(Passes, createFunctionInliningPass()); // Inline small functions + // If we didn't decide to inline a function, check to see if we can + // transform it to pass arguments by value instead of by reference. + addPass(Passes, createArgumentPromotionPass()); + // The IPO passes may leave cruft around. Clean up after them. addPass(Passes, createInstructionCombiningPass()); From brukman at cs.uiuc.edu Wed Mar 10 19:05:35 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:35 2004 Subject: [llvm-commits] [parallel] CVS: llvm/docs/CFEBuildInstrs.html GettingStarted.html HowToSubmitABug.html LLVMVsTheWorld.html LangRef.html OpenProjects.html ProgrammersManual.html ReleaseNotes.html TestingGuide.html WritingAnLLVMPass.html index.html Message-ID: <200403110104.TAA06617@zion.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.11.2.1 -> 1.11.2.2 GettingStarted.html updated: 1.48.2.1 -> 1.48.2.2 HowToSubmitABug.html updated: 1.11.2.1 -> 1.11.2.2 LLVMVsTheWorld.html updated: 1.5.4.1 -> 1.5.4.2 LangRef.html updated: 1.43.2.1 -> 1.43.2.2 OpenProjects.html updated: 1.15 -> 1.15.2.1 ProgrammersManual.html updated: 1.53.2.1 -> 1.53.2.2 ReleaseNotes.html updated: 1.102.2.1 -> 1.102.2.2 TestingGuide.html updated: 1.6.4.1 -> 1.6.4.2 WritingAnLLVMPass.html updated: 1.22.2.1 -> 1.22.2.2 index.html updated: 1.6.4.1 -> 1.6.4.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+90 -47) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.11.2.1 llvm/docs/CFEBuildInstrs.html:1.11.2.2 --- llvm/docs/CFEBuildInstrs.html:1.11.2.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/CFEBuildInstrs.html Wed Mar 10 19:04:46 2004 @@ -185,7 +185,7 @@
      % gmake -C runtime
      % mkdir $CFEINSTALL/bytecode-libs
    - % gmake -C runtime install
    + % gmake -C runtime install-bytecode
      % setenv LLVM_LIB_SEARCH_PATH $CFEINSTALL/bytecode-libs
     
    @@ -243,14 +243,13 @@ -
    Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.48.2.1 llvm/docs/GettingStarted.html:1.48.2.2 --- llvm/docs/GettingStarted.html:1.48.2.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/GettingStarted.html Wed Mar 10 19:04:46 2004 @@ -1147,7 +1147,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/01 23:56:01 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/HowToSubmitABug.html diff -u llvm/docs/HowToSubmitABug.html:1.11.2.1 llvm/docs/HowToSubmitABug.html:1.11.2.2 --- llvm/docs/HowToSubmitABug.html:1.11.2.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/HowToSubmitABug.html Wed Mar 10 19:04:46 2004 @@ -315,7 +315,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/01 23:56:01 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/LLVMVsTheWorld.html diff -u llvm/docs/LLVMVsTheWorld.html:1.5.4.1 llvm/docs/LLVMVsTheWorld.html:1.5.4.2 --- llvm/docs/LLVMVsTheWorld.html:1.5.4.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/LLVMVsTheWorld.html Wed Mar 10 19:04:46 2004 @@ -66,7 +66,7 @@

    GCC: Many relatively mature platform backends support assembly-language code generation from many source languages. No run-time compilation -support. Relatively weak optimization support.

    +support.

    @@ -173,7 +173,7 @@
    Brian R. Gaeke
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/01 23:56:01 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.43.2.1 llvm/docs/LangRef.html:1.43.2.2 --- llvm/docs/LangRef.html:1.43.2.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/LangRef.html Wed Mar 10 19:04:46 2004 @@ -623,45 +623,61 @@ outside of the current module. It is illegal for a function declaration to have any linkage type other than "externally visible".

    + - + +
    +

    Global variables define regions of memory allocated at compilation time instead of run-time. Global variables may optionally be initialized. A variable may be defined as a global "constant", which indicates that the contents of the variable will never be modified -(opening options for optimization). Constants must always have an -initial value.

    +(opening options for optimization).

    +

    As SSA values, global variables define pointer values that are in scope (i.e. they dominate) for all basic blocks in the program. Global variables always define a pointer to their "content" type because they describe a region of memory, and all memory objects in LLVM are accessed through pointers.

    +
    + + - + +
    -

    LLVM function definitions are composed of a (possibly empty) -argument list, an opening curly brace, a list of basic blocks, and a -closing curly brace. LLVM function declarations are defined with the "declare" -keyword, a function name, and a function signature.

    -

    A function definition contains a list of basic blocks, forming the -CFG for the function. Each basic block may optionally start with a -label (giving the basic block a symbol table entry), contains a list of -instructions, and ends with a terminator -instruction (such as a branch or function return).

    -

    The first basic block in program is special in two ways: it is -immediately executed on entrance to the function, and it is not allowed -to have predecessor basic blocks (i.e. there can not be any branches to -the entry block of a function). Because the block can have no -predecessors, it also cannot have any PHI nodes.

    -

    -LLVM functions are identified by their name and type signature. Hence, two -functions with the same name but different parameter lists or return values -are considered different functions, and LLVM will resolves references to each -appropriately. -

    + +

    LLVM function definitions are composed of a (possibly empty) argument list, +an opening curly brace, a list of basic blocks, and a closing curly brace. LLVM +function declarations are defined with the "declare" keyword, a +function name, and a function signature.

    + +

    A function definition contains a list of basic blocks, forming the CFG for +the function. Each basic block may optionally start with a label (giving the +basic block a symbol table entry), contains a list of instructions, and ends +with a terminator instruction (such as a branch or +function return).

    + +

    The first basic block in program is special in two ways: it is immediately +executed on entrance to the function, and it is not allowed to have predecessor +basic blocks (i.e. there can not be any branches to the entry block of a +function). Because the block can have no predecessors, it also cannot have any +PHI nodes.

    + +

    LLVM functions are identified by their name and type signature. Hence, two +functions with the same name but different parameter lists or return values are +considered different functions, and LLVM will resolves references to each +appropriately.

    +
    + + @@ -2058,7 +2074,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/01 23:56:01 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.15 llvm/docs/OpenProjects.html:1.15.2.1 --- llvm/docs/OpenProjects.html:1.15 Sun Dec 28 17:04:17 2003 +++ llvm/docs/OpenProjects.html Wed Mar 10 19:04:46 2004 @@ -54,7 +54,7 @@ Additionally this is a good way to get more information about a specific project or to suggest other projects to add to this page. Another good place to look for ideas is the LLVM bug -tracker.

    +tracker by querying for unassigned enhancements.

    @@ -229,11 +229,11 @@
    -

    We are getting to the point where we really need a unified infrastructure for -profile guided optimizations. It would be wonderful to be able to write profile -guided transformations which can be performed either at static compile time -(compile time or offline optimization time) or at runtime in a JIT type setup. -The LLVM transformation itself shouldn't need to know how it is being used.

    +

    We now have a unified infrastructure for writing profile-guided +transformations, which will work either at offline-compile-time or in the JIT, +but we don't have many transformations. We would welcome new profile-guided +transformations as well as improvements to the current profiling system. +

    Ideas for profile guided transformations:

    @@ -245,6 +245,23 @@
  • ...
  • +

    Improvements to the existing support:

    + +
      +
    1. The current block and edge profiling code that gets inserted is very simple +and inefficient. Through the use of control-dependence information, many fewer +counters could be inserted into the code. Also, if the execution count of a +loop is known to be a compile-time or runtime constant, all of the counters in +the loop could be avoided.
    2. + +
    3. You could implement one of the "static profiling" algorithms which analyze a +piece of code an make educated guesses about the relative execution frequencies +of various parts of the code.
    4. + +
    5. You could add path profiling support, or adapt the existing LLVM path +profiling code to work with the generic profiling interfaces.
    6. +
    +
    @@ -291,6 +308,11 @@
    1. Write a new frontend for some language (Java? OCaml? Forth?)
    2. Write a new backend for a target (IA64? MIPS? MMIX?)
    3. +
    4. Random test vector generator: Use a C grammar to generate random C code; +run it through llvm-gcc, then run a random set of passes on it using opt. +Try to crash opt. When opt crashes, use bugpoint to reduce the test case and +mail the result to yourself. Repeat ad infinitum.
    5. +
    6. Design a simple, recognizable logo.
    @@ -302,7 +324,7 @@
    Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2003/12/28 23:04:17 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/ProgrammersManual.html diff -u llvm/docs/ProgrammersManual.html:1.53.2.1 llvm/docs/ProgrammersManual.html:1.53.2.2 --- llvm/docs/ProgrammersManual.html:1.53.2.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/ProgrammersManual.html Wed Mar 10 19:04:46 2004 @@ -1829,7 +1829,7 @@ Dinakar Dhurjati and Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/01 23:56:01 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.102.2.1 llvm/docs/ReleaseNotes.html:1.102.2.2 --- llvm/docs/ReleaseNotes.html:1.102.2.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/ReleaseNotes.html Wed Mar 10 19:04:46 2004 @@ -158,6 +158,7 @@
  • [llvmgcc] C front-end does not emit 'zeroinitializer' when possible
  • [llvmgcc] Structure copies result in a LOT of code
  • LLVM is now much more memory efficient when handling large zero initialized arrays
  • +
  • [llvmgcc] Local array initializers are expanded into large amounts of code
  • @@ -215,6 +216,8 @@
  • Linking weak and strong global variables is dependent on link order
  • Variables used to define non-printable FP constants are externally visible
  • CBE gives linkonce functions wrong linkage semantics
  • +
  • [JIT] Programs cannot resolve the fstat function
  • +
  • [indvars] Induction variable analysis violates LLVM invariants
  • @@ -229,6 +232,9 @@
  • [llvmgcc] floating-point unary minus is incorrect for +0.0
  • [llvm-gcc] miscompilation of 'X = Y = Z' with aggregate values
  • [llvm-gcc] miscompilation when a function is re-declared as static
  • +
  • [llvmgcc] Invalid code created for complex division operation
  • +
  • [llvmgcc] Incorrect code generation for pointer subtraction
  • +
  • [llvmg++] Crash assigning pointers-to-members with casted types
  • @@ -619,7 +625,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/01 23:56:01 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/TestingGuide.html diff -u llvm/docs/TestingGuide.html:1.6.4.1 llvm/docs/TestingGuide.html:1.6.4.2 --- llvm/docs/TestingGuide.html:1.6.4.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/TestingGuide.html Wed Mar 10 19:04:46 2004 @@ -377,7 +377,7 @@ John T. Criswell
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/01 23:56:01 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/WritingAnLLVMPass.html diff -u llvm/docs/WritingAnLLVMPass.html:1.22.2.1 llvm/docs/WritingAnLLVMPass.html:1.22.2.2 --- llvm/docs/WritingAnLLVMPass.html:1.22.2.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/WritingAnLLVMPass.html Wed Mar 10 19:04:46 2004 @@ -1381,8 +1381,8 @@ timing and debugging the actual loading of the module from disk or standard input.

    -

    To solve this problem, eventually the PassManger class will accept a -ModuleSource object instead of a Module itself. When complete, this +

    To solve this problem, eventually the PassManager class will accept +a ModuleSource object instead of a Module itself. When complete, this will also allow for streaming of functions out of the bytecode representation, allowing us to avoid holding the entire program in memory at once if we only are dealing with FunctionPasses.

    @@ -1396,7 +1396,7 @@
    @@ -1426,7 +1426,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/01 23:56:01 $ + Last modified: $Date: 2004/03/11 01:04:46 $ Index: llvm/docs/index.html diff -u llvm/docs/index.html:1.6.4.1 llvm/docs/index.html:1.6.4.2 --- llvm/docs/index.html:1.6.4.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/index.html Wed Mar 10 19:04:46 2004 @@ -48,7 +48,7 @@
    For license information:
    - llvm/LICENSE.TXT + llvm/LICENSE.TXT

    From brukman at cs.uiuc.edu Wed Mar 10 19:05:40 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:05:40 2004 Subject: [llvm-commits] [parallel] CVS: llvm/docs/CommandGuide/llc.html Message-ID: <200403110104.TAA06580@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: llc.html updated: 1.6.6.1 -> 1.6.6.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+14 -10) Index: llvm/docs/CommandGuide/llc.html diff -u llvm/docs/CommandGuide/llc.html:1.6.6.1 llvm/docs/CommandGuide/llc.html:1.6.6.2 --- llvm/docs/CommandGuide/llc.html:1.6.6.1 Mon Mar 1 17:56:01 2004 +++ llvm/docs/CommandGuide/llc.html Wed Mar 10 19:04:46 2004 @@ -90,13 +90,13 @@ architectures are:
    - x86 +
    x86
    IA-32 (Pentium and above)
    - sparc +
    sparc
    SPARC V9
    - c +
    c
    Emit C code

    @@ -142,18 +142,19 @@

  • -regalloc=<ra>
    - Specify the register allocator to use. The default is simple. + Specify the register allocator to use. The default is local. Valid register allocators are: +

    - simple +
    simple
    Very simple register allocator
    - local +
    local
    Local register allocator
    - linearscan +
    linearscan
    Linear scan global register allocator (experimental)
    -

    +

  • -spiller=<sp>
    @@ -161,11 +162,14 @@ Currently this option is used by the linear scan register allocator. The default is local. Valid spillers are: +

    - local +
    simple
    +
    Simple spiller
    + +
    local
    Local spiller
    -

    From brukman at cs.uiuc.edu Wed Mar 10 19:08:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:08:00 2004 Subject: [llvm-commits] [parallel] CVS: llvm/Makefile.config.in Makefile.rules Message-ID: <200403110107.TAA07738@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.config.in updated: 1.16.2.1 -> 1.16.2.2 Makefile.rules updated: 1.169.2.1 -> 1.169.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+17 -5) Index: llvm/Makefile.config.in diff -u llvm/Makefile.config.in:1.16.2.1 llvm/Makefile.config.in:1.16.2.2 --- llvm/Makefile.config.in:1.16.2.1 Mon Mar 1 17:54:05 2004 +++ llvm/Makefile.config.in Wed Mar 10 19:07:33 2004 @@ -65,8 +65,8 @@ # object files. OBJ_ROOT := . -# Path to location for LLVM front-end this should only be specified here if you -# want to override the value set in Makefile.$(uname) +# Path to location for LLVM C/C++ front-end. You can modify this if you +# want to override the value set by configure. LLVMGCCDIR := @LLVMGCCDIR@ # When this variable is set to 1, programs in the llvm/test/Programs hierarchy Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.169.2.1 llvm/Makefile.rules:1.169.2.2 --- llvm/Makefile.rules:1.169.2.1 Mon Mar 1 17:54:05 2004 +++ llvm/Makefile.rules Wed Mar 10 19:07:33 2004 @@ -78,6 +78,7 @@ # if BYTECODE_LIBRARY is specified, the default is to build the bytecode lib all:: bytecodelib install:: install-bytecode-library +install-bytecode:: install-bytecode-library endif # Default Rule: Make sure it's also a :: rule @@ -92,6 +93,9 @@ # Default rule for building only bytecode. bytecode:: +# Default rule for installing only bytecode. +install-bytecode:: + # Print out the directories used for building prdirs:: @${ECHO} "Build Source Root: " $(BUILD_SRC_ROOT) @@ -320,6 +324,13 @@ # (Note that we always link with the C++ compiler). # Link := $(LIBTOOL) --mode=link $(CXX) +ifeq ($(ARCH),Sparc) +Link += -B /home/vadve/shared/localtools/sparc/bin +else + ifeq ($(ARCH),X86) + Link += -B /home/vadve/shared/localtools/x86/bin + endif +endif # link both projlib and llvmlib libraries LinkG := $(Link) -g -L$(PROJLIBDEBUGSOURCE) -L$(LLVMLIBDEBUGSOURCE) $(STRIP) @@ -391,7 +402,7 @@ #--------------------------------------------------------- ifdef DIRS -all install clean test bytecode stripped-bytecode:: +all install clean test bytecode stripped-bytecode install-bytecode:: $(VERB) for dir in ${DIRS}; do \ if [ ! -f $$dir/Makefile ]; \ then \ @@ -410,8 +421,9 @@ test :: $(addsuffix /.maketest , $(PARALLEL_DIRS)) bytecode :: $(addsuffix /.makebytecode, $(PARALLEL_DIRS)) stripped-bytecode :: $(addsuffix /.makestripped-bytecode, $(PARALLEL_DIRS)) +install-bytecode :: $(addsuffix /.makeinstall-bytecode, $(PARALLEL_DIRS)) -%/.makeall %/.makeinstall %/.makeclean %/.maketest %/.makebytecode %/.makestripped-bytecode: +%/.makeall %/.makeinstall %/.makeclean %/.maketest %/.makebytecode %/.makestripped-bytecode %/.makeinstall-bytecode: $(VERB) if [ ! -f $(@D)/Makefile ]; \ then \ $(MKDIR) $(@D); \ @@ -422,7 +434,7 @@ # Handle directories that may or may not exist ifdef OPTIONAL_DIRS -all install clean test bytecode stripped-bytecode:: +all install clean test bytecode stripped-bytecode install-bytecode:: $(VERB) for dir in ${OPTIONAL_DIRS}; do \ if [ -d $(SourceDir)/$$dir ]; \ then\ From brukman at cs.uiuc.edu Wed Mar 10 19:10:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/External/SPEC/CINT2000/164.gzip/Makefile Message-ID: <200403110109.TAA07832@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT2000/164.gzip: Makefile updated: 1.1.14.1 -> 1.1.14.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+4 -0) Index: llvm/test/Programs/External/SPEC/CINT2000/164.gzip/Makefile diff -u llvm/test/Programs/External/SPEC/CINT2000/164.gzip/Makefile:1.1.14.1 llvm/test/Programs/External/SPEC/CINT2000/164.gzip/Makefile:1.1.14.2 --- llvm/test/Programs/External/SPEC/CINT2000/164.gzip/Makefile:1.1.14.1 Mon Mar 1 17:59:09 2004 +++ llvm/test/Programs/External/SPEC/CINT2000/164.gzip/Makefile Wed Mar 10 19:09:31 2004 @@ -1,4 +1,8 @@ LEVEL = ../../../../../.. RUN_OPTIONS = `cat $(REF_IN_DIR)control` +ifeq ($(RUN_TYPE),test) STDOUT_FILENAME := input.compressed.out +else +STDOUT_FILENAME := input.combined.out +endif include ../../Makefile.spec2000 From brukman at cs.uiuc.edu Wed Mar 10 19:10:07 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:07 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/External/SPEC/CINT2000/197.parser/xa.c Message-ID: <200403110109.TAA07843@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT2000/197.parser: xa.c added (r1.1.2.1) --- Log message: Merge from trunk. --- Diffs of the changes: (+16 -0) Index: llvm/test/Programs/External/SPEC/CINT2000/197.parser/xa.c diff -c /dev/null llvm/test/Programs/External/SPEC/CINT2000/197.parser/xa.c:1.1.2.1 *** /dev/null Wed Mar 10 19:09:41 2004 --- llvm/test/Programs/External/SPEC/CINT2000/197.parser/xa.c Wed Mar 10 19:09:31 2004 *************** *** 0 **** --- 1,16 ---- + + #include + + int max_space_in_use = 0; + int space_in_use = 0; + + void initialize_memory() { + } + + void * xalloc(int size) { + return malloc(size); + } + + void xfree(void *P, int size) { + free(P); + } From brukman at cs.uiuc.edu Wed Mar 10 19:10:12 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:12 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/External/SPEC/CINT95/132.ijpeg/Makefile Message-ID: <200403110109.TAA07864@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT95/132.ijpeg: Makefile updated: 1.3.2.1 -> 1.3.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+8 -4) Index: llvm/test/Programs/External/SPEC/CINT95/132.ijpeg/Makefile diff -u llvm/test/Programs/External/SPEC/CINT95/132.ijpeg/Makefile:1.3.2.1 llvm/test/Programs/External/SPEC/CINT95/132.ijpeg/Makefile:1.3.2.2 --- llvm/test/Programs/External/SPEC/CINT95/132.ijpeg/Makefile:1.3.2.1 Mon Mar 1 17:59:09 2004 +++ llvm/test/Programs/External/SPEC/CINT95/132.ijpeg/Makefile Wed Mar 10 19:09:31 2004 @@ -1,7 +1,12 @@ LEVEL = ../../../../../.. -STDIN_FILENAME := specmun.ppm -STDOUT_FILENAME := specmun.out -RUN_OPTIONS := -image_file specmun.ppm -compression.quality 90 -compression.optimize_coding 0 -compression.smoothing_factor 90 -difference.image 1 -difference.x_stride 10 -difference.y_stride 10 -verbose 1 -GO.findoptcomp +ifeq ($(RUN_TYPE),test) +FILENAME := specmun +else +FILENAME := vigo +endif + +STDOUT_FILENAME := $(FILENAME).out +RUN_OPTIONS := -image_file $(FILENAME).ppm -compression.quality 90 -compression.optimize_coding 0 -compression.smoothing_factor 90 -difference.image 1 -difference.x_stride 10 -difference.y_stride 10 -verbose 1 -GO.findoptcomp # This line nukes the __const's found in /usr/include/stdio.h that prevent the # extern char * sys_errlist variable from linking properly. @@ -9,4 +14,3 @@ Source=libpbm1.c libpbm2.c libpbm3.c libpbm4.c libpbm5.c libpgm1.c libpgm2.c libppm1.c libppm2.c libppm3.c libppm4.c libppm5.c spec_image.c spec_jmemdst.c spec_jmemsrc.c spec_main.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c wrtarga.c rdbmp.c wrbmp.c jcapi.c jcparam.c jdatadst.c jcmaster.c jcmarker.c jcmainct.c jcprepct.c jccoefct.c jccolor.c jcsample.c jchuff.c jcdctmgr.c jfdctfst.c jfdctflt.c jfdctint.c jdapi.c jdatasrc.c jdmaster.c jdmarker.c jdmainct.c jdcoefct.c jdpostct.c jddctmgr.c jidctfst.c jidctflt.c jidctint.c jidctred.c jdhuff.c jdsample.c jdcolor.c jquant1.c jquant2.c jdmerge.c jcomapi.c jutils.c jerror.c jmemmgr.c jmemnobs.c include ../../Makefile.spec95 - From brukman at cs.uiuc.edu Wed Mar 10 19:10:17 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:17 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/External/SPEC/CINT2000/Makefile Message-ID: <200403110109.TAA07825@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT2000: Makefile updated: 1.12 -> 1.12.4.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+0 -8) Index: llvm/test/Programs/External/SPEC/CINT2000/Makefile diff -u llvm/test/Programs/External/SPEC/CINT2000/Makefile:1.12 llvm/test/Programs/External/SPEC/CINT2000/Makefile:1.12.4.1 --- llvm/test/Programs/External/SPEC/CINT2000/Makefile:1.12 Tue Nov 25 10:42:00 2003 +++ llvm/test/Programs/External/SPEC/CINT2000/Makefile Wed Mar 10 19:09:31 2004 @@ -13,12 +13,4 @@ 256.bzip2 \ 300.twolf -# Get the $(ARCH) setting -include $(LEVEL)/Makefile.config - -# Disable crafty until it stops infinite-looping on Sparc -ifeq ($(ARCH), Sparc) -PARALLEL_DIRS := $(filter-out 186.crafty, $(PARALLEL_DIRS)) -endif - include ${LEVEL}/test/Programs/Makefile.programs From brukman at cs.uiuc.edu Wed Mar 10 19:10:22 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:22 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/Makefile.programs TEST.vtl.Makefile Message-ID: <200403110109.TAA07816@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.109.2.1 -> 1.109.2.2 TEST.vtl.Makefile updated: 1.3.2.1 -> 1.3.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+2 -19) Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.109.2.1 llvm/test/Programs/Makefile.programs:1.109.2.2 --- llvm/test/Programs/Makefile.programs:1.109.2.1 Mon Mar 1 17:59:09 2004 +++ llvm/test/Programs/Makefile.programs Wed Mar 10 19:09:31 2004 @@ -395,7 +395,7 @@ # $(PROGRAMS_TO_TEST:%=Output/%.llvm-prof.bc): \ Output/%.llvm-prof.bc: Output/%.llvm.bc - $(LOPT) -insert-block-profiling $< -o $@ -f + $(LOPT) -insert-edge-profiling $< -o $@ -f $(PROGRAMS_TO_TEST:%=Output/%.printprof): \ Output/%.printprof: Output/%.llvm.bc Output/%.prof $(LPROF) Index: llvm/test/Programs/TEST.vtl.Makefile diff -u llvm/test/Programs/TEST.vtl.Makefile:1.3.2.1 llvm/test/Programs/TEST.vtl.Makefile:1.3.2.2 --- llvm/test/Programs/TEST.vtl.Makefile:1.3.2.1 Mon Mar 1 17:59:09 2004 +++ llvm/test/Programs/TEST.vtl.Makefile Wed Mar 10 19:09:31 2004 @@ -30,26 +30,9 @@ #-$(VERB) $(VTL) view > $@ #$(VERB) $(VTL) delete $* -f -test:: $(PROGRAMS_TO_TEST:%=test.$(TEST).pa.%) # -# Generate events for Pool Allocated CBE -# -$(PROGRAMS_TO_TEST:%=test.$(TEST).pa.%): \ -test.$(TEST).pa.%: Output/%.poolalloc.cbe - @echo "=========================================" - @echo "Running '$(TEST)' test on '$(TESTNAME)' program" -ifeq ($(RUN_OPTIONS),) - $(VERB) cat $(STDIN_FILENAME) | $(VTL) activity $* -d 50 -c sampling -o $(EVENTS) -app $< -else - $(VERB) cat $(STDIN_FILENAME) | $(VTL) activity $* -d 50 -c sampling -o $(EVENTS) -app $<,"$(RUN_OPTIONS)" -endif - -$(VERB) $(VTL) run $* - -$(VERB) $(VTL) view > $@ - $(VERB) $(VTL) delete $* -f - -# -# Generate events for Pool Allocated CBE +# Generate events for CBE # $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.cbe From brukman at cs.uiuc.edu Wed Mar 10 19:10:27 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:27 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/MultiSource/Applications/hbd/Makefile Message-ID: <200403110109.TAA07878@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Applications/hbd: Makefile updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/MultiSource/Applications/hbd/Makefile diff -u llvm/test/Programs/MultiSource/Applications/hbd/Makefile:1.1.2.1 llvm/test/Programs/MultiSource/Applications/hbd/Makefile:1.1.2.2 --- llvm/test/Programs/MultiSource/Applications/hbd/Makefile:1.1.2.1 Mon Mar 1 17:59:10 2004 +++ llvm/test/Programs/MultiSource/Applications/hbd/Makefile Wed Mar 10 19:09:31 2004 @@ -3,6 +3,6 @@ CPPFLAGS += -DHAVE_CONFIG_H LDFLAGS += -lstdc++ LIBS += -lstdc++ -RUN_OPTIONS = Sort.class +RUN_OPTIONS = $(BUILD_SRC_DIR)/Sort.class REQUIRES_EH_SUPPORT := 1 include ../../Makefile.multisrc From brukman at cs.uiuc.edu Wed Mar 10 19:10:32 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:32 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile Message-ID: <200403110109.TAA07850@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT95/124.m88ksim: Makefile updated: 1.4.2.1 -> 1.4.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+8 -9) Index: llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile diff -u llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile:1.4.2.1 llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile:1.4.2.2 --- llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile:1.4.2.1 Mon Mar 1 17:59:09 2004 +++ llvm/test/Programs/External/SPEC/CINT95/124.m88ksim/Makefile Wed Mar 10 19:09:31 2004 @@ -2,18 +2,13 @@ RUN_OPTIONS = -c ifeq ($(ENDIAN),big) -EXTENSION := big +STDIN_FILENAME := ctl.big else -EXTENSION := lit +STDIN_FILENAME := ctl.lit +CPPFLAGS += -DLEHOST endif -ifeq ($(RUN_TYPE),test) -STDIN_FILENAME := ctl.$(EXTENSION) -else -STDIN_FILENAME := dcrand.$(EXTENSION) -endif - -STDOUT_FILENAME := test.out +STDOUT_FILENAME = $(RUN_TYPE).out Source := addd.c \ adds.c \ @@ -113,3 +108,7 @@ updstat.c include ../../Makefile.spec95 + +$(REF_IN_DIR)/ctl.$(EXTENSION): $(REF_IN_DIR)/ctl.raw + $(SED) -e s/%endian%/$(EXTENSION)/ < $< > $@ + From brukman at cs.uiuc.edu Wed Mar 10 19:10:37 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:37 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/External/SPEC/CINT95/130.li/Makefile Message-ID: <200403110109.TAA07857@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT95/130.li: Makefile updated: 1.2.2.1 -> 1.2.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+3 -3) Index: llvm/test/Programs/External/SPEC/CINT95/130.li/Makefile diff -u llvm/test/Programs/External/SPEC/CINT95/130.li/Makefile:1.2.2.1 llvm/test/Programs/External/SPEC/CINT95/130.li/Makefile:1.2.2.2 --- llvm/test/Programs/External/SPEC/CINT95/130.li/Makefile:1.2.2.1 Mon Mar 1 17:59:09 2004 +++ llvm/test/Programs/External/SPEC/CINT95/130.li/Makefile Wed Mar 10 19:09:31 2004 @@ -1,5 +1,5 @@ LEVEL = ../../../../../.. -REQUIRES_EH_SUPPORT = 1 -STDIN_FILENAME := train.lsp -STDOUT_FILENAME := train.out include ../../Makefile.spec95 +REQUIRES_EH_SUPPORT = 1 +STDIN_FILENAME := $(RUN_TYPE).lsp +STDOUT_FILENAME := $(RUN_TYPE).out From brukman at cs.uiuc.edu Wed Mar 10 19:10:43 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:43 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c/p2c.hdrs p2c.proto Message-ID: <200403110109.TAA07899@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c: p2c.hdrs added (r1.1.2.1) p2c.proto added (r1.1.2.1) --- Log message: Merge from trunk. --- Diffs of the changes: (+1000 -0) Index: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c/p2c.hdrs diff -c /dev/null llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c/p2c.hdrs:1.1.2.1 *** /dev/null Wed Mar 10 19:09:42 2004 --- llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c/p2c.hdrs Wed Mar 10 19:09:31 2004 *************** *** 0 **** --- 1,574 ---- + + /* Declarations created by "makeproto" on Mon Feb 16 16:39:12 2004 */ + + + + /* Declarations from trans.c */ + extern void saveoldfile PP( (char *fname) ); + extern void closelogfile PV(); + extern void showinitfile PV(); + extern void usage PV(); + extern int main PP( (int argc, char **argv) ); + extern int outmem PV(); + extern int ISBOGUS PP( (char *p) ); + extern char *meaningkindname PP( (enum meaningkind kind) ); + extern char *typekindname PP( (enum typekind kind) ); + extern char *exprkindname PP( (enum exprkind kind) ); + extern char *stmtkindname PP( (enum stmtkind kind) ); + extern void dumptype PP( (Type *tp) ); + extern void dumpmeaning PP( (Meaning *mp) ); + extern void dumpsymtable PP( (Symbol *sym) ); + extern void dumptypename PP( (Type *tp, int waddr) ); + extern void dumptypename_file PP( (FILE *f, Type *tp) ); + extern void dumpexpr PP( (Expr *ex) ); + extern void dumpexpr_file PP( (FILE *f, Expr *ex) ); + extern void innerdumpstmt PP( (Stmt *sp, int indent) ); + extern void dumpstmt PP( (Stmt *sp, int indent) ); + extern void dumpstmt_file PP( (FILE *f, Stmt *sp) ); + extern void wrapup PV(); + extern void mem_summary PV(); + extern anyptr test_malloc PP( (int size, int *total, int *final) ); + extern void test_free PP( (anyptr p) ); + extern anyptr test_realloc PP( (anyptr p, int size) ); + + /* Declarations from stuff.c */ + extern void debughook PV(); + extern Strlist *strlist_append PP( (Strlist **base, char *s) ); + extern Strlist *strlist_insert PP( (Strlist **base, char *s) ); + extern Strlist *strlist_add PP( (Strlist **base, char *s) ); + extern void strlist_mix PP( (Strlist **base, Strlist *sl) ); + extern void strlist_eat PP( (Strlist **base) ); + extern void strlist_empty PP( (Strlist **base) ); + extern void strlist_remove PP( (Strlist **base, char *s) ); + extern void strlist_delete PP( (Strlist **base, Strlist *sl) ); + extern Strlist *strlist_find PP( (Strlist *base, char *s) ); + extern Strlist *strlist_cifind PP( (Strlist *base, char *s) ); + extern int strcincmp PP( (char *s1, char *s2, int n) ); + extern int strcicmp PP( (char *s1, char *s2) ); + extern void fixfname PP( (char *fn, char *ext) ); + extern void removesuffix PP( (char *fn) ); + extern char *stralloc PP( (char *s) ); + extern void strchange PP( (char **v, char *s) ); + extern char *format_gen PP( (char *fmt, long i1, long i2, double dbl, + char *s1, char *s2, char *s3) ); + extern char *format_none PP( (char *fmt) ); + extern char *format_d PP( (char *fmt, int a1) ); + extern char *format_g PP( (char *fmt, double a1) ); + extern char *format_s PP( (char *fmt, char *a1) ); + extern char *format_ss PP( (char *fmt, char *a1, char *a2) ); + extern char *format_sd PP( (char *fmt, char *a1, int a2) ); + extern char *format_ds PP( (char *fmt, long a1, char *a2) ); + extern char *format_dd PP( (char *fmt, long a1, long a2) ); + extern char *format_sss PP( (char *fmt, char *a1, char *a2, char *a3) ); + extern char *format_ssd PP( (char *fmt, char *a1, char *a2, long a3) ); + extern char *format_sds PP( (char *fmt, char *a1, long a2, char *a3) ); + extern int my_toupper PP( (int c) ); + extern int my_tolower PP( (int c) ); + extern void upc PP( (char *s) ); + extern void lwc PP( (char *s) ); + extern char *strupper PP( (char *s) ); + extern char *strlower PP( (char *s) ); + extern char *my_strchr PP( (char *cp, int c) ); + extern char *my_strrchr PP( (char *cp, int c) ); + extern char *my_strtok PP( (char *cp, char *delim) ); + extern long my_strtol PP( (char *buf, char **ret, int base) ); + extern void init_stuff PV(); + + /* Declarations from out.c */ + extern void setup_out PV(); + extern void select_outfile PP( (FILE *fp) ); + extern void start_source PV(); + extern void end_source PV(); + extern int line_start PV(); + extern int cur_column PV(); + extern int lookback PP( (int n) ); + extern int lookback_prn PP( (int n) ); + extern int adddeltas PP( (int d1, int d2) ); + extern int applydelta PP( (int i, int d) ); + extern void moreindent PP( (int delta) ); + extern void singleindent PP( (int delta) ); + extern void futureindent PP( (int num) ); + extern int parsedelta PP( (char *cp, int def) ); + extern void eatblanklines PV(); + extern int parse_breakstr PP( (char *cp) ); + extern long getcurtime PV(); + extern void output PP( (char *msg) ); + extern void out_n_spaces PP( (int n) ); + extern void out_spaces PP( (int spc, int over, int len, int delta) ); + extern void testlinebreaker PP( (int lev, char *fn) ); + extern void outsection PP( (int size) ); + extern int isembedcomment PP( (Strlist *cmt) ); + extern Strlist *outcomments PP( (Strlist *cmt) ); + extern void outcomment PP( (Strlist *cmt) ); + extern void outtrailcomment PP( (Strlist *cmt, int serial, int indent) ); + extern void flushcomments PP( (Strlist **cmt, int kind, int serial) ); + extern char *rawCstring PP( (char *fmt, char *s, int len, int special) ); + extern char *makeCstring PP( (char *s, int len) ); + extern char *makeCchar PP( (int ich) ); + + /* Declarations from comment.c */ + extern void setup_comment PV(); + extern int commentlen PP( (Strlist *cmt) ); + extern int commentvisible PP( (Strlist *cmt) ); + extern void steal_comments PP( (long olds, long news, int always) ); + extern Strlist *fixbeginendcomment PP( (Strlist *cmt) ); + extern void attach_comments PP( (Stmt *sbase) ); + extern void setcommentkind PP( (Strlist *cmt, int kind) ); + extern void commentline PP( (int kind) ); + extern void addnote PP( (char *msg, long serial) ); + extern Strlist *grabcomment PP( (int kind) ); + extern int matchcomment PP( (Strlist *cmt, int kind, int stamp) ); + extern Strlist *findcomment PP( (Strlist *cmt, int kind, int stamp) ); + extern Strlist *extractcomment PP( (Strlist **cmt, int kind, int stamp) ); + extern void changecomments PP( (Strlist *cmt, int okind, int ostamp, + int kind, int stamp) ); + + /* Declarations from lex.c */ + extern char *fixpascalname PP( (char *name) ); + extern void init_lex PV(); + extern void setup_lex PV(); + extern int checkeatnote PP( (char *msg) ); + extern void beginerror PV(); + extern void counterror PV(); + extern void error PP( (char *msg) ); + extern void interror PP( (char *proc, char *msg) ); + extern void warning PP( (char *msg) ); + extern void intwarning PP( (char *proc, char *msg) ); + extern void note PP( (char *msg) ); + extern void endnote PP( (char *msg) ); + extern void showendnotes PV(); + extern char *tok_name PP( (Token tok) ); + extern void expected PP( (char *msg) ); + extern void expecttok PP( (Token tok) ); + extern void needtok PP( (Token tok) ); + extern int wexpected PP( (char *msg) ); + extern int wexpecttok PP( (Token tok) ); + extern int wneedtok PP( (Token tok) ); + extern void alreadydef PP( (Symbol *sym) ); + extern void undefsym PP( (Symbol *sym) ); + extern void symclass PP( (Symbol *sym) ); + extern void badtypes PV(); + extern void valrange PV(); + extern void skipparens PV(); + extern void skiptotoken2 PP( (Token tok1, Token tok2) ); + extern void skippasttoken2 PP( (Token tok1, Token tok2) ); + extern void skippasttotoken PP( (Token tok1, Token tok2) ); + extern void skiptotoken PP( (Token tok) ); + extern void skippasttoken PP( (Token tok) ); + extern int skipopenparen PV(); + extern int skipcloseparen PV(); + extern int skipcomma PV(); + extern char *findaltname PP( (char *name, int num) ); + extern Symbol *findsymbol_opt PP( (char *name) ); + extern Symbol *findsymbol PP( (char *name) ); + extern void clearprogress PV(); + extern void progress PV(); + extern void p2c_getline PV(); + extern void push_input_file PP( (FILE *fp, char *fname, int isinclude) ); + extern void include_as_import PV(); + extern void push_input_strlist PP( (Strlist *sp, char *fname) ); + extern void pop_input PV(); + extern int undooption PP( (int i, char *name) ); + extern void badinclude PV(); + extern int handle_include PP( (char *fn) ); + extern int turbo_directive PP( (char *closing, char *after) ); + extern void defmacro PP( (char *name, long kind, char *fname, + int lnum) ); + extern void check_unused_macros PV(); + extern char *getinlinepart PV(); + extern char getchartok PV(); + extern char *getparenstr PP( (char *buf) ); + extern void leadingcomments PV(); + extern void get_C_string PP( (int term) ); + extern void begincommenting PP( (char *cp) ); + extern void saveinputcomment PP( (char *cp) ); + extern void endcommenting PP( (char *cp) ); + extern int peeknextchar PV(); + extern void gettok PV(); + extern void checkkeyword PP( (Token tok) ); + extern void checkmodulewords PV(); + + /* Declarations from parse.c */ + extern void setup_parse PV(); + extern void echobreak PV(); + extern void echoword PP( (char *name, int comma) ); + extern void echoprocname PP( (Meaning *mp) ); + extern void need_forward_decl PP( (Meaning *func) ); + extern void free_stmt PP( (Stmt *sp) ); + extern Stmt *makestmt PP( (enum stmtkind kind) ); + extern Stmt *makestmt_call PP( (Expr *call) ); + extern Stmt *makestmt_assign PP( (Expr *lhs, Expr *rhs) ); + extern Stmt *makestmt_if PP( (Expr *cond, Stmt *thn, Stmt *els) ); + extern Stmt *makestmt_seq PP( (Stmt *s1, Stmt *s2) ); + extern Stmt *copystmt PP( (Stmt *sp) ); + extern void nukestmt PP( (Stmt *sp) ); + extern void splicestmt PP( (Stmt *sp, Stmt *spnew) ); + extern int stmtcount PP( (Stmt *sp) ); + extern Stmt *close_files_to_ctx PP( (Meaning *ctx) ); + extern int simplewith PP( (Expr *ex) ); + extern int simplefor PP( (Stmt *sp, Expr *ex) ); + extern int tryfuncmacro PP( (Expr **exp, Meaning *mp) ); + extern Expr *replaceexprexpr PP( (Expr *ex, Expr *oldex, Expr *newex, + int keeptype) ); + extern void replaceexpr PP( (Stmt *sp, Expr *oldex, Expr *newex) ); + extern Stmt *mixassignments PP( (Stmt *sp, Meaning *mp) ); + extern int expr_is_bool PP( (Expr *ex, int want) ); + extern int implies PP( (Expr *c1, Expr *c2, int not1, int not2) ); + extern void infiniteloop PP( (Stmt *sp) ); + extern Expr *print_func PP( (Expr *ex) ); + extern int printnl_func PP( (Expr *ex) ); + extern Expr *chg_printf PP( (Expr *ex) ); + extern Expr *mix_printf PP( (Expr *ex, Expr *ex2) ); + extern void eatstmt PP( (Stmt **spp) ); + extern int haslabels PP( (Stmt *sp) ); + extern void fixblock PP( (Stmt **spp, Stmt *thereturn) ); + extern int checkvarchangedexpr PP( (Expr *ex, Meaning *mp, int addrokay) ); + extern int checkvarchanged PP( (Stmt *sp, Meaning *mp) ); + extern int checkexprchanged PP( (Stmt *sp, Expr *ex) ); + extern void checkvaroffsetexpr PP( (Expr *ex, Meaning *mp, int myoffset) ); + extern void checkvaroffsetstmt PP( (Stmt *sp, Meaning *mp) ); + extern int checkvaroffset PP( (Stmt *sp, Meaning *mp) ); + extern Expr *initfilevar PP( (Expr *ex) ); + extern void initfilevars PP( (Meaning *mp, Stmt ***sppp, Expr *exbase) ); + extern void movetoend PP( (Meaning *mp) ); + extern void do_include PP( (Token blkind) ); + extern void p_block PP( (Token blkind) ); + extern int p_search PP( (char *fname, char *ext, int need) ); + extern void p_program PV(); + + /* Declarations from decl.c */ + extern Meaning *makespecialproc PP( (char *name, Stmt *(*handler)()) ); + extern Meaning *makestandardproc PP( (char *name, Stmt *(*handler)()) ); + extern Meaning *makespecialfunc PP( (char *name, Expr *(*handler)()) ); + extern Meaning *makestandardfunc PP( (char *name, Expr *(*handler)()) ); + extern Meaning *makespecialvar PP( (char *name, Expr *(*handler)()) ); + extern void setup_decl PV(); + extern int push_imports PV(); + extern void pop_imports PP( (int mark) ); + extern void import_ctx PP( (Meaning *ctx) ); + extern void perm_import PP( (Meaning *ctx) ); + extern void unimport PP( (int mark) ); + extern void activatemeaning PP( (Meaning *mp) ); + extern void pushctx PP( (Meaning *ctx) ); + extern void popctx PV(); + extern void forget_ctx PP( (Meaning *ctx, int all) ); + extern void handle_nameof PV(); + extern int issafename PP( (Symbol *sp, int isglobal, int isdefine) ); + extern void setupmeaning PP( (Meaning *mp, Symbol *sym, + enum meaningkind kind, + enum meaningkind namekind) ); + extern Meaning *addmeaningas PP( (Symbol *sym, enum meaningkind kind, + enum meaningkind namekind) ); + extern Meaning *addmeaning PP( (Symbol *sym, enum meaningkind kind) ); + extern Meaning *addmeaningafter PP( (Meaning *mpprev, Symbol *sym, + enum meaningkind kind) ); + extern void unaddmeaning PP( (Meaning *mp) ); + extern void readdmeaning PP( (Meaning *mp) ); + extern Meaning *addfield PP( (Symbol *sym, Meaning ***flast, + Type *rectype, Meaning *tname) ); + extern int isfiletype PP( (Type *type, int big) ); + extern Meaning *isfilevar PP( (Expr *ex) ); + extern Type *filebasetype PP( (Type *type) ); + extern Expr *filebasename PP( (Expr *ex) ); + extern Expr *filenamepart PP( (Expr *ex) ); + extern int fileisbuffered PP( (Expr *ex, int maybe) ); + extern Type *findbasetype_ PP( (Type *type, int flags) ); + extern Type *findbasetype PP( (Type *type, int flags) ); + extern Expr *arraysize PP( (Type *tp, int incskipped) ); + extern Type *promote_type PP( (Type *tp) ); + extern Type *promote_type_bin PP( (Type *t1, Type *t2) ); + extern void predeclare_varstruct PP( (Meaning *mp) ); + extern void outdeclarator PP( (Type *type, char *name, int flags) ); + extern Type *canonicaltype PP( (Type *type) ); + extern int identicaltypes PP( (Type *t1, Type *t2) ); + extern int similartypes PP( (Type *t1, Type *t2) ); + extern void declarefiles PP( (Strlist *fnames) ); + extern char *variantfieldname PP( (int num) ); + extern int record_is_union PP( (Type *tp) ); + extern void outfieldlist PP( (Meaning *mp) ); + extern void declarebigfile PP( (Type *type) ); + extern void outbasetype PP( (Type *type, int flags) ); + extern void out_type PP( (Type *type, int witharrays) ); + extern int varstorageclass PP( (Meaning *mp) ); + extern char *storageclassname PP( (int i) ); + extern void declarevar PP( (Meaning *mp, int which) ); + extern int checkvarmac PP( (Meaning *mp) ); + extern int declarevars PP( (Meaning *ctx, int invarstruct) ); + extern void redeclarevars PP( (Meaning *ctx) ); + extern void out_argdecls PP( (Type *ftype) ); + extern void makevarstruct PP( (Meaning *func) ); + extern Type *maketype PP( (enum typekind kind) ); + extern Type *makesubrangetype PP( (Type *type, Expr *smin, Expr *smax) ); + extern Type *makesettype PP( (Type *setof) ); + extern Type *makestringtype PP( (int len) ); + extern Type *makepointertype PP( (Type *type) ); + extern Value p_constant PP( (Type *type) ); + extern int typebits PP( (long smin, long smax) ); + extern int packedsize PP( (char *fname, Type **typep, long *sizep, + int mode) ); + extern void decl_comments PP( (Meaning *mp) ); + extern void p_attributes PV(); + extern void ignore_attributes PV(); + extern int size_attributes PV(); + extern void p_mech_spec PP( (int doref) ); + extern Type *p_modula_subrange PP( (Type *basetype) ); + extern void makefakestruct PP( (Type *tp, Meaning *tname) ); + extern Type *p_type PP( (Meaning *tname) ); + extern Type *p_funcdecl PP( (int *isfunc, int istype) ); + extern Symbol *findlabelsym PV(); + extern void p_labeldecl PV(); + extern Meaning *findfieldname PP( (Symbol *sym, Meaning **variants, + int *nvars) ); + extern Expr *p_constrecord PP( (Type *type, int style) ); + extern Expr *p_constarray PP( (Type *type, int style) ); + extern Expr *p_conststring PP( (Type *type, int style) ); + extern Expr *p_subconst PP( (Type *type, int style) ); + extern void p_constdecl PV(); + extern void declaresubtypes PP( (Meaning *mp) ); + extern void declaretype PP( (Meaning *mp) ); + extern void declaretypes PP( (int outflag) ); + extern void p_typedecl PV(); + extern void setupfilevar PP( (Meaning *mp) ); + extern Meaning *validatedtype PP( (Meaning *dtype, Type *type) ); + extern void p_vardecl PV(); + extern void p_valuedecl PV(); + extern Meaning *maketempvar PP( (Type *type, char *name) ); + extern Meaning *makestmttempvar PP( (Type *type, char *name) ); + extern Meaning *markstmttemps PV(); + extern void freestmttemps PP( (Meaning *mark) ); + extern void freetempvar PP( (Meaning *tvar) ); + extern void canceltempvar PP( (Meaning *tvar) ); + + /* Declarations from expr.c */ + extern void free_value PP( (Value *val) ); + extern Value copyvalue PP( (Value val) ); + extern int valuesame PP( (Value a, Value b) ); + extern char *value_name PP( (Value val, char *intfmt, int islong) ); + extern Value value_cast PP( (Value val, Type *type) ); + extern Type *ord_type PP( (Type *tp) ); + extern int long_type PP( (Type *tp) ); + extern Value make_ord PP( (Type *type, long i) ); + extern long ord_value PP( (Value val) ); + extern void ord_range_expr PP( (Type *type, Expr **smin, Expr **smax) ); + extern int ord_range PP( (Type *type, long *smin, long *smax) ); + extern void freeexpr PP( (Expr *ex) ); + extern Expr *makeexpr PP( (enum exprkind kind, int n) ); + extern Expr *makeexpr_un PP( (enum exprkind kind, Type *type, + Expr *arg1) ); + extern Expr *makeexpr_bin PP( (enum exprkind kind, Type *type, + Expr *arg1, Expr *arg2) ); + extern Expr *makeexpr_val PP( (Value val) ); + extern Expr *makeexpr_char PP( (int c) ); + extern Expr *makeexpr_long PP( (long i) ); + extern Expr *makeexpr_real PP( (char *r) ); + extern Expr *makeexpr_lstring PP( (char *msg, int len) ); + extern Expr *makeexpr_string PP( (char *msg) ); + extern int checkstring PP( (Expr *ex, char *msg) ); + extern Expr *makeexpr_var PP( (Meaning *mp) ); + extern Expr *makeexpr_name PP( (char *name, Type *type) ); + extern Expr *makeexpr_setbits PV(); + extern Expr *makeexpr_bicall_0 PP( (char *name, Type *type) ); + extern Expr *makeexpr_bicall_1 PP( (char *name, Type *type, Expr *arg1) ); + extern Expr *makeexpr_bicall_2 PP( (char *name, Type *type, Expr *arg1, + Expr *arg2) ); + extern Expr *makeexpr_bicall_3 PP( (char *name, Type *type, Expr *arg1, + Expr *arg2, Expr *arg3) ); + extern Expr *makeexpr_bicall_4 PP( (char *name, Type *type, Expr *arg1, + Expr *arg2, Expr *arg3, Expr *arg4) ); + extern Expr *makeexpr_bicall_5 PP( (char *name, Type *type, Expr *arg1, + Expr *arg2, Expr *arg3, Expr *arg4, + Expr *arg5) ); + extern Expr *copyexpr PP( (Expr *ex) ); + extern int exprsame PP( (Expr *a, Expr *b, int strict) ); + extern int exprequiv PP( (Expr *a, Expr *b) ); + extern void deletearg PP( (Expr **ex, int n) ); + extern void insertarg PP( (Expr **ex, int n, Expr *arg) ); + extern Expr *grabarg PP( (Expr *ex, int n) ); + extern void delsimparg PP( (Expr **ep, int n) ); + extern Expr *resimplify PP( (Expr *ex) ); + extern int realzero PP( (char *s) ); + extern int realint PP( (char *s, int i) ); + extern int checkconst PP( (Expr *ex, long val) ); + extern int isliteralconst PP( (Expr *ex, Value *valp) ); + extern int isconstexpr PP( (Expr *ex, long *valp) ); + extern int isconstantexpr PP( (Expr *ex) ); + extern Expr *makeexpr_actcast PP( (Expr *a, Type *type) ); + extern Expr *makeexpr_cast PP( (Expr *a, Type *type) ); + extern Expr *gentle_cast PP( (Expr *a, Type *type) ); + extern Expr *makeexpr_charcast PP( (Expr *ex) ); + extern Expr *makeexpr_stringcast PP( (Expr *ex) ); + extern int exprlongness PP( (Expr *ex) ); + extern Expr *makeexpr_longcast PP( (Expr *a, int tolong) ); + extern Expr *makeexpr_arglong PP( (Expr *a, int tolong) ); + extern Expr *makeexpr_unlongcast PP( (Expr *a) ); + extern Expr *makeexpr_forcelongness PP( (Expr *a) ); + extern Expr *makeexpr_ord PP( (Expr *ex) ); + extern int expr_looks_neg PP( (Expr *ex) ); + extern int expr_is_neg PP( (Expr *ex) ); + extern int expr_neg_cost PP( (Expr *a) ); + extern Expr *enum_to_int PP( (Expr *a) ); + extern Expr *neg_inside_sum PP( (Expr *a) ); + extern Expr *makeexpr_neg PP( (Expr *a) ); + extern Type *true_type PP( (Expr *ex) ); + extern int ischartype PP( (Expr *ex) ); + extern Expr *makeexpr_plus PP( (Expr *a, Expr *b) ); + extern Expr *makeexpr_minus PP( (Expr *a, Expr *b) ); + extern Expr *makeexpr_inc PP( (Expr *a, Expr *b) ); + extern Expr *distribute_plus PP( (Expr *ex) ); + extern Expr *makeexpr_times PP( (Expr *a, Expr *b) ); + extern Expr *makeexpr_sqr PP( (Expr *ex, int cube) ); + extern Expr *makeexpr_divide PP( (Expr *a, Expr *b) ); + extern int gcd PP( (int a, int b) ); + extern int negsigns PP( (int mask) ); + extern int possiblesigns PP( (Expr *ex) ); + extern Expr *dodivmod PP( (char *funcname, enum exprkind ekind, + Expr *a, Expr *b) ); + extern Expr *makeexpr_div PP( (Expr *a, Expr *b) ); + extern Expr *makeexpr_mod PP( (Expr *a, Expr *b) ); + extern Expr *makeexpr_rem PP( (Expr *a, Expr *b) ); + extern int expr_not_cost PP( (Expr *a) ); + extern Expr *makeexpr_not PP( (Expr *a) ); + extern Type *mixsets PP( (Expr **ep1, Expr **ep2) ); + extern Meaning *istempprocptr PP( (Expr *ex) ); + extern Expr *makeexpr_stringify PP( (Expr *ex) ); + extern Expr *makeexpr_rel PP( (enum exprkind rel, Expr *a, Expr *b) ); + extern Expr *makeexpr_and PP( (Expr *a, Expr *b) ); + extern Expr *makeexpr_or PP( (Expr *a, Expr *b) ); + extern Expr *makeexpr_range PP( (Expr *ex, Expr *exlow, Expr *exhigh, + int higheq) ); + extern Expr *makeexpr_cond PP( (Expr *c, Expr *a, Expr *b) ); + extern int expr_is_lvalue PP( (Expr *ex) ); + extern int expr_has_address PP( (Expr *ex) ); + extern Expr *checknil PP( (Expr *ex) ); + extern int checkvarinlists PP( (Strlist *yes, Strlist *no, int def, + Meaning *mp) ); + extern void requirefilebuffer PP( (Expr *ex) ); + extern Expr *makeexpr_hat PP( (Expr *a, int check) ); + extern Expr *un_sign_extend PP( (Expr *a) ); + extern Expr *makeexpr_addr PP( (Expr *a) ); + extern Expr *makeexpr_addrstr PP( (Expr *a) ); + extern Expr *makeexpr_addrf PP( (Expr *a) ); + extern Expr *makeexpr_index PP( (Expr *a, Expr *b, Expr *offset) ); + extern Expr *makeexpr_type PP( (Type *type) ); + extern Expr *makeexpr_sizeof PP( (Expr *ex, int incskipped) ); + extern int exprspeed PP( (Expr *ex) ); + extern int noargdependencies PP( (Expr *ex, int vars) ); + extern int nodependencies PP( (Expr *ex, int vars) ); + extern int exprdependsvar PP( (Expr *ex, Meaning *mp) ); + extern int exprdepends PP( (Expr *ex, Expr *ex2) ); + extern int nosideeffects_func PP( (Expr *ex) ); + extern int deterministic_func PP( (Expr *ex) ); + extern int noargsideeffects PP( (Expr *ex, int mode) ); + extern int nosideeffects PP( (Expr *ex, int mode) ); + extern int exproccurs PP( (Expr *ex, Expr *ex2) ); + extern Expr *singlevar PP( (Expr *ex) ); + extern int structuredfunc PP( (Expr *ex) ); + extern int strlapfunc PP( (Expr *ex) ); + extern Meaning *istempvar PP( (Expr *ex) ); + extern Meaning *totempvar PP( (Expr *ex) ); + extern Meaning *isretvar PP( (Expr *ex) ); + extern Expr *bumpstring PP( (Expr *ex, Expr *index, int offset) ); + extern long po2m1 PP( (int n) ); + extern int isarithkind PP( (enum exprkind kind) ); + extern Expr *makeexpr_assign PP( (Expr *a, Expr *b) ); + extern Expr *makeexpr_comma PP( (Expr *a, Expr *b) ); + extern int strmax PP( (Expr *ex) ); + extern int strhasnull PP( (Value val) ); + extern int istempsprintf PP( (Expr *ex) ); + extern Expr *makeexpr_sprintfify PP( (Expr *ex) ); + extern Expr *makeexpr_unsprintfify PP( (Expr *ex) ); + extern int sprintflength PP( (Expr *ex, int allownulls) ); + extern Expr *makeexpr_concat PP( (Expr *a, Expr *b, int usesprintf) ); + extern Expr *cleansprintf PP( (Expr *ex) ); + extern Expr *makeexpr_substring PP( (Expr *vex, Expr *ex, Expr *exi, + Expr *exj) ); + extern Expr *makeexpr_dot PP( (Expr *ex, Meaning *mp) ); + extern Expr *makeexpr_dotq PP( (Expr *ex, char *name, Type *type) ); + extern Expr *strmax_func PP( (Expr *ex) ); + extern Expr *makeexpr_nil PV(); + extern Expr *makeexpr_ctx PP( (Meaning *ctx) ); + extern Expr *force_signed PP( (Expr *ex) ); + extern Expr *force_unsigned PP( (Expr *ex) ); + extern long type_sizeof PP( (Type *type, int pasc) ); + extern Value eval_expr PP( (Expr *ex) ); + extern Value eval_expr_consts PP( (Expr *ex) ); + extern Value eval_expr_pasc PP( (Expr *ex) ); + extern int expr_is_const PP( (Expr *ex) ); + extern Expr *eatcasts PP( (Expr *ex) ); + + /* Declarations from pexpr.c */ + extern Expr *dots_n_hats PP( (Expr *ex, Type *target) ); + extern Expr *p_index PP( (Expr *ex, Expr *ex2) ); + extern Expr *fake_dots_n_hats PP( (Expr *ex) ); + extern void var_reference PP( (Meaning *mp) ); + extern Expr *p_ord_expr PV(); + extern Expr *packset PP( (Expr *ex, Type *type) ); + extern Expr *p_setfactor PP( (Type *target, int sure) ); + extern Expr *p_funcarglist PP( (Expr *ex, Meaning *args, int firstarg, + int ismacro) ); + extern Expr *replacemacargs PP( (Expr *ex, Expr *fex) ); + extern Expr *p_noarglist PP( (Expr *ex, Meaning *mp, Meaning *args) ); + extern void func_reference PP( (Meaning *func) ); + extern Expr *p_funccall PP( (Meaning *mp) ); + extern Expr *accumulate_strlit PV(); + extern Expr *pascaltypecast PP( (Type *type, Expr *ex2) ); + extern Expr *p_expr PP( (Type *target) ); + extern Type *nametotype PP( (char *name) ); + extern int istypespec PV(); + extern Expr *pc_parentype PP( (char *cp) ); + extern Expr *pc_factor PV(); + extern Expr *pc_expr2 PP( (int prec) ); + extern Expr *pc_expr PV(); + extern Expr *pc_expr_str PP( (char *buf) ); + extern Expr *fixexpr PP( (Expr *ex, int env) ); + extern void out_var PP( (Meaning *mp, int prec) ); + extern void out_field PP( (Meaning *mp) ); + extern void out_expr PP( (Expr *ex) ); + extern void out_expr_top PP( (Expr *ex) ); + extern void out_expr_factor PP( (Expr *ex) ); + extern void out_expr_parens PP( (Expr *ex) ); + extern void out_expr_stmt PP( (Expr *ex) ); + extern void out_expr_bool PP( (Expr *ex) ); + + /* Declarations from funcs.c */ + extern void setup_funcs PV(); + extern int isvar PP( (Expr *ex, Meaning *mp) ); + extern char *getstring PP( (Expr *ex) ); + extern Expr *p_parexpr PP( (Type *target) ); + extern Type *argbasetype PP( (Expr *ex) ); + extern Type *choosetype PP( (Type *t1, Type *t2) ); + extern Expr *convert_offset PP( (Type *type, Expr *ex2) ); + extern Expr *convert_size PP( (Type *type, Expr *ex, char *name) ); + extern Stmt *proc_assert PV(); + extern Stmt *wrapopencheck PP( (Stmt *sp, Expr *fex) ); + extern void parse_special_variant PP( (Type *tp, char *buf) ); + extern char *find_special_variant PP( (char *buf, char *spname, + Strlist *splist, int need) ); + extern int is_std_file PP( (Expr *ex) ); + extern Stmt *proc_exit PV(); + extern Stmt *doseek PP( (Expr *fex, Expr *ex) ); + extern Expr *writeelement PP( (Expr *ex, Expr *wid, Expr *prec, + int base) ); + extern void decl_builtins PV(); + + /* Declarations from dir.c */ + extern void init_dir PV(); + extern void setup_dir PV(); + extern void setup_module PP( (char *name, int defn) ); + extern void fix_parameters PV(); + extern Stmt *fix_statement PP( (Stmt *sp) ); + extern Expr *fix_expression PP( (Expr *ex, int env) ); + extern Expr *fix_bicall PP( (Expr *ex, int env) ); + extern int boolean_bicall PP( (char *name) ); + extern unsigned int safemask_bicall PP( (char *name) ); + extern int sideeffects_bicall PP( (char *name) ); + + /* Declarations from hpmods.c */ + extern void hpmods PP( (char *name, int defn) ); + + /* Declarations from citmods.c */ + extern void citmods PP( (char *name, int defn) ); + + + /* End. */ + Index: llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c/p2c.proto diff -c /dev/null llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c/p2c.proto:1.1.2.1 *** /dev/null Wed Mar 10 19:09:42 2004 --- llvm/test/Programs/MultiSource/Benchmarks/MallocBench/p2c/p2c.proto Wed Mar 10 19:09:31 2004 *************** *** 0 **** --- 1,426 ---- + + /* Declarations created by "makeproto" on Mon Feb 16 16:39:12 2004 */ + + + + /* Declarations from trans.c */ + #ifdef PROTO_TRANS_C + Static void initrc PV(); + Static int readrc PP( (char *rcname, int need) ); + Static void postrc PV(); + Static void openlogfile PV(); + #endif /*PROTO_TRANS_C*/ + + /* Declarations from stuff.c */ + #ifdef PROTO_STUFF_C + Static void cvcase PP( (char *buf, int flags) ); + #endif /*PROTO_STUFF_C*/ + + /* Declarations from out.c */ + #ifdef PROTO_OUT_C + Static void leading_tab PP( (int col) ); + Static void flush_outbuf PP( (int numbreaks, int *breakpos, + int *breakindent, int numedits, + int *editpos, char *editold, + char *editnew) ); + Static int readquotes PP( (int *posp, int err) ); + Static int readparens PP( (int *posp, int err) ); + Static int measurechars PP( (int first, int last) ); + Static void makeedit PP( (int pos, int ch) ); + Static void unedit PV(); + Static int parencount PP( (Paren *par) ); + Static int trybreakline PP( (int pos, int count, int indent, + double badness, int flags, Paren *parens) ); + #endif /*PROTO_OUT_C*/ + + /* Declarations from comment.c */ + #ifdef PROTO_COMMENT_C + Static void attach_mark PP( (Stmt *sp) ); + #endif /*PROTO_COMMENT_C*/ + + /* Declarations from lex.c */ + #ifdef PROTO_LEX_C + Static void makekeyword PP( (char *name) ); + Static void makeglobword PP( (char *name) ); + Static void makekeywords PV(); + Static Symbol *Pkeyword PP( (char *name, Token tok) ); + Static Symbol *Pkeywordposs PP( (char *name, Token tok) ); + Static void makePascalwords PV(); + Static void deterministic PP( (char *name) ); + Static void nosideeff PP( (char *name) ); + Static void recordsideeffects PV(); + Static void push_input PV(); + Static int parsecomment PP( (int p2c_only, int starparen) ); + Static void comment PP( (int starparen) ); + Static int getflag PV(); + #endif /*PROTO_LEX_C*/ + + /* Declarations from parse.c */ + #ifdef PROTO_PARSE_C + Static void forward_decl PP( (Meaning *func, int isextern) ); + Static Stmt *p_stmt PP( (Stmt *slist, int sflags) ); + Static int usebraces PP( (Stmt *sp, int opts) ); + Static void outnl PP( (int serial) ); + Static void out_block PP( (Stmt *spbase, int opts, int serial) ); + Static int checkreturns PP( (Stmt **spp, int nearret) ); + Static int isescape PP( (Expr *ex) ); + Static int deadendblock PP( (Stmt *sp) ); + Static int checkcomma_expr PP( (Stmt **spp, Expr **exp) ); + Static void checkcommas PP( (Stmt **spp) ); + Static int checkvarchangeable PP( (Expr *ex, Meaning *mp) ); + Static Stmt *p_body PV(); + Static void out_function PP( (Meaning *func) ); + Static void scanfwdparams PP( (Meaning *mp) ); + Static void p_function PP( (int isfunc) ); + Static void out_include PP( (char *name, int quoted) ); + Static void cleanheadername PP( (char *dest, char *name) ); + Static int tryimport PP( (Symbol *sym, char *fname, char *ext, + int need) ); + Static void p_import PP( (int inheader) ); + Static void skipunitheader PV(); + Static void skiptomodule PV(); + Static void p_moduleinit PP( (Meaning *mod) ); + Static void p_nested_module PV(); + Static int p_module PP( (int ignoreit, int isdefn) ); + #endif /*PROTO_PARSE_C*/ + + /* Declarations from decl.c */ + #ifdef PROTO_DECL_C + Static Meaning *findstandardmeaning PP( (enum meaningkind kind, char *name) ); + Static Meaning *makestandardmeaning PP( (enum meaningkind kind, char *name) ); + Static Type *makestandardtype PP( (enum typekind kind, Meaning *mp) ); + Static Stmt *nullspecialproc PP( (Meaning *mp) ); + Static Stmt *nullstandardproc PP( (Expr *ex) ); + Static Expr *nullspecialfunc PP( (Meaning *mp) ); + Static Expr *nullstandardfunc PP( (Expr *ex) ); + Static Expr *nullspecialvar PP( (Meaning *mp) ); + Static void initmeaning PP( (Meaning *mp) ); + Static void declare_args PP( (Type *type, int isheader, int isforward) ); + Static int checkstructconst PP( (Meaning *mp) ); + Static int mixable PP( (Meaning *mp1, Meaning *mp2, int args, + int flags) ); + Static int checkvarmacdef PP( (Expr *ex, Meaning *mp) ); + Static void fielddecl PP( (Meaning *mp, Type **type, Type **tp2, + long *val, int ispacked, int *aligned) ); + Static void realignfields PP( (Meaning *firstmp, Meaning *stopmp) ); + static void tryrealignfields PP( (Meaning *firstmp) ); + Static void p_fieldlist PP( (Type *tp, Meaning **flast, int ispacked, + Meaning *tname) ); + Static Type *p_arraydecl PP( (char *tname, int ispacked, + Meaning ***confp) ); + Static Type *p_conformant_array PP( (char *tname, Meaning ***confp) ); + Static void nameexternalvar PP( (Meaning *mp, char *name) ); + Static void handlebrackets PP( (Meaning *mp, int skip, int wasaliased) ); + Static void handleabsolute PP( (Meaning *mp, int skip) ); + #endif /*PROTO_DECL_C*/ + + /* Declarations from expr.c */ + #ifdef PROTO_EXPR_C + Static Expr *docast PP( (Expr *a, Type *type) ); + Static Expr *dolongcast PP( (Expr *a, int tolong) ); + Static Expr *commute PP( (Expr *a, Expr *b, enum exprkind kind) ); + Static Value eval_expr_either PP( (Expr *ex, int pasc) ); + #endif /*PROTO_EXPR_C*/ + + /* Declarations from pexpr.c */ + #ifdef PROTO_PEXPR_C + Static void bindnames PP( (Expr *ex) ); + Static Expr *p_variable PP( (Type *target) ); + Static Expr *makesmallsetconst PP( (long bits, Type *type) ); + Static Expr *p_factor PP( (Type *target) ); + Static Expr *p_powterm PP( (Type *target) ); + Static Expr *p_term PP( (Type *target) ); + Static Expr *p_sexpr PP( (Type *target) ); + Static int incompat PP( (Expr *ex, int num, int prec) ); + Static void outop3 PP( (int breakbefore, char *name) ); + Static void out_ctx PP( (Meaning *ctx, int address) ); + Static int scanfield PP( (Meaning **variants, short *unions, + int lev, Meaning *mp, Meaning *field) ); + Static void wrexpr PP( (Expr *ex, int prec) ); + #endif /*PROTO_PEXPR_C*/ + + /* Declarations from funcs.c */ + #ifdef PROTO_FUNCS_C + Static Expr *func_abs PV(); + Static Expr *func_addr PV(); + Static Expr *func_iaddress PV(); + Static Expr *func_addtopointer PV(); + Static Expr *checkfilename PP( (Expr *nex) ); + Static Stmt *assignfilename PP( (Expr *fex, Expr *nex) ); + Static Stmt *proc_assign PV(); + Static Stmt *handleopen PP( (int code) ); + Static Stmt *proc_append PV(); + Static Expr *func_arccos PP( (Expr *ex) ); + Static Expr *func_arcsin PP( (Expr *ex) ); + Static Expr *func_arctan PP( (Expr *ex) ); + Static Expr *func_arctanh PP( (Expr *ex) ); + Static Stmt *proc_argv PV(); + Static Expr *func_asr PV(); + Static Expr *func_lsl PV(); + Static Expr *func_lsr PV(); + Static Expr *func_bin PV(); + Static Expr *func_binary PP( (Expr *ex) ); + Static Expr *handle_bitsize PP( (int next) ); + Static Expr *func_bitsize PV(); + Static Expr *func_bitnext PV(); + Static Expr *func_blockread PV(); + Static Expr *func_blockwrite PV(); + Static Stmt *proc_blockread PV(); + Static Stmt *proc_blockwrite PV(); + Static Stmt *proc_bclr PV(); + Static Stmt *proc_bset PV(); + Static Expr *func_bsl PV(); + Static Expr *func_bsr PV(); + Static Expr *func_btst PV(); + Static Expr *func_byteread PV(); + Static Expr *func_bytewrite PV(); + Static Expr *func_byte_offset PV(); + Static Stmt *proc_call PV(); + Static Expr *func_chr PV(); + Static Stmt *proc_close PV(); + Static Expr *func_concat PV(); + Static Expr *func_copy PP( (Expr *ex) ); + Static Expr *func_cos PP( (Expr *ex) ); + Static Expr *func_cosh PP( (Expr *ex) ); + Static Stmt *proc_cycle PV(); + Static Stmt *proc_date PV(); + Static Stmt *proc_dec PV(); + Static Expr *func_dec PV(); + Static Stmt *proc_delete PP( (Expr *ex) ); + Static char *choose_free_func PP( (Expr *ex) ); + Static Stmt *proc_dispose PV(); + Static Expr *func_exp PP( (Expr *ex) ); + Static Expr *func_expo PP( (Expr *ex) ); + Static Expr *iofunc PP( (Expr *ex, int code) ); + Static Expr *func_eof PV(); + Static Expr *func_eoln PV(); + Static Stmt *proc_escape PV(); + Static Stmt *proc_excl PV(); + Static Expr *file_iofunc PP( (int code, long base) ); + Static Expr *func_fcall PV(); + Static Expr *func_filepos PV(); + Static Expr *func_filesize PV(); + Static Stmt *proc_fillchar PV(); + Static Expr *func_sngl PV(); + Static Expr *func_float PV(); + Static Stmt *proc_flush PV(); + Static Expr *func_frac PP( (Expr *ex) ); + Static Stmt *proc_freemem PP( (Expr *ex) ); + Static Stmt *proc_get PV(); + Static Stmt *proc_getmem PP( (Expr *ex) ); + Static Stmt *proc_gotoxy PP( (Expr *ex) ); + Static Expr *handle_vax_hex PP( (Expr *ex, char *fmt, int scale) ); + Static Expr *func_hex PV(); + Static Expr *func_hi PV(); + Static Expr *func_high PV(); + Static Expr *func_hiword PV(); + Static Stmt *proc_inc PV(); + Static Stmt *proc_incl PV(); + Static Stmt *proc_insert PP( (Expr *ex) ); + Static Expr *func_int PV(); + Static Expr *func_uint PV(); + Static Stmt *proc_leave PV(); + Static Expr *func_lo PV(); + Static Expr *func_loophole PV(); + Static Expr *func_lower PV(); + Static Expr *func_loword PV(); + Static Expr *func_ln PP( (Expr *ex) ); + Static Expr *func_log PP( (Expr *ex) ); + Static Expr *func_max PV(); + Static Expr *func_maxavail PP( (Expr *ex) ); + Static Expr *func_maxpos PV(); + Static Expr *func_memavail PP( (Expr *ex) ); + Static Expr *var_mem PV(); + Static Expr *var_memw PV(); + Static Expr *var_meml PV(); + Static Expr *func_min PV(); + Static Stmt *proc_move PP( (Expr *ex) ); + Static Stmt *proc_move_fast PV(); + Static Stmt *proc_new PV(); + Static Expr *func_oct PV(); + Static Expr *func_octal PP( (Expr *ex) ); + Static Expr *func_odd PP( (Expr *ex) ); + Static Stmt *proc_open PV(); + Static Expr *func_ord PV(); + Static Expr *func_ord4 PV(); + Static Stmt *proc_pack PV(); + Static Expr *func_pad PP( (Expr *ex) ); + Static Stmt *proc_page PV(); + Static Expr *func_paramcount PP( (Expr *ex) ); + Static Expr *func_paramstr PP( (Expr *ex) ); + Static Expr *func_pi PV(); + Static Expr *var_port PV(); + Static Expr *var_portw PV(); + Static Expr *func_pos PP( (Expr *ex) ); + Static Expr *func_ptr PP( (Expr *ex) ); + Static Expr *func_position PV(); + Static Expr *func_pred PV(); + Static Stmt *proc_put PV(); + Static Expr *func_pwroften PP( (Expr *ex) ); + Static Stmt *proc_reset PV(); + Static Stmt *proc_rewrite PV(); + Static Expr *makegetchar PP( (Expr *fex) ); + Static Stmt *fixscanf PP( (Stmt *sp, Expr *fex) ); + Static Expr *makefgets PP( (Expr *vex, Expr *lex, Expr *fex) ); + Static Stmt *skipeoln PP( (Expr *fex) ); + Static Stmt *handleread_text PP( (Expr *fex, Expr *var, int isreadln) ); + Static Stmt *handleread_bin PP( (Expr *fex, Expr *var) ); + Static Stmt *proc_read PV(); + Static Stmt *proc_readdir PV(); + Static Stmt *proc_readln PV(); + Static Stmt *proc_readv PV(); + Static Stmt *proc_strread PV(); + Static Expr *func_random PV(); + Static Stmt *proc_randomize PV(); + Static Expr *func_round PP( (Expr *ex) ); + Static Stmt *proc_unpack PV(); + Static Expr *func_uround PP( (Expr *ex) ); + Static Expr *func_scan PV(); + Static Expr *func_scaneq PP( (Expr *ex) ); + Static Expr *func_scanne PP( (Expr *ex) ); + Static Stmt *proc_seek PV(); + Static Expr *func_seekeof PV(); + Static Expr *func_seekeoln PV(); + Static Stmt *proc_setstrlen PV(); + Static Stmt *proc_settextbuf PV(); + Static Expr *func_sin PP( (Expr *ex) ); + Static Expr *func_sinh PP( (Expr *ex) ); + Static Expr *func_sizeof PV(); + Static Expr *func_statusv PV(); + Static Expr *func_str_hp PP( (Expr *ex) ); + Static Stmt *proc_strappend PV(); + Static Stmt *proc_strdelete PV(); + Static Stmt *proc_strinsert PV(); + Static Stmt *proc_strmove PV(); + Static Expr *func_strlen PP( (Expr *ex) ); + Static Expr *func_strltrim PP( (Expr *ex) ); + Static Expr *func_strmax PP( (Expr *ex) ); + Static Expr *func_strpos PP( (Expr *ex) ); + Static Expr *func_strrpt PP( (Expr *ex) ); + Static Expr *func_strrtrim PP( (Expr *ex) ); + Static Expr *func_succ PV(); + Static Expr *func_sqr PV(); + Static Expr *func_sqrt PP( (Expr *ex) ); + Static Expr *func_swap PP( (Expr *ex) ); + Static Expr *func_tan PP( (Expr *ex) ); + Static Expr *func_tanh PP( (Expr *ex) ); + Static Expr *func_trunc PP( (Expr *ex) ); + Static Expr *func_utrunc PP( (Expr *ex) ); + Static Expr *func_uand PV(); + Static Expr *func_udec PV(); + Static Expr *func_unot PV(); + Static Expr *func_uor PV(); + Static Expr *func_upcase PP( (Expr *ex) ); + Static Expr *func_upper PV(); + Static Expr *func_uxor PV(); + Static Expr *func_val_modula PV(); + Static Stmt *proc_val_turbo PV(); + Static Expr *writestrelement PP( (Expr *ex, Expr *wid, Expr *vex, int code, + int needboth) ); + Static char *makeenumnames PP( (Type *tp) ); + Static Stmt *handlewrite_text PP( (Expr *fex, Expr *ex, int iswriteln) ); + Static Stmt *handlewrite_bin PP( (Expr *fex, Expr *ex) ); + Static Stmt *proc_write PV(); + Static Stmt *handle_modula_write PP( (char *fmt) ); + Static Stmt *proc_writecard PV(); + Static Stmt *proc_writeint PV(); + Static Stmt *proc_writehex PV(); + Static Stmt *proc_writeoct PV(); + Static Stmt *proc_writereal PV(); + Static Stmt *proc_writedir PV(); + Static Stmt *handlewriteln PP( (int iswriteln) ); + Static Stmt *proc_overprint PV(); + Static Stmt *proc_prompt PV(); + Static Stmt *proc_writeln PV(); + Static Stmt *proc_message PV(); + Static Stmt *proc_writev PV(); + Static Stmt *proc_strwrite PP( (Meaning *mp_x, Stmt *spbase) ); + Static Stmt *proc_str_turbo PV(); + Static Stmt *proc_time PV(); + Static Expr *func_xor PV(); + #endif /*PROTO_FUNCS_C*/ + + /* Declarations from dir.c */ + #ifdef PROTO_DIR_C + Static void _setup PP( (char *name, int defn) ); + #endif /*PROTO_DIR_C*/ + + /* Declarations from hpmods.c */ + #ifdef PROTO_HPMODS_C + Static Stmt *proc_freadbytes PV(); + Static Stmt *proc_fwritebytes PV(); + Static void setup_sysglobals PV(); + #endif /*PROTO_HPMODS_C*/ + + /* Declarations from citmods.c */ + #ifdef PROTO_CITMODS_C + Static Stmt *proc_na_fillbyte PP( (Expr *ex) ); + Static Stmt *proc_na_fill PP( (Expr *ex) ); + Static Stmt *proc_na_move PP( (Expr *ex) ); + Static Stmt *proc_na_exch PP( (Expr *ex) ); + Static Expr *func_na_comp PP( (Expr *ex) ); + Static Expr *func_na_scaneq PP( (Expr *ex) ); + Static Expr *func_na_scanne PP( (Expr *ex) ); + Static Stmt *proc_na_new PP( (Expr *ex) ); + Static Stmt *proc_na_dispose PP( (Expr *ex) ); + Static Stmt *proc_na_alloc PP( (Expr *ex) ); + Static Stmt *proc_na_outeralloc PP( (Expr *ex) ); + Static Stmt *proc_na_free PP( (Expr *ex) ); + Static Expr *func_na_memavail PP( (Expr *ex) ); + Static Expr *func_na_and PP( (Expr *ex) ); + Static Expr *func_na_bic PP( (Expr *ex) ); + Static Expr *func_na_or PP( (Expr *ex) ); + Static Expr *func_na_xor PP( (Expr *ex) ); + Static Expr *func_na_not PP( (Expr *ex) ); + Static Expr *func_na_mask PP( (Expr *ex) ); + Static int check0_31 PP( (Expr *ex) ); + Static Expr *func_na_test PP( (Expr *ex) ); + Static Stmt *proc_na_set PP( (Expr *ex) ); + Static Stmt *proc_na_clear PP( (Expr *ex) ); + Static Expr *func_na_po2 PP( (Expr *ex) ); + Static Expr *func_na_lobits PP( (Expr *ex) ); + Static Expr *func_na_hibits PP( (Expr *ex) ); + Static Expr *func_na_asl PP( (Expr *ex) ); + Static Expr *func_na_lsl PP( (Expr *ex) ); + Static Stmt *proc_na_bfand PP( (Expr *ex) ); + Static Stmt *proc_na_bfbic PP( (Expr *ex) ); + Static Stmt *proc_na_bfor PP( (Expr *ex) ); + Static Stmt *proc_na_bfxor PP( (Expr *ex) ); + Static Expr *func_imin PP( (Expr *ex) ); + Static Expr *func_imax PP( (Expr *ex) ); + Static Expr *func_na_add PP( (Expr *ex) ); + Static Expr *func_na_sub PP( (Expr *ex) ); + Static Stmt *proc_return PV(); + Static Expr *func_charupper PP( (Expr *ex) ); + Static Expr *func_charlower PP( (Expr *ex) ); + Static Expr *func_strint PP( (Expr *ex) ); + Static Expr *func_strint2 PP( (Expr *ex) ); + Static Expr *func_strhex PP( (Expr *ex) ); + Static Expr *func_strreal PP( (Expr *ex) ); + Static Expr *func_strchar PP( (Expr *ex) ); + Static Expr *func_strreadint PP( (Expr *ex) ); + Static Expr *func_strreadreal PP( (Expr *ex) ); + Static Stmt *proc_strappendc PP( (Expr *ex) ); + Static Expr *func_strbegins PP( (Expr *ex) ); + Static Expr *func_strcontains PP( (Expr *ex) ); + Static Expr *func_strsub PP( (Expr *ex) ); + Static Expr *func_strpart PP( (Expr *ex) ); + Static Expr *func_strequal PP( (Expr *ex) ); + Static Expr *func_strcmp PP( (Expr *ex) ); + Static Expr *func_strljust PP( (Expr *ex) ); + Static Expr *func_strrjust PP( (Expr *ex) ); + Static Stmt *proc_strnew PP( (Expr *ex) ); + Static Stmt *proc_strlist_add PP( (Expr *ex) ); + Static Stmt *proc_strlist_append PP( (Expr *ex) ); + Static Stmt *proc_strlist_insert PP( (Expr *ex) ); + Static Stmt *proc_fixfname PP( (Expr *ex) ); + Static Stmt *proc_forcefname PP( (Expr *ex) ); + Static Expr *func_stdin PV(); + Static Expr *func_stdout PV(); + Static Expr *func_stderr PV(); + Static Stmt *proc_m_color PP( (Expr *ex) ); + #endif /*PROTO_CITMODS_C*/ + + + /* End. */ + From brukman at cs.uiuc.edu Wed Mar 10 19:10:50 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:50 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/External/SPEC/Makefile.spec Message-ID: <200403110109.TAA07820@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC: Makefile.spec updated: 1.21.2.1 -> 1.21.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+2 -0) Index: llvm/test/Programs/External/SPEC/Makefile.spec diff -u llvm/test/Programs/External/SPEC/Makefile.spec:1.21.2.1 llvm/test/Programs/External/SPEC/Makefile.spec:1.21.2.2 --- llvm/test/Programs/External/SPEC/Makefile.spec:1.21.2.1 Mon Mar 1 17:59:09 2004 +++ llvm/test/Programs/External/SPEC/Makefile.spec Wed Mar 10 19:09:31 2004 @@ -24,7 +24,9 @@ BENCH_NAME := $(patsubst /%,%,$(BENCH_NAME)) SPEC_SUBDIR := $(patsubst /%,%,$(SPEC_SUBDIR)) +ifndef SPEC_BENCH_DIR SPEC_BENCH_DIR := $(SPEC_ROOT)/$(SPEC_SUBDIR) +endif PROG := $(BENCH_NAME) ifndef Source From brukman at cs.uiuc.edu Wed Mar 10 19:10:56 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:10:56 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/MultiSource/Benchmarks/FreeBench/distray/ref.in Message-ID: <200403110109.TAA07885@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/FreeBench/distray: ref.in updated: 1.1 -> 1.1.6.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/MultiSource/Benchmarks/FreeBench/distray/ref.in diff -u llvm/test/Programs/MultiSource/Benchmarks/FreeBench/distray/ref.in:1.1 llvm/test/Programs/MultiSource/Benchmarks/FreeBench/distray/ref.in:1.1.6.1 --- llvm/test/Programs/MultiSource/Benchmarks/FreeBench/distray/ref.in:1.1 Sat Oct 11 16:18:47 2003 +++ llvm/test/Programs/MultiSource/Benchmarks/FreeBench/distray/ref.in Wed Mar 10 19:09:31 2004 @@ -1 +1 @@ -6 +5 From brukman at cs.uiuc.edu Wed Mar 10 19:11:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:11:02 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/MultiSource/Applications/Makefile Message-ID: <200403110109.TAA07869@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Applications: Makefile updated: 1.4 -> 1.4.2.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+1 -4) Index: llvm/test/Programs/MultiSource/Applications/Makefile diff -u llvm/test/Programs/MultiSource/Applications/Makefile:1.4 llvm/test/Programs/MultiSource/Applications/Makefile:1.4.2.1 --- llvm/test/Programs/MultiSource/Applications/Makefile:1.4 Thu Jan 1 11:14:25 2004 +++ llvm/test/Programs/MultiSource/Applications/Makefile Wed Mar 10 19:09:31 2004 @@ -4,9 +4,6 @@ include $(LEVEL)/Makefile.config -PARALLEL_DIRS = Burg aha sgefa siod lambda-0.1.3 -ifeq ($(OS),Linux) -PARALLEL_DIRS += d -endif +PARALLEL_DIRS = Burg aha sgefa siod lambda-0.1.3 d include $(LEVEL)/test/Programs/Makefile.programs From brukman at cs.uiuc.edu Wed Mar 10 19:11:08 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:11:08 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/MultiSource/Benchmarks/Olden/health/health.c Message-ID: <200403110109.TAA07895@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/Olden/health: health.c updated: 1.12 -> 1.12.14.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+1 -1) Index: llvm/test/Programs/MultiSource/Benchmarks/Olden/health/health.c diff -u llvm/test/Programs/MultiSource/Benchmarks/Olden/health/health.c:1.12 llvm/test/Programs/MultiSource/Benchmarks/Olden/health/health.c:1.12.14.1 --- llvm/test/Programs/MultiSource/Benchmarks/Olden/health/health.c:1.12 Sun Apr 7 00:57:31 2002 +++ llvm/test/Programs/MultiSource/Benchmarks/Olden/health/health.c Wed Mar 10 19:09:31 2004 @@ -241,7 +241,7 @@ chatting("Done.\n\n"); chatting("# of people treated: %f people\n", total_patients); - chatting("Average length of stay: %f time units\n", + chatting("Average length of stay: %0.2f time units\n", total_time / total_patients); chatting("Average # of hospitals visited: %f hospitals\n\n", total_hosps / total_patients); From brukman at cs.uiuc.edu Wed Mar 10 19:11:14 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:11:14 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/Makefile llubenchmark.c Message-ID: <200403110109.TAA07909@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/llubenchmark: Makefile updated: 1.2 -> 1.2.6.1 llubenchmark.c updated: 1.1 -> 1.1.14.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+3 -1) Index: llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/Makefile diff -u llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/Makefile:1.2 llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/Makefile:1.2.6.1 --- llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/Makefile:1.2 Fri Sep 12 11:02:42 2003 +++ llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/Makefile Wed Mar 10 19:09:32 2004 @@ -4,4 +4,6 @@ CPPFLAGS = LDFLAGS = +RUN_OPTIONS = -i 3000 + include ../../Makefile.multisrc Index: llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/llubenchmark.c diff -u llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/llubenchmark.c:1.1 llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/llubenchmark.c:1.1.14.1 --- llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/llubenchmark.c:1.1 Thu May 8 22:49:51 2003 +++ llvm/test/Programs/MultiSource/Benchmarks/llubenchmark/llubenchmark.c Wed Mar 10 19:09:32 2004 @@ -63,7 +63,7 @@ int element_size = 32; int num_allocated = 0; -#if 1 +#if 0 struct element * allocate() { if (next_free == ALLOC_SIZE) { From brukman at cs.uiuc.edu Wed Mar 10 19:11:21 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:11:21 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Programs/SingleSource/UnitTests/SetjmpLongjmp/C/Makefile Message-ID: <200403110109.TAA07914@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/UnitTests/SetjmpLongjmp/C: Makefile updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+1 -0) Index: llvm/test/Programs/SingleSource/UnitTests/SetjmpLongjmp/C/Makefile diff -u llvm/test/Programs/SingleSource/UnitTests/SetjmpLongjmp/C/Makefile:1.1.2.1 llvm/test/Programs/SingleSource/UnitTests/SetjmpLongjmp/C/Makefile:1.1.2.2 --- llvm/test/Programs/SingleSource/UnitTests/SetjmpLongjmp/C/Makefile:1.1.2.1 Mon Mar 1 17:59:14 2004 +++ llvm/test/Programs/SingleSource/UnitTests/SetjmpLongjmp/C/Makefile Wed Mar 10 19:09:32 2004 @@ -1,5 +1,6 @@ # Programs/SingleSource/UnitTests/SetjmpLongjmp/Makefile LEVEL = ../../../../../.. +REQUIRES_EH_SUPPORT = 1 include $(LEVEL)/test/Programs/SingleSource/Makefile.singlesrc From brukman at cs.uiuc.edu Wed Mar 10 19:22:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:22:02 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/Argument.h Constant.h Module.h Pass.h Type.h Message-ID: <200403110121.TAA08004@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Argument.h updated: 1.7 -> 1.7.4.1 Constant.h updated: 1.12 -> 1.12.4.1 Module.h updated: 1.40 -> 1.40.2.1 Pass.h updated: 1.42 -> 1.42.4.1 Type.h updated: 1.37.4.1 -> 1.37.4.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+10 -12) Index: llvm/include/llvm/Argument.h diff -u llvm/include/llvm/Argument.h:1.7 llvm/include/llvm/Argument.h:1.7.4.1 --- llvm/include/llvm/Argument.h:1.7 Tue Nov 11 16:41:29 2003 +++ llvm/include/llvm/Argument.h Wed Mar 10 19:20:50 2004 @@ -19,6 +19,10 @@ namespace llvm { +template struct ilist_traits; +template class SymbolTableListTraits; + class Argument : public Value { // Defined in the Function.cpp file Function *Parent; Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.12 llvm/include/llvm/Constant.h:1.12.4.1 --- llvm/include/llvm/Constant.h:1.12 Tue Nov 11 16:41:29 2003 +++ llvm/include/llvm/Constant.h Wed Mar 10 19:20:50 2004 @@ -85,12 +85,6 @@ "implemented for all constants that have operands!"); assert(0 && "Constants that do not have operands cannot be using 'From'!"); } - - // WARNING: Only to be used by Bytecode & Assembly Parsers! USER CODE SHOULD - // NOT USE THIS!! - // Returns the number of uses of OldV that were replaced. - unsigned mutateReferences(Value* OldV, Value *NewV); - // END WARNING!! }; } // End llvm namespace Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.40 llvm/include/llvm/Module.h:1.40.2.1 --- llvm/include/llvm/Module.h:1.40 Wed Dec 31 02:42:27 2003 +++ llvm/include/llvm/Module.h Wed Mar 10 19:20:50 2004 @@ -77,7 +77,6 @@ // Accessor for the underlying GVRefMap... only through the Constant class... friend class Constant; friend class ConstantPointerRef; - void mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV); ConstantPointerRef *getConstantPointerRef(GlobalValue *GV); void destroyConstantPointerRef(ConstantPointerRef *CPR); Index: llvm/include/llvm/Pass.h diff -u llvm/include/llvm/Pass.h:1.42 llvm/include/llvm/Pass.h:1.42.4.1 --- llvm/include/llvm/Pass.h:1.42 Tue Nov 11 16:41:30 2003 +++ llvm/include/llvm/Pass.h Wed Mar 10 19:20:50 2004 @@ -29,11 +29,12 @@ #ifndef LLVM_PASS_H #define LLVM_PASS_H -#include -#include +#include #include +#include +#include #include -#include +#include namespace llvm { Index: llvm/include/llvm/Type.h diff -u llvm/include/llvm/Type.h:1.37.4.1 llvm/include/llvm/Type.h:1.37.4.2 --- llvm/include/llvm/Type.h:1.37.4.1 Mon Mar 1 17:57:19 2004 +++ llvm/include/llvm/Type.h Wed Mar 10 19:20:50 2004 @@ -206,8 +206,8 @@ ID != FunctionTyID && ID != LabelTyID && ID != OpaqueTyID; } - /// getPrimitiveSize - Return the basic size of this type if it is a primative - /// type. These are fixed by LLVM and are not target dependent. This will + /// getPrimitiveSize - Return the basic size of this type if it is a primitive + /// type. These are fixed by LLVM and are not target-dependent. This will /// return zero if the type does not have a size or is not a primitive type. /// unsigned getPrimitiveSize() const; From brukman at cs.uiuc.edu Wed Mar 10 19:23:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:23:00 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/Analysis/Trace.h DSGraph.h ProfileInfo.h ProfileInfoLoader.h Message-ID: <200403110122.TAA08035@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Trace.h added (r1.2.2.1) DSGraph.h updated: 1.64.4.1 -> 1.64.4.2 ProfileInfo.h updated: 1.2.2.1 -> 1.2.2.2 ProfileInfoLoader.h updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+172 -26) Index: llvm/include/llvm/Analysis/Trace.h diff -c /dev/null llvm/include/llvm/Analysis/Trace.h:1.2.2.1 *** /dev/null Wed Mar 10 19:22:15 2004 --- llvm/include/llvm/Analysis/Trace.h Wed Mar 10 19:22:05 2004 *************** *** 0 **** --- 1,116 ---- + //===- llvm/Analysis/Trace.h - Represent one trace of LLVM code -*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This class represents a single trace of LLVM basic blocks. A trace is a + // single entry, multiple exit, region of code that is often hot. Trace-based + // optimizations treat traces almost like they are a large, strange, basic + // block: because the trace path is assumed to be hot, optimizations for the + // fall-through path are made at the expense of the non-fall-through paths. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_ANALYSIS_TRACE_H + #define LLVM_ANALYSIS_TRACE_H + + #include + #include + #include + + namespace llvm { + class BasicBlock; + class Function; + class Module; + + class Trace { + typedef std::vector BasicBlockListType; + BasicBlockListType BasicBlocks; + + public: + /// Trace ctor - Make a new trace from a vector of basic blocks, + /// residing in the function which is the parent of the first + /// basic block in the vector. + /// + Trace(const std::vector &vBB) : BasicBlocks (vBB) {} + + /// getEntryBasicBlock - Return the entry basic block (first block) + /// of the trace. + /// + BasicBlock *getEntryBasicBlock () const { return BasicBlocks[0]; } + + /// operator[]/getBlock - Return basic block N in the trace. + /// + BasicBlock *operator[](unsigned i) const { return BasicBlocks[i]; } + BasicBlock *getBlock(unsigned i) const { return BasicBlocks[i]; } + + /// getFunction - Return this trace's parent function. + /// + Function *getFunction () const; + + /// getModule - Return this Module that contains this trace's parent + /// function. + /// + Module *getModule () const; + + /// getBlockIndex - Return the index of the specified basic block in the + /// trace, or -1 if it is not in the trace. + int getBlockIndex(const BasicBlock *X) const { + for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) + if (BasicBlocks[i] == X) + return i; + return -1; + } + + /// contains - Returns true if this trace contains the given basic + /// block. + /// + bool contains(const BasicBlock *X) const { + return getBlockIndex(X) != -1; + } + + /// Returns true if B1 occurs before B2 in the trace, or if it is the same + /// block as B2.. Both blocks must be in the trace. + /// + bool dominates(const BasicBlock *B1, const BasicBlock *B2) const { + int B1Idx = getBlockIndex(B1), B2Idx = getBlockIndex(B2); + assert(B1Idx != -1 && B2Idx != -1 && "Block is not in the trace!"); + return B1Idx <= B2Idx; + } + + // BasicBlock iterators... + typedef BasicBlockListType::iterator iterator; + typedef BasicBlockListType::const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + iterator begin() { return BasicBlocks.begin(); } + const_iterator begin() const { return BasicBlocks.begin(); } + iterator end () { return BasicBlocks.end(); } + const_iterator end () const { return BasicBlocks.end(); } + + reverse_iterator rbegin() { return BasicBlocks.rbegin(); } + const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); } + reverse_iterator rend () { return BasicBlocks.rend(); } + const_reverse_iterator rend () const { return BasicBlocks.rend(); } + + unsigned size() const { return BasicBlocks.size(); } + bool empty() const { return BasicBlocks.empty(); } + + /// print - Write trace to output stream. + /// + void print (std::ostream &O) const; + + /// dump - Debugger convenience method; writes trace to standard error + /// output stream. + /// + void dump () const; + }; + + } // end namespace llvm + + #endif // TRACE_H Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.64.4.1 llvm/include/llvm/Analysis/DSGraph.h:1.64.4.2 --- llvm/include/llvm/Analysis/DSGraph.h:1.64.4.1 Mon Mar 1 17:57:19 2004 +++ llvm/include/llvm/Analysis/DSGraph.h Wed Mar 10 19:22:05 2004 @@ -360,6 +360,10 @@ /// DSCallSite getCallSiteForArguments(Function &F) const; + /// getDSCallSiteForCallSite - Given an LLVM CallSite object that is live in + /// the context of this graph, return the DSCallSite for it. + DSCallSite getDSCallSiteForCallSite(CallSite CS) const; + // Methods for checking to make sure graphs are well formed... void AssertNodeInGraph(const DSNode *N) const { assert((!N || N->getParentGraph() == this) && @@ -370,22 +374,9 @@ N->getGlobals().end() && "Global value not in node!"); } - void AssertCallSiteInGraph(const DSCallSite &CS) const { - if (CS.isIndirectCall()) - AssertNodeInGraph(CS.getCalleeNode()); - AssertNodeInGraph(CS.getRetVal().getNode()); - for (unsigned j = 0, e = CS.getNumPtrArgs(); j != e; ++j) - AssertNodeInGraph(CS.getPtrArg(j).getNode()); - } - - void AssertCallNodesInGraph() const { - for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) - AssertCallSiteInGraph(FunctionCalls[i]); - } - void AssertAuxCallNodesInGraph() const { - for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i) - AssertCallSiteInGraph(AuxFunctionCalls[i]); - } + void AssertCallSiteInGraph(const DSCallSite &CS) const; + void AssertCallNodesInGraph() const; + void AssertAuxCallNodesInGraph() const; void AssertGraphOK() const; @@ -436,7 +427,13 @@ /// site into the nodes reachable from DestCS. void mergeCallSite(const DSCallSite &DestCS, const DSCallSite &SrcCS); - bool clonedNode() const { return !NodeMap.empty(); } + bool clonedAnyNodes() const { return !NodeMap.empty(); } + + /// hasClonedNode - Return true if the specified node has been cloned from + /// the source graph into the destination graph. + bool hasClonedNode(const DSNode *N) { + return NodeMap.count(N); + } void destroy() { NodeMap.clear(); } }; Index: llvm/include/llvm/Analysis/ProfileInfo.h diff -u llvm/include/llvm/Analysis/ProfileInfo.h:1.2.2.1 llvm/include/llvm/Analysis/ProfileInfo.h:1.2.2.2 --- llvm/include/llvm/Analysis/ProfileInfo.h:1.2.2.1 Mon Mar 1 17:57:19 2004 +++ llvm/include/llvm/Analysis/ProfileInfo.h Wed Mar 10 19:22:05 2004 @@ -22,30 +22,45 @@ #define LLVM_ANALYSIS_PROFILEINFO_H #include +#include namespace llvm { class BasicBlock; class Pass; - /// createProfileLoaderPass - This function returns a Pass that loads the - /// profiling information for the module from the specified filename, making - /// it available to the optimizers. - Pass *createProfileLoaderPass(const std::string &Filename); - - struct ProfileInfo { + /// ProfileInfo Class - This class holds and maintains edge profiling + /// information for some unit of code. + class ProfileInfo { + protected: + // EdgeCounts - Count the number of times a transition between two blocks is + // executed. As a special case, we also hold an edge from the null + // BasicBlock to the entry block to indicate how many times the function was + // entered. + std::map, unsigned> EdgeCounts; + public: virtual ~ProfileInfo(); // We want to be subclassed //===------------------------------------------------------------------===// /// Profile Information Queries /// - virtual unsigned getExecutionCount(BasicBlock *BB) = 0; - + unsigned getExecutionCount(BasicBlock *BB) const; + + unsigned getEdgeWeight(BasicBlock *Src, BasicBlock *Dest) const { + std::map, unsigned>::const_iterator I= + EdgeCounts.find(std::make_pair(Src, Dest)); + return I != EdgeCounts.end() ? I->second : 0; + } + //===------------------------------------------------------------------===// /// Analysis Update Methods /// }; + /// createProfileLoaderPass - This function returns a Pass that loads the + /// profiling information for the module from the specified filename, making + /// it available to the optimizers. + Pass *createProfileLoaderPass(const std::string &Filename); } // End llvm namespace #endif Index: llvm/include/llvm/Analysis/ProfileInfoLoader.h diff -u llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.1.2.1 llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.1.2.2 --- llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.1.2.1 Mon Mar 1 17:57:19 2004 +++ llvm/include/llvm/Analysis/ProfileInfoLoader.h Wed Mar 10 19:22:05 2004 @@ -31,6 +31,7 @@ std::vector CommandLines; std::vector FunctionCounts; std::vector BlockCounts; + std::vector EdgeCounts; public: // ProfileInfoLoader ctor - Read the specified profiling data file, exiting // the program if the file is invalid or broken. @@ -50,7 +51,14 @@ // frequency information from whatever we have. // bool hasAccurateBlockCounts() const { - return !BlockCounts.empty(); + return !BlockCounts.empty() || !EdgeCounts.empty(); + } + + // hasAccurateEdgeCounts - Return true if we can synthesize accurate edge + // frequency information from whatever we have. + // + bool hasAccurateEdgeCounts() const { + return !EdgeCounts.empty(); } // getBlockCounts - This method is used by consumers of block counting @@ -58,6 +66,16 @@ // compute it from other, more refined, types of profile information. // void getBlockCounts(std::vector > &Counts); + + // getEdgeCounts - This method is used by consumers of edge counting + // information. If we do not directly have edge count information, we compute + // it from other, more refined, types of profile information. + // + // Edges are represented as a pair, where the first element is the basic block + // and the second element is the successor number. + // + typedef std::pair Edge; + void getEdgeCounts(std::vector > &Counts); }; } // End llvm namespace From brukman at cs.uiuc.edu Wed Mar 10 19:23:06 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:23:06 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/Assembly/AsmAnnotationWriter.h Message-ID: <200403110122.TAA08055@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Assembly: AsmAnnotationWriter.h updated: 1.2 -> 1.2.4.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+9 -3) Index: llvm/include/llvm/Assembly/AsmAnnotationWriter.h diff -u llvm/include/llvm/Assembly/AsmAnnotationWriter.h:1.2 llvm/include/llvm/Assembly/AsmAnnotationWriter.h:1.2.4.1 --- llvm/include/llvm/Assembly/AsmAnnotationWriter.h:1.2 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Assembly/AsmAnnotationWriter.h Wed Mar 10 19:22:24 2004 @@ -31,9 +31,15 @@ // the start of a function. virtual void emitFunctionAnnot(const Function *F, std::ostream &OS) {} - // emitBasicBlockAnnot - This may be implemented to emit a string right after - // the basic block label, but before the first instruction in the block. - virtual void emitBasicBlockAnnot(const BasicBlock *BB, std::ostream &OS) {} + // emitBasicBlockStartAnnot - This may be implemented to emit a string right + // after the basic block label, but before the first instruction in the block. + virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, std::ostream &OS){ + } + + // emitBasicBlockEndAnnot - This may be implemented to emit a string right + // after the basic block. + virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, std::ostream &OS){ + } // emitInstructionAnnot - This may be implemented to emit a string right // before an instruction is emitted. From brukman at cs.uiuc.edu Wed Mar 10 19:24:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:24:00 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/Target/TargetMachine.h TargetMachineImpls.h Message-ID: <200403110123.TAA08083@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.42.2.1 -> 1.42.2.2 TargetMachineImpls.h updated: 1.8.2.1 -> 1.8.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+10 -0) Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.42.2.1 llvm/include/llvm/Target/TargetMachine.h:1.42.2.2 --- llvm/include/llvm/Target/TargetMachine.h:1.42.2.1 Mon Mar 1 17:57:19 2004 +++ llvm/include/llvm/Target/TargetMachine.h Wed Mar 10 19:23:07 2004 @@ -52,6 +52,12 @@ unsigned char DoubleAl = 8, unsigned char FloatAl = 4, unsigned char LongAl = 8, unsigned char IntAl = 4, unsigned char ShortAl = 2, unsigned char ByteAl = 1); + + // This constructor is used for targets that support arbitrary TargetData + // layouts, like the C backend. It initializes the TargetData to match that + // of the specified module. + TargetMachine(const std::string &name, IntrinsicLowering *IL, + const Module &M); public: virtual ~TargetMachine(); Index: llvm/include/llvm/Target/TargetMachineImpls.h diff -u llvm/include/llvm/Target/TargetMachineImpls.h:1.8.2.1 llvm/include/llvm/Target/TargetMachineImpls.h:1.8.2.2 --- llvm/include/llvm/Target/TargetMachineImpls.h:1.8.2.1 Mon Mar 1 17:57:19 2004 +++ llvm/include/llvm/Target/TargetMachineImpls.h Wed Mar 10 19:23:07 2004 @@ -16,6 +16,10 @@ #define LLVM_TARGET_TARGETMACHINEIMPLS_H namespace llvm { + /// Command line options shared between TargetMachine implementations - + /// these should go in their own header eventually. + /// + extern bool PrintMachineCode; class TargetMachine; class Module; From brukman at cs.uiuc.edu Wed Mar 10 19:24:06 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:24:06 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200403110123.TAA08096@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.118.2.1 -> 1.118.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+100 -64) Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.118.2.1 llvm/include/llvm/CodeGen/MachineInstr.h:1.118.2.2 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.118.2.1 Mon Mar 1 17:57:19 2004 +++ llvm/include/llvm/CodeGen/MachineInstr.h Wed Mar 10 19:23:34 2004 @@ -110,71 +110,81 @@ private: union { - Value* value; // BasicBlockVal for a label operand. - // ConstantVal for a non-address immediate. - // Virtual register for an SSA operand, - // including hidden operands required for - // the generated machine code. - // LLVM global for MO_GlobalAddress. + Value* value; // BasicBlockVal for a label operand. + // ConstantVal for a non-address immediate. + // Virtual register for an SSA operand, + // including hidden operands required for + // the generated machine code. + // LLVM global for MO_GlobalAddress. int immedVal; // Constant value for an explicit constant MachineBasicBlock *MBB; // For MO_MachineBasicBlock type std::string *SymbolName; // For MO_ExternalSymbol type - }; + } contents; char flags; // see bit field definitions above MachineOperandType opType:8; // Pack into 8 bits efficiently after flags. int regNum; // register number for an explicit register // will be set for a value after reg allocation private: + void zeroContents () { + memset (&contents, 0, sizeof (contents)); + } + MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister) - : immedVal(ImmVal), - flags(0), - opType(OpTy), - regNum(-1) {} + : flags(0), opType(OpTy), regNum(-1) { + zeroContents (); + contents.immedVal = ImmVal; + } MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy) - : immedVal(0), flags(UseTy), opType(OpTy), regNum(Reg) { } + : flags(UseTy), opType(OpTy), regNum(Reg) { + zeroContents (); + } MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy, bool isPCRelative = false) - : value(V), - flags(UseTy | (isPCRelative ? PCRELATIVE : 0)), - opType(OpTy), - regNum(-1) { + : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy), regNum(-1) { + zeroContents (); + contents.value = V; } MachineOperand(MachineBasicBlock *mbb) - : MBB(mbb), flags(0), opType(MO_MachineBasicBlock), regNum(-1) { } + : flags(0), opType(MO_MachineBasicBlock), regNum(-1) { + zeroContents (); + contents.MBB = mbb; + } MachineOperand(const std::string &SymName, bool isPCRelative) - : SymbolName(new std::string(SymName)), flags(isPCRelative ? PCRELATIVE :0), - opType(MO_ExternalSymbol), regNum(-1) {} + : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol), regNum(-1) { + zeroContents (); + contents.SymbolName = new std::string (SymName); + } public: - MachineOperand(const MachineOperand &M) : immedVal(M.immedVal), - flags(M.flags), - opType(M.opType), - regNum(M.regNum) { + MachineOperand(const MachineOperand &M) + : flags(M.flags), opType(M.opType), regNum(M.regNum) { + zeroContents (); + contents = M.contents; if (isExternalSymbol()) - SymbolName = new std::string(M.getSymbolName()); + contents.SymbolName = new std::string(M.getSymbolName()); } ~MachineOperand() { if (isExternalSymbol()) - delete SymbolName; + delete contents.SymbolName; } const MachineOperand &operator=(const MachineOperand &MO) { if (isExternalSymbol()) // if old operand had a symbol name, - delete SymbolName; // release old memory - immedVal = MO.immedVal; + delete contents.SymbolName; // release old memory + contents = MO.contents; flags = MO.flags; opType = MO.opType; regNum = MO.regNum; if (isExternalSymbol()) - SymbolName = new std::string(MO.getSymbolName()); + contents.SymbolName = new std::string(MO.getSymbolName()); return *this; } @@ -184,9 +194,7 @@ /// getUseType - Returns the MachineOperandUseType of this operand. /// - UseType getUseType() const { - return UseType(flags & (USEFLAG|DEFFLAG)); - } + UseType getUseType() const { return UseType(flags & (USEFLAG|DEFFLAG)); } /// isPCRelative - This returns the value of the PCRELATIVE flag, which /// indicates whether this operand should be emitted as a PC relative value @@ -205,6 +213,8 @@ return opType == MO_MachineRegister || opType == MO_VirtualRegister; } + /// Accessors that tell you what kind of MachineOperand you're looking at. + /// bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; } bool isPCRelativeDisp() const { return opType == MO_PCRelativeDisp; } bool isImmediate() const { @@ -215,83 +225,109 @@ bool isGlobalAddress() const { return opType == MO_GlobalAddress; } bool isExternalSymbol() const { return opType == MO_ExternalSymbol; } - Value* getVRegValue() const { - assert(opType == MO_VirtualRegister || opType == MO_CCRegister || - isPCRelativeDisp()); - return value; - } + /// getVRegValueOrNull - Get the Value* out of a MachineOperand if it + /// has one. This is deprecated and only used by the SPARC v9 backend. + /// Value* getVRegValueOrNull() const { return (opType == MO_VirtualRegister || opType == MO_CCRegister || - isPCRelativeDisp()) ? value : NULL; + isPCRelativeDisp()) ? contents.value : NULL; + } + + /// MachineOperand accessors that only work on certain types of + /// MachineOperand... + /// + Value* getVRegValue() const { + assert ((opType == MO_VirtualRegister || opType == MO_CCRegister + || isPCRelativeDisp()) && "Wrong MachineOperand accessor"); + return contents.value; } int getMachineRegNum() const { - assert(opType == MO_MachineRegister); + assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor"); return regNum; } - int getImmedValue() const { assert(isImmediate()); return immedVal; } - void setImmedValue(int ImmVal) { assert(isImmediate()); immedVal = ImmVal; } - + int getImmedValue() const { + assert(isImmediate() && "Wrong MachineOperand accessor"); + return contents.immedVal; + } MachineBasicBlock *getMachineBasicBlock() const { - assert(isMachineBasicBlock() && "Can't get MBB in non-MBB operand!"); - return MBB; + assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); + return contents.MBB; + } + int getFrameIndex() const { + assert(isFrameIndex() && "Wrong MachineOperand accessor"); + return contents.immedVal; } - int getFrameIndex() const { assert(isFrameIndex()); return immedVal; } unsigned getConstantPoolIndex() const { - assert(isConstantPoolIndex()); - return immedVal; + assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); + return contents.immedVal; } - GlobalValue *getGlobal() const { - assert(isGlobalAddress()); - return (GlobalValue*)value; + assert(isGlobalAddress() && "Wrong MachineOperand accessor"); + return (GlobalValue*)contents.value; } - const std::string &getSymbolName() const { - assert(isExternalSymbol()); - return *SymbolName; + assert(isExternalSymbol() && "Wrong MachineOperand accessor"); + return *contents.SymbolName; } + /// MachineOperand methods for testing that work on any kind of + /// MachineOperand... + /// bool isUse () const { return flags & USEFLAG; } MachineOperand& setUse () { flags |= USEFLAG; return *this; } - bool isDef () const { return flags & DEFFLAG; } + bool isDef () const { return flags & DEFFLAG; } MachineOperand& setDef () { flags |= DEFFLAG; return *this; } bool isHiBits32 () const { return flags & HIFLAG32; } bool isLoBits32 () const { return flags & LOFLAG32; } bool isHiBits64 () const { return flags & HIFLAG64; } bool isLoBits64 () const { return flags & LOFLAG64; } - // used to check if a machine register has been allocated to this operand + /// hasAllocatedReg - Returns true iff a machine register has been + /// allocated to this operand. + /// bool hasAllocatedReg() const { return (regNum >= 0 && (opType == MO_VirtualRegister || opType == MO_CCRegister || opType == MO_MachineRegister)); } - // used to get the reg number if when one is allocated + /// getReg - Returns the register number. It is a runtime error to call this + /// if a register is not allocated. + /// unsigned getReg() const { assert(hasAllocatedReg()); return regNum; } - // ********** TODO: get rid of this duplicate code! *********** + /// MachineOperand mutators... + /// void setReg(unsigned Reg) { + // This method's comment used to say: 'TODO: get rid of this duplicate + // code.' It's not clear where the duplication is. assert(hasAllocatedReg() && "This operand cannot have a register number!"); regNum = Reg; } + void setImmedValue(int immVal) { + assert(isImmediate() && "Wrong MachineOperand mutator"); + contents.immedVal = immVal; + } friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); private: - - // Construction methods needed for fine-grain control. - // These must be accessed via coresponding methods in MachineInstr. + /// markHi32, markLo32, etc. - These methods must be accessed via + /// corresponding methods in MachineInstr. These methods are deprecated + /// and only used by the SPARC v9 back-end. + /// void markHi32() { flags |= HIFLAG32; } void markLo32() { flags |= LOFLAG32; } void markHi64() { flags |= HIFLAG64; } void markLo64() { flags |= LOFLAG64; } - // Replaces the Value with its corresponding physical register after - // register allocation is complete + /// setRegForValue - Replaces the Value with its corresponding physical + /// register after register allocation is complete. This is deprecated + /// and only used by the SPARC v9 back-end. + /// void setRegForValue(int reg) { assert(opType == MO_VirtualRegister || opType == MO_CCRegister || opType == MO_MachineRegister); @@ -321,18 +357,18 @@ //===----------------------------------------------------------------------===// class MachineInstr { - short Opcode; // the opcode + short Opcode; // the opcode unsigned char numImplicitRefs; // number of implicit operands std::vector operands; // the operands MachineInstr* prev, *next; // links for our intrusive list MachineBasicBlock* parent; // pointer to the owning basic block + // OperandComplete - Return true if it's illegal to add a new operand bool OperandsComplete() const; MachineInstr(const MachineInstr &); // DO NOT IMPLEMENT void operator=(const MachineInstr&); // DO NOT IMPLEMENT -private: // Intrusive list support // friend class ilist_traits; @@ -358,7 +394,7 @@ const MachineBasicBlock* getParent() const { return parent; } MachineBasicBlock* getParent() { return parent; } - /// Accessors for opcode. + /// getOpcode - Returns the opcode of this MachineInstr. /// const int getOpcode() const { return Opcode; } From brukman at cs.uiuc.edu Wed Mar 10 19:25:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:25:02 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/Transforms/IPO.h Message-ID: <200403110124.TAA08126@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.26.2.1 -> 1.26.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+6 -0) Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.26.2.1 llvm/include/llvm/Transforms/IPO.h:1.26.2.2 --- llvm/include/llvm/Transforms/IPO.h:1.26.2.1 Mon Mar 1 17:57:19 2004 +++ llvm/include/llvm/Transforms/IPO.h Wed Mar 10 19:24:11 2004 @@ -115,6 +115,12 @@ Pass *createDeadArgHackingPass(); //===----------------------------------------------------------------------===// +// createArgumentPromotionPass - This pass promotes "by reference" arguments to +// be passed by value. +// +Pass *createArgumentPromotionPass(); + +//===----------------------------------------------------------------------===// // createIPConstantPropagationPass - This pass propagates constants from call // sites into the bodies of functions. // From brukman at cs.uiuc.edu Wed Mar 10 19:29:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:29:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp DataStructure.cpp Local.cpp Printer.cpp Message-ID: <200403110128.TAA08208@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.70.4.1 -> 1.70.4.2 DataStructure.cpp updated: 1.131.4.1 -> 1.131.4.2 Local.cpp updated: 1.74.4.1 -> 1.74.4.2 Printer.cpp updated: 1.62.4.1 -> 1.62.4.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+288 -34) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.70.4.1 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.70.4.2 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.70.4.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Wed Mar 10 19:28:21 2004 @@ -100,6 +100,9 @@ ValMap[F] = Min; Stack.push_back(F); + // FIXME! This test should be generalized to be any function that we have + // already processed, in the case when there isn't a main or there are + // unreachable functions! if (F->isExternal()) { // sprintf, fprintf, sscanf, etc... // No callees! Stack.pop_back(); @@ -167,6 +170,8 @@ // graph sizes. DSGraph &NFGraph = getDSGraph(*NF); SCCGraphs.insert(&NFGraph); + // FIXME: If we used a better way of cloning graphs (ie, just splice all + // of the nodes into the new graph), this would be completely unneeded! if (!SCCGraph || SCCGraph->getGraphSize() < NFGraph.getGraphSize()) SCCGraph = &NFGraph; } while (NF != F); @@ -186,9 +191,11 @@ E = SCCGraphs.end(); I != E; ++I) { DSGraph &G = **I; if (&G != SCCGraph) { - DSGraph::NodeMapTy NodeMap; - SCCGraph->cloneInto(G, SCCGraph->getScalarMap(), - SCCGraph->getReturnNodes(), NodeMap); + { + DSGraph::NodeMapTy NodeMap; + SCCGraph->cloneInto(G, SCCGraph->getScalarMap(), + SCCGraph->getReturnNodes(), NodeMap); + } // Update the DSInfo map and delete the old graph... for (DSGraph::ReturnNodesTy::iterator I = G.getReturnNodes().begin(), E = G.getReturnNodes().end(); I != E; ++I) @@ -278,16 +285,12 @@ // Get the data structure graph for the called function. // DSGraph &GI = getDSGraph(*Callee); // Graph to inline - - if (Callee->getName() == "bc_raise") - std::cerr << "HERE!\n"; DEBUG(std::cerr << " Inlining graph for " << Callee->getName() << "[" << GI.getGraphSize() << "+" << GI.getAuxFunctionCalls().size() << "] into '" << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() << "+" << Graph.getAuxFunctionCalls().size() << "]\n"); - Graph.mergeInGraph(CS, *Callee, GI, DSGraph::KeepModRefBits | DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes); Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.131.4.1 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.131.4.2 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.131.4.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Mar 10 19:28:21 2004 @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/DSGraph.h" +#include "llvm/Analysis/DSGraphTraits.h" #include "llvm/Function.h" #include "llvm/GlobalVariable.h" #include "llvm/iOther.h" @@ -20,6 +20,7 @@ #include "llvm/Assembly/Writer.h" #include "Support/CommandLine.h" #include "Support/Debug.h" +#include "Support/DepthFirstIterator.h" #include "Support/STLExtras.h" #include "Support/Statistic.h" #include "Support/Timer.h" @@ -80,10 +81,11 @@ // DSNode copy constructor... do not copy over the referrers list! DSNode::DSNode(const DSNode &N, DSGraph *G, bool NullLinks) : NumReferrers(0), Size(N.Size), ParentGraph(G), - Ty(N.Ty), Globals(N.Globals), NodeType(N.NodeType) { - if (!NullLinks) + Ty(N.Ty), NodeType(N.NodeType) { + if (!NullLinks) { Links = N.Links; - else + Globals = N.Globals; + } else Links.resize(N.Links.size()); // Create the appropriate number of null links G->addNode(this); ++NumNodeAllocated; @@ -630,6 +632,8 @@ void DSNode::MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH) { assert(CurNodeH.getOffset() >= NH.getOffset() && "This should have been enforced in the caller."); + assert(CurNodeH.getNode()->getParentGraph()==NH.getNode()->getParentGraph() && + "Cannot merge two nodes that are not in the same graph!"); // Now we know that Offset >= NH.Offset, so convert it so our "Offset" (with // respect to NH.Offset) is now zero. NOffset is the distance from the base @@ -781,6 +785,23 @@ if (!NH.isNull()) // Node already mapped? return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset()); + // If SrcNH has globals and the destination graph has one of the same globals, + // merge this node with the destination node, which is much more efficient. + if (SN->global_begin() != SN->global_end()) { + DSScalarMap &DestSM = Dest.getScalarMap(); + for (DSNode::global_iterator I = SN->global_begin(), E = SN->global_end(); + I != E; ++I) { + GlobalValue *GV = *I; + DSScalarMap::iterator GI = DestSM.find(GV); + if (GI != DestSM.end() && !GI->second.isNull()) { + // We found one, use merge instead! + merge(GI->second, Src.getNodeForValue(GV)); + assert(!NH.isNull() && "Didn't merge node!"); + return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset()); + } + } + } + DSNode *DN = new DSNode(*SN, &Dest, true /* Null out all links */); DN->maskNodeTypes(BitsToKeep); NH = DN; @@ -823,6 +844,7 @@ if (CloneFlags & DSGraph::UpdateInlinedGlobals) Dest.getInlinedGlobals().insert(GV); } + NH.getNode()->mergeGlobals(SN->getGlobals()); return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset()); } @@ -912,6 +934,7 @@ if (CloneFlags & DSGraph::UpdateInlinedGlobals) Dest.getInlinedGlobals().insert(GV); } + NH.getNode()->mergeGlobals(SN->getGlobals()); } } else { // We cannot handle this case without allocating a temporary node. Fall @@ -963,19 +986,25 @@ // wrapping), but if the current node gets collapsed due to // recursive merging, we must make sure to merge in all remaining // links at offset zero. - unsigned MergeOffset = 0; DSNode *CN = SCNH.getNode(); - if (CN->getSize() != 1) - MergeOffset = ((i << DS::PointerShift)+SCNH.getOffset()) %CN->getSize(); + unsigned MergeOffset = + ((i << DS::PointerShift)+SCNH.getOffset()) % CN->getSize(); - DSNodeHandle &Link = CN->getLink(MergeOffset); - if (!Link.isNull()) { + DSNodeHandle Tmp = CN->getLink(MergeOffset); + if (!Tmp.isNull()) { // Perform the recursive merging. Make sure to create a temporary NH, // because the Link can disappear in the process of recursive merging. - DSNodeHandle Tmp = Link; merge(Tmp, SrcEdge); } else { - merge(Link, SrcEdge); + Tmp.mergeWith(getClonedNH(SrcEdge)); + // Merging this could cause all kinds of recursive things to happen, + // culminating in the current node being eliminated. Since this is + // possible, make sure to reaquire the link from 'CN'. + + unsigned MergeOffset = 0; + CN = SCNH.getNode(); + MergeOffset = ((i << DS::PointerShift)+SCNH.getOffset()) %CN->getSize(); + CN->getLink(MergeOffset).mergeWith(Tmp); } } } @@ -1181,6 +1210,23 @@ } } +static bool PathExistsToClonedNode(const DSNode *N, ReachabilityCloner &RC) { + if (N) + for (df_iterator I = df_begin(N), E = df_end(N); I != E; ++I) + if (RC.hasClonedNode(*I)) + return true; + return false; +} + +static bool PathExistsToClonedNode(const DSCallSite &CS, + ReachabilityCloner &RC) { + if (PathExistsToClonedNode(CS.getRetVal().getNode(), RC)) + return true; + for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) + if (PathExistsToClonedNode(CS.getPtrArg(i).getNode(), RC)) + return true; + return false; +} /// mergeInGraph - The method is used for merging graphs together. If the /// argument graph is not *this, it makes a clone of the specified graph, then @@ -1191,6 +1237,10 @@ const DSGraph &Graph, unsigned CloneFlags) { TIME_REGION(X, "mergeInGraph"); + // Fastpath for a noop inline. + if (CS.getNumPtrArgs() == 0 && CS.getRetVal().isNull()) + return; + // If this is not a recursive call, clone the graph into this graph... if (&Graph != this) { // Clone the callee's graph into the current graph, keeping track of where @@ -1218,29 +1268,72 @@ // Map the return node pointer over. if (!CS.getRetVal().isNull()) RC.merge(CS.getRetVal(), Graph.getReturnNodeFor(F)); - - // If requested, copy the calls or aux-calls lists. + + // If requested, copy all of the calls. if (!(CloneFlags & DontCloneCallNodes)) { // Copy the function calls list... FunctionCalls.reserve(FunctionCalls.size()+Graph.FunctionCalls.size()); for (unsigned i = 0, ei = Graph.FunctionCalls.size(); i != ei; ++i) FunctionCalls.push_back(DSCallSite(Graph.FunctionCalls[i], RC)); } - + + // If the user has us copying aux calls (the normal case), set up a data + // structure to keep track of which ones we've copied over. + std::vector CopiedAuxCall; if (!(CloneFlags & DontCloneAuxCallNodes)) { - // Copy the auxiliary function calls list... AuxFunctionCalls.reserve(AuxFunctionCalls.size()+ Graph.AuxFunctionCalls.size()); - for (unsigned i = 0, ei = Graph.AuxFunctionCalls.size(); i != ei; ++i) - AuxFunctionCalls.push_back(DSCallSite(Graph.AuxFunctionCalls[i], RC)); + CopiedAuxCall.resize(Graph.AuxFunctionCalls.size()); } // Clone over all globals that appear in the caller and callee graphs. + hash_set NonCopiedGlobals; for (DSScalarMap::global_iterator GI = Graph.getScalarMap().global_begin(), E = Graph.getScalarMap().global_end(); GI != E; ++GI) if (GlobalVariable *GV = dyn_cast(*GI)) if (ScalarMap.count(GV)) RC.merge(ScalarMap[GV], Graph.getNodeForValue(GV)); + else + NonCopiedGlobals.insert(GV); + + // If the global does not appear in the callers graph we generally don't + // want to copy the node. However, if there is a path from the node global + // node to a node that we did copy in the graph, we *must* copy it to + // maintain the connection information. Every time we decide to include a + // new global, this might make other globals live, so we must iterate + // unfortunately. + bool MadeChange = true; + while (MadeChange) { + MadeChange = false; + for (hash_set::iterator I = NonCopiedGlobals.begin(); + I != NonCopiedGlobals.end();) { + DSNode *GlobalNode = Graph.getNodeForValue(*I).getNode(); + if (RC.hasClonedNode(GlobalNode)) { + // Already cloned it, remove from set. + NonCopiedGlobals.erase(I++); + MadeChange = true; + } else if (PathExistsToClonedNode(GlobalNode, RC)) { + RC.getClonedNH(Graph.getNodeForValue(*I)); + NonCopiedGlobals.erase(I++); + MadeChange = true; + } else { + ++I; + } + } + + // If requested, copy any aux calls that can reach copied nodes. + if (!(CloneFlags & DontCloneAuxCallNodes)) { + for (unsigned i = 0, ei = Graph.AuxFunctionCalls.size(); i != ei; ++i) + if (!CopiedAuxCall[i] && + PathExistsToClonedNode(Graph.AuxFunctionCalls[i], RC)) { + AuxFunctionCalls.push_back(DSCallSite(Graph.AuxFunctionCalls[i], + RC)); + CopiedAuxCall[i] = true; + MadeChange = true; + } + } + } + } else { DSNodeHandle RetVal = getReturnNodeFor(F); @@ -1282,6 +1375,30 @@ return DSCallSite(CallSite(), getReturnNodeFor(F), &F, Args); } +/// getDSCallSiteForCallSite - Given an LLVM CallSite object that is live in +/// the context of this graph, return the DSCallSite for it. +DSCallSite DSGraph::getDSCallSiteForCallSite(CallSite CS) const { + DSNodeHandle RetVal; + Instruction *I = CS.getInstruction(); + if (isPointerType(I->getType())) + RetVal = getNodeForValue(I); + + std::vector Args; + Args.reserve(CS.arg_end()-CS.arg_begin()); + + // Calculate the arguments vector... + for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I) + if (isPointerType((*I)->getType())) + Args.push_back(getNodeForValue(*I)); + + // Add a new function call entry... + if (Function *F = CS.getCalledFunction()) + return DSCallSite(CS, RetVal, F, Args); + else + return DSCallSite(CS, RetVal, + getNodeForValue(CS.getCalledValue()).getNode(), Args); +} + // markIncompleteNodes - Mark the specified node as having contents that are not @@ -1348,7 +1465,7 @@ for (DSScalarMap::global_iterator I = ScalarMap.global_begin(), E = ScalarMap.global_end(); I != E; ++I) if (GlobalVariable *GV = dyn_cast(*I)) - if (!GV->isConstant()) + if (!GV->isConstant() || !GV->hasInitializer()) markIncompleteNode(ScalarMap[GV].getNode()); } @@ -1799,6 +1916,29 @@ DEBUG(AssertGraphOK(); GlobalsGraph->AssertGraphOK()); } +void DSGraph::AssertCallSiteInGraph(const DSCallSite &CS) const { + if (CS.isIndirectCall()) { + AssertNodeInGraph(CS.getCalleeNode()); +#if 0 + if (CS.getNumPtrArgs() && CS.getCalleeNode() == CS.getPtrArg(0).getNode() && + CS.getCalleeNode() && CS.getCalleeNode()->getGlobals().empty()) + std::cerr << "WARNING: WIERD CALL SITE FOUND!\n"; +#endif + } + AssertNodeInGraph(CS.getRetVal().getNode()); + for (unsigned j = 0, e = CS.getNumPtrArgs(); j != e; ++j) + AssertNodeInGraph(CS.getPtrArg(j).getNode()); +} + +void DSGraph::AssertCallNodesInGraph() const { + for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) + AssertCallSiteInGraph(FunctionCalls[i]); +} +void DSGraph::AssertAuxCallNodesInGraph() const { + for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i) + AssertCallSiteInGraph(AuxFunctionCalls[i]); +} + void DSGraph::AssertGraphOK() const { for (node_iterator NI = node_begin(), E = node_end(); NI != E; ++NI) (*NI)->assertOK(); @@ -1847,4 +1987,7 @@ for (unsigned i = 0, e = N1->getSize(); i < e; i += DS::PointerSize) if (unsigned(N2Idx)+i < N2Size) computeNodeMapping(N1->getLink(i), N2->getLink(N2Idx+i), NodeMap); + else + computeNodeMapping(N1->getLink(i), + N2->getLink(unsigned(N2Idx+i) % N2Size), NodeMap); } Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.74.4.1 llvm/lib/Analysis/DataStructure/Local.cpp:1.74.4.2 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.74.4.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/DataStructure/Local.cpp Wed Mar 10 19:28:21 2004 @@ -117,6 +117,8 @@ void visitInstruction(Instruction &I); void visitCallSite(CallSite CS); + void visitVANextInst(VANextInst &I); + void visitVAArgInst(VAArgInst &I); void MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C); private: @@ -185,7 +187,7 @@ for (DSScalarMap::global_iterator I = ScalarMap.global_begin(); I != ScalarMap.global_end(); ++I) if (GlobalVariable *GV = dyn_cast(*I)) - if (GV->isConstant()) + if (!GV->isExternal() && GV->isConstant()) RC.merge(ScalarMap[GV], GG->ScalarMap[GV]); } @@ -281,11 +283,7 @@ /// merge the two destinations together. /// void GraphBuilder::setDestTo(Value &V, const DSNodeHandle &NH) { - DSNodeHandle &AINH = ScalarMap[&V]; - if (AINH.getNode() == 0) // Not pointing to anything yet? - AINH = NH; // Just point directly to NH - else - AINH.mergeWith(NH); + ScalarMap[&V].mergeWith(NH); } @@ -442,7 +440,7 @@ void GraphBuilder::visitStoreInst(StoreInst &SI) { const Type *StoredTy = SI.getOperand(0)->getType(); DSNodeHandle Dest = getValueDest(*SI.getOperand(1)); - if (Dest.getNode() == 0) return; + if (Dest.isNull()) return; // Mark that the node is written to... Dest.getNode()->setModifiedMarker(); @@ -460,6 +458,25 @@ RetNode->mergeWith(getValueDest(*RI.getOperand(0))); } +void GraphBuilder::visitVANextInst(VANextInst &I) { + getValueDest(*I.getOperand(0)).mergeWith(getValueDest(I)); +} + +void GraphBuilder::visitVAArgInst(VAArgInst &I) { + DSNodeHandle Ptr = getValueDest(*I.getOperand(0)); + if (Ptr.isNull()) return; + + // Make that the node is read from. + Ptr.getNode()->setReadMarker(); + + // Ensure a typerecord exists... + Ptr.getNode()->mergeTypeInfo(I.getType(), Ptr.getOffset(), false); + + if (isPointerType(I.getType())) + setDestTo(I, getLink(Ptr)); +} + + void GraphBuilder::visitCallInst(CallInst &CI) { visitCallSite(&CI); } @@ -477,6 +494,17 @@ if (Function *F = dyn_cast(Callee)) if (F->isExternal()) switch (F->getIntrinsicID()) { + case Intrinsic::va_start: + getValueDest(*CS.getInstruction()).getNode()->setAllocaNodeMarker(); + return; + case Intrinsic::va_copy: + getValueDest(*CS.getInstruction()). + mergeWith(getValueDest(**(CS.arg_begin()))); + return; + // FIXME: the #undef is a quick fix for compilation on Sparc +#undef va_end + case Intrinsic::va_end: + return; // noop case Intrinsic::memmove: case Intrinsic::memcpy: { // Merge the first & second arguments, and mark the memory read and @@ -560,6 +588,24 @@ N->mergeTypeInfo(PTy->getElementType(), StatBuf.getOffset()); } return; + } else if (F->getName() == "strtod" || F->getName() == "strtof" || + F->getName() == "strtold") { + // These functions read the first pointer + if (DSNode *Str = getValueDest(**CS.arg_begin()).getNode()) { + Str->setReadMarker(); + // If the second parameter is passed, it will point to the first + // argument node. + const DSNodeHandle &EndPtrNH = getValueDest(**(CS.arg_begin()+1)); + if (DSNode *End = EndPtrNH.getNode()) { + End->mergeTypeInfo(PointerType::get(Type::SByteTy), + EndPtrNH.getOffset(), false); + End->setModifiedMarker(); + DSNodeHandle &Link = getLink(EndPtrNH); + Link.mergeWith(getValueDest(**CS.arg_begin())); + } + } + + return; } else if (F->getName() == "fopen" || F->getName() == "fdopen" || F->getName() == "freopen") { // These functions read all of their pointer operands. @@ -581,7 +627,8 @@ // If this is freopen, merge the file descriptor passed in with the // result. - Result.mergeWith(getValueDest(**--CS.arg_end())); + if (F->getName() == "freopen") + Result.mergeWith(getValueDest(**--CS.arg_end())); return; } else if (F->getName() == "fclose" && CS.arg_end()-CS.arg_begin() ==1){ @@ -721,6 +768,54 @@ if (DSNode *N = getValueDest(**AI).getNode()) N->setReadMarker(); } + return; + } else if (F->getName() == "vprintf" || F->getName() == "vfprintf" || + F->getName() == "vsprintf") { + CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end(); + + if (F->getName() == "vfprintf") { + // ffprintf reads and writes the FILE argument, and applies the type + // to it. + DSNodeHandle H = getValueDest(**AI); + if (DSNode *N = H.getNode()) { + N->setModifiedMarker()->setReadMarker(); + const Type *ArgTy = (*AI)->getType(); + if (const PointerType *PTy = dyn_cast(ArgTy)) + N->mergeTypeInfo(PTy->getElementType(), H.getOffset()); + } + ++AI; + } else if (F->getName() == "vsprintf") { + // vsprintf writes the first string argument. + DSNodeHandle H = getValueDest(**AI++); + if (DSNode *N = H.getNode()) { + N->setModifiedMarker(); + const Type *ArgTy = (*AI)->getType(); + if (const PointerType *PTy = dyn_cast(ArgTy)) + N->mergeTypeInfo(PTy->getElementType(), H.getOffset()); + } + } + + // Read the format + if (AI != E) { + if (isPointerType((*AI)->getType())) + if (DSNode *N = getValueDest(**AI).getNode()) + N->setReadMarker(); + ++AI; + } + + // Read the valist, and the pointed-to objects. + if (AI != E && isPointerType((*AI)->getType())) { + const DSNodeHandle &VAList = getValueDest(**AI); + if (DSNode *N = VAList.getNode()) { + N->setReadMarker(); + N->mergeTypeInfo(PointerType::get(Type::SByteTy), + VAList.getOffset(), false); + + DSNodeHandle &VAListObjs = getLink(VAList); + VAListObjs.getNode()->setReadMarker(); + } + } + return; } else if (F->getName() == "scanf" || F->getName() == "fscanf" || F->getName() == "sscanf") { Index: llvm/lib/Analysis/DataStructure/Printer.cpp diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.62.4.1 llvm/lib/Analysis/DataStructure/Printer.cpp:1.62.4.2 --- llvm/lib/Analysis/DataStructure/Printer.cpp:1.62.4.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/DataStructure/Printer.cpp Wed Mar 10 19:28:21 2004 @@ -40,11 +40,17 @@ std::stringstream OS; Module *M = 0; - if (G) G = N->getParentGraph(); + if (!G) G = N->getParentGraph(); // Get the module from ONE of the functions in the graph it is available. if (G && !G->getReturnNodes().empty()) M = G->getReturnNodes().begin()->first->getParent(); + if (M == 0 && G) { + // If there is a global in the graph, we can use it to find the module. + const DSScalarMap &SM = G->getScalarMap(); + if (SM.global_begin() != SM.global_end()) + M = (*SM.global_begin())->getParent(); + } if (N->isNodeCompletelyFolded()) OS << "COLLAPSED"; @@ -108,6 +114,13 @@ Module *CurMod = 0; if (!G->getReturnNodes().empty()) CurMod = G->getReturnNodes().begin()->first->getParent(); + else { + // If there is a global in the graph, we can use it to find the module. + const DSScalarMap &SM = G->getScalarMap(); + if (SM.global_begin() != SM.global_end()) + CurMod = (*SM.global_begin())->getParent(); + } + // Add scalar nodes to the graph... const DSGraph::ScalarMapTy &VM = G->getScalarMap(); From brukman at cs.uiuc.edu Wed Mar 10 19:29:08 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:29:08 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp Message-ID: <200403110128.TAA08225@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: CompleteBottomUp.cpp updated: 1.3.4.1 -> 1.3.4.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+29 -6) Index: llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp diff -u llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.3.4.1 llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.3.4.2 --- llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.3.4.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp Wed Mar 10 19:28:39 2004 @@ -16,13 +16,16 @@ #include "llvm/Analysis/DataStructure.h" #include "llvm/Module.h" #include "llvm/Analysis/DSGraph.h" +#include "Support/Debug.h" #include "Support/SCCIterator.h" +#include "Support/Statistic.h" #include "Support/STLExtras.h" using namespace llvm; namespace { RegisterAnalysis X("cbudatastructure", "'Complete' Bottom-up Data Structure Analysis"); + Statistic<> NumCBUInlines("cbudatastructures", "Number of graphs inlined"); } @@ -68,7 +71,8 @@ unsigned NextID = 1; if (Function *Main = M.getMainFunction()) { - calculateSCCGraphs(getOrCreateGraph(*Main), Stack, NextID, ValMap); + if (!Main->isExternal()) + calculateSCCGraphs(getOrCreateGraph(*Main), Stack, NextID, ValMap); } else { std::cerr << "CBU-DSA: No 'main' function found!\n"; } @@ -168,26 +172,45 @@ /// processGraph - Process the BU graphs for the program in bottom-up order on /// the SCC of the __ACTUAL__ call graph. This builds "complete" BU graphs. void CompleteBUDataStructures::processGraph(DSGraph &G) { + hash_set calls; // The edges out of the current node are the call site targets... for (unsigned i = 0, e = G.getFunctionCalls().size(); i != e; ++i) { const DSCallSite &CS = G.getFunctionCalls()[i]; Instruction *TheCall = CS.getCallSite().getInstruction(); + assert(calls.insert(TheCall).second && + "Call instruction occurs multiple times in graph??"); + + // The Normal BU pass will have taken care of direct calls well already, // don't worry about them. + + // FIXME: if a direct callee had indirect callees, it seems like they could + // be updated and we would have to reinline even direct calls! + if (!CS.getCallSite().getCalledFunction()) { // Loop over all of the actually called functions... ActualCalleesTy::iterator I, E; - for (tie(I, E) = ActualCallees.equal_range(TheCall); I != E; ++I) { + tie(I, E) = ActualCallees.equal_range(TheCall); + unsigned TNum = 0, Num = std::distance(I, E); + for (; I != E; ++I, ++TNum) { Function *CalleeFunc = I->second; if (!CalleeFunc->isExternal()) { // Merge the callee's graph into this graph. This works for normal // calls or for self recursion within an SCC. - G.mergeInGraph(CS, *CalleeFunc, getOrCreateGraph(*CalleeFunc), - DSGraph::KeepModRefBits | - DSGraph::StripAllocaBit | - DSGraph::DontCloneCallNodes); + DSGraph &GI = getOrCreateGraph(*CalleeFunc); + ++NumCBUInlines; + G.mergeInGraph(CS, *CalleeFunc, GI, DSGraph::KeepModRefBits | + DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes | + DSGraph::DontCloneAuxCallNodes); + DEBUG(std::cerr << " Inlining graph [" << i << "/" << e-1 + << ":" << TNum << "/" << Num-1 << "] for " + << CalleeFunc->getName() << "[" + << GI.getGraphSize() << "+" << GI.getAuxFunctionCalls().size() + << "] into '" /*<< G.getFunctionNames()*/ << "' [" + << G.getGraphSize() << "+" << G.getAuxFunctionCalls().size() + << "]\n"); } } } From brukman at cs.uiuc.edu Wed Mar 10 19:30:03 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:30:03 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200403110129.TAA08245@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.13.4.1 -> 1.13.4.2 --- Log message: Implement getModRefInfo() for resolving aliasing between calls and values. --- Diffs of the changes: (+37 -3) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.13.4.1 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.13.4.2 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.13.4.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Wed Mar 10 19:29:34 2004 @@ -12,15 +12,16 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Module.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/DataStructure.h" #include "llvm/Analysis/DSGraph.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Module.h" using namespace llvm; namespace { class DSAA : public Pass, public AliasAnalysis { TDDataStructures *TD; + BUDataStructures *BU; public: DSAA() : TD(0) {} @@ -34,13 +35,15 @@ bool run(Module &M) { InitializeAliasAnalysis(this); TD = &getAnalysis(); + BU = &getAnalysis(); return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AliasAnalysis::getAnalysisUsage(AU); AU.setPreservesAll(); // Does not transform code... - AU.addRequired(); // Uses TD Datastructures + AU.addRequiredLive(); // Uses TD Datastructures + AU.addRequiredLive(); // Uses BU Datastructures AU.addRequired(); // Chains to another AA impl... } @@ -56,6 +59,9 @@ bool pointsToConstantMemory(const Value *P) { return getAnalysis().pointsToConstantMemory(P); } + + AliasAnalysis::ModRefResult + getModRefInfo(CallSite CS, Value *P, unsigned Size); private: DSGraph *getGraphForValue(const Value *V); @@ -150,6 +156,34 @@ // FIXME: we could improve on this by checking the globals graph for aliased // global queries... return getAnalysis().alias(V1, V1Size, V2, V2Size); +} + +/// getModRefInfo - +/// +AliasAnalysis::ModRefResult +DSAA::getModRefInfo(CallSite CS, Value *P, unsigned Size) { + Function *F = CS.getCalledFunction(); + if (!F) return pointsToConstantMemory(P) ? Ref : ModRef; + if (F->isExternal()) return ModRef; + + // Clone the function TD graph, clearing off Mod/Ref flags + const Function *csParent = CS.getInstruction()->getParent()->getParent(); + DSGraph TDGraph(TD->getDSGraph(*csParent)); + TDGraph.maskNodeTypes(0); + + // Insert the callee's BU graph into the TD graph + const DSGraph &BUGraph = BU->getDSGraph(*F); + TDGraph.mergeInGraph(TDGraph.getDSCallSiteForCallSite(CS), + *F, BUGraph, 0); + + // Report the flags that have been added + const DSNodeHandle &DSH = TDGraph.getNodeForValue(P); + if (const DSNode *N = DSH.getNode()) + if (N->isModified()) + return N->isRead() ? ModRef : Mod; + else + return N->isRead() ? Ref : NoModRef; + return NoModRef; } From brukman at cs.uiuc.edu Wed Mar 10 19:33:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:33:00 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Analysis/Trace.cpp BasicAliasAnalysis.cpp InductionVariable.cpp ProfileInfo.cpp ProfileInfoLoader.cpp ProfileInfoLoaderPass.cpp Message-ID: <200403110132.TAA08321@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: Trace.cpp added (r1.1.2.1) BasicAliasAnalysis.cpp updated: 1.26.2.1 -> 1.26.2.2 InductionVariable.cpp updated: 1.34 -> 1.34.2.1 ProfileInfo.cpp updated: 1.3.2.1 -> 1.3.2.2 ProfileInfoLoader.cpp updated: 1.2.2.1 -> 1.2.2.2 ProfileInfoLoaderPass.cpp updated: 1.3.2.1 -> 1.3.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+232 -29) Index: llvm/lib/Analysis/Trace.cpp diff -c /dev/null llvm/lib/Analysis/Trace.cpp:1.1.2.1 *** /dev/null Wed Mar 10 19:32:01 2004 --- llvm/lib/Analysis/Trace.cpp Wed Mar 10 19:31:51 2004 *************** *** 0 **** --- 1,50 ---- + //===- Trace.cpp - Implementation of Trace class --------------------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This class represents a single trace of LLVM basic blocks. A trace is a + // single entry, multiple exit, region of code that is often hot. Trace-based + // optimizations treat traces almost like they are a large, strange, basic + // block: because the trace path is assumed to be hot, optimizations for the + // fall-through path are made at the expense of the non-fall-through paths. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Analysis/Trace.h" + #include "llvm/Function.h" + #include "llvm/Assembly/Writer.h" + using namespace llvm; + + Function *Trace::getFunction() const { + return getEntryBasicBlock()->getParent(); + } + + + Module *Trace::getModule() const { + return getFunction()->getParent(); + } + + /// print - Write trace to output stream. + /// + void Trace::print (std::ostream &O) const { + Function *F = getFunction (); + O << "; Trace from function " << F->getName () << ", blocks:\n"; + for (const_iterator i = begin (), e = end (); i != e; ++i) { + O << "; "; + WriteAsOperand (O, *i, true, true, getModule ()); + O << "\n"; + } + O << "; Trace parent function: \n" << *F; + } + + /// dump - Debugger convenience method; writes trace to standard error + /// output stream. + /// + void Trace::dump () const { + print (std::cerr); + } Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.26.2.1 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.26.2.2 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.26.2.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Wed Mar 10 19:31:51 2004 @@ -20,16 +20,19 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Pass.h" #include "llvm/Argument.h" #include "llvm/iOther.h" #include "llvm/iMemory.h" #include "llvm/Constants.h" #include "llvm/GlobalVariable.h" #include "llvm/DerivedTypes.h" -#include "llvm/Target/TargetData.h" +#include "llvm/GlobalVariable.h" +#include "llvm/iOther.h" +#include "llvm/iMemory.h" +#include "llvm/Pass.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/Target/TargetData.h" using namespace llvm; // Make sure that anything that uses AliasAnalysis pulls in this file... Index: llvm/lib/Analysis/InductionVariable.cpp diff -u llvm/lib/Analysis/InductionVariable.cpp:1.34 llvm/lib/Analysis/InductionVariable.cpp:1.34.2.1 --- llvm/lib/Analysis/InductionVariable.cpp:1.34 Tue Dec 23 02:04:02 2003 +++ llvm/lib/Analysis/InductionVariable.cpp Wed Mar 10 19:31:51 2004 @@ -136,10 +136,14 @@ if (Constant *CV = dyn_cast(V)) Step = ConstantExpr::get(Instruction::Sub, Zero, CV); else if (Instruction *I = dyn_cast(V)) { + BasicBlock::iterator InsertPt = I; + for (++InsertPt; isa(InsertPt); ++InsertPt) + /*empty*/; Step = BinaryOperator::create(Instruction::Sub, Zero, V, - V->getName()+".neg", I->getNext()); + V->getName()+".neg", InsertPt); } else { + // Must be loop invariant Step = BinaryOperator::create(Instruction::Sub, Zero, V, V->getName()+".neg", Phi->getParent()->getParent()->begin()->begin()); Index: llvm/lib/Analysis/ProfileInfo.cpp diff -u llvm/lib/Analysis/ProfileInfo.cpp:1.3.2.1 llvm/lib/Analysis/ProfileInfo.cpp:1.3.2.2 --- llvm/lib/Analysis/ProfileInfo.cpp:1.3.2.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/ProfileInfo.cpp Wed Mar 10 19:31:51 2004 @@ -14,6 +14,8 @@ #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Pass.h" +#include "llvm/Support/CFG.h" +#include using namespace llvm; // Register the ProfileInfo interface, providing a nice name to refer to. @@ -23,15 +25,63 @@ ProfileInfo::~ProfileInfo() {} +unsigned ProfileInfo::getExecutionCount(BasicBlock *BB) const { + pred_iterator PI = pred_begin(BB), PE = pred_end(BB); + + // Are there zero predecessors of this block? + if (PI == PE) { + // If this is the entry block, look for the Null -> Entry edge. + if (BB == &BB->getParent()->front()) + return getEdgeWeight(0, BB); + else + return 0; // Otherwise, this is a dead block. + } + + // Otherwise, if there are predecessors, the execution count of this block is + // the sum of the edge frequencies from the incoming edges. Note that if + // there are multiple edges from a predecessor to this block that we don't + // want to count its weight multiple times. For this reason, we keep track of + // the predecessors we've seen and only count them if we haven't run into them + // yet. + // + // We don't want to create an std::set unless we are dealing with a block that + // has a LARGE number of in-edges. Handle the common case of having only a + // few in-edges with special code. + // + BasicBlock *FirstPred = *PI; + unsigned Count = getEdgeWeight(FirstPred, BB); + ++PI; + if (PI == PE) return Count; // Quick exit for single predecessor blocks + + BasicBlock *SecondPred = *PI; + if (SecondPred != FirstPred) Count += getEdgeWeight(SecondPred, BB); + ++PI; + if (PI == PE) return Count; // Quick exit for two predecessor blocks + + BasicBlock *ThirdPred = *PI; + if (ThirdPred != FirstPred && ThirdPred != SecondPred) + Count += getEdgeWeight(ThirdPred, BB); + ++PI; + if (PI == PE) return Count; // Quick exit for three predecessor blocks + + std::set ProcessedPreds; + ProcessedPreds.insert(FirstPred); + ProcessedPreds.insert(SecondPred); + ProcessedPreds.insert(ThirdPred); + for (; PI != PE; ++PI) + if (ProcessedPreds.insert(*PI).second) + Count += getEdgeWeight(*PI, BB); + return Count; +} + + //===----------------------------------------------------------------------===// // NoProfile ProfileInfo implementation // namespace { - struct NoProfileInfo : public ImmutablePass, public ProfileInfo { - unsigned getExecutionCount(BasicBlock *BB) { return 0; } - }; + struct NoProfileInfo : public ImmutablePass, public ProfileInfo {}; // Register this pass... RegisterOpt Index: llvm/lib/Analysis/ProfileInfoLoader.cpp diff -u llvm/lib/Analysis/ProfileInfoLoader.cpp:1.2.2.1 llvm/lib/Analysis/ProfileInfoLoader.cpp:1.2.2.2 --- llvm/lib/Analysis/ProfileInfoLoader.cpp:1.2.2.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/ProfileInfoLoader.cpp Wed Mar 10 19:31:51 2004 @@ -14,13 +14,16 @@ #include "llvm/Analysis/ProfileInfoLoader.h" #include "llvm/Module.h" +#include "llvm/InstrTypes.h" #include +#include using namespace llvm; enum ProfilingType { ArgumentInfo = 1, // The command line argument block FunctionInfo = 2, // Function profiling information BlockInfo = 3, // Block profiling information + EdgeInfo = 4, // Edge profiling information }; // ByteSwap - Byteswap 'Var' if 'Really' is true. @@ -122,6 +125,10 @@ ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts); break; + case EdgeInfo: + ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts); + break; + default: std::cerr << ToolName << ": Unknown packet type #" << PacketType << "!\n"; exit(1); @@ -139,15 +146,19 @@ void ProfileInfoLoader::getFunctionCounts(std::vector > &Counts) { if (FunctionCounts.empty()) { - // Synthesize function frequency information from the number of times their - // entry blocks were executed. - std::vector > BlockCounts; - getBlockCounts(BlockCounts); - - for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i) - if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first) - Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(), - BlockCounts[i].second)); + if (hasAccurateBlockCounts()) { + // Synthesize function frequency information from the number of times + // their entry blocks were executed. + std::vector > BlockCounts; + getBlockCounts(BlockCounts); + + for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i) + if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first) + Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(), + BlockCounts[i].second)); + } else { + std::cerr << "Function counts are not available!\n"; + } return; } @@ -165,8 +176,59 @@ void ProfileInfoLoader::getBlockCounts(std::vector > &Counts) { if (BlockCounts.empty()) { - std::cerr << "Block counts not available, and no synthesis " - << "is implemented yet!\n"; + if (hasAccurateEdgeCounts()) { + // Synthesize block count information from edge frequency information. + // The block execution frequency is equal to the sum of the execution + // frequency of all outgoing edges from a block. + // + // If a block has no successors, this will not be correct, so we have to + // special case it. :( + std::vector > EdgeCounts; + getEdgeCounts(EdgeCounts); + + std::map InEdgeFreqs; + + BasicBlock *LastBlock = 0; + TerminatorInst *TI = 0; + for (unsigned i = 0, e = EdgeCounts.size(); i != e; ++i) { + if (EdgeCounts[i].first.first != LastBlock) { + LastBlock = EdgeCounts[i].first.first; + TI = LastBlock->getTerminator(); + Counts.push_back(std::make_pair(LastBlock, 0)); + } + Counts.back().second += EdgeCounts[i].second; + unsigned SuccNum = EdgeCounts[i].first.second; + if (SuccNum >= TI->getNumSuccessors()) { + static bool Warned = false; + if (!Warned) { + std::cerr << "WARNING: profile info doesn't seem to match" + << " the program!\n"; + Warned = true; + } + } else { + // If this successor has no successors of its own, we will never + // compute an execution count for that block. Remember the incoming + // edge frequencies to add later. + BasicBlock *Succ = TI->getSuccessor(SuccNum); + if (Succ->getTerminator()->getNumSuccessors() == 0) + InEdgeFreqs[Succ] += EdgeCounts[i].second; + } + } + + // Now we have to accumulate information for those blocks without + // successors into our table. + for (std::map::iterator I = InEdgeFreqs.begin(), + E = InEdgeFreqs.end(); I != E; ++I) { + unsigned i = 0; + for (; i != Counts.size() && Counts[i].first != I->first; ++i) + /*empty*/; + if (i == Counts.size()) Counts.push_back(std::make_pair(I->first, 0)); + Counts[i].second += I->second; + } + + } else { + std::cerr << "Block counts are not available!\n"; + } return; } @@ -177,4 +239,27 @@ if (Counter == BlockCounts.size()) return; } +} + +// getEdgeCounts - This method is used by consumers of edge counting +// information. If we do not directly have edge count information, we compute +// it from other, more refined, types of profile information. +// +void ProfileInfoLoader::getEdgeCounts(std::vector > &Counts) { + if (EdgeCounts.empty()) { + std::cerr << "Edge counts not available, and no synthesis " + << "is implemented yet!\n"; + return; + } + + unsigned Counter = 0; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + for (unsigned i = 0, e = BB->getTerminator()->getNumSuccessors(); + i != e; ++i) { + Counts.push_back(std::make_pair(Edge(BB, i), EdgeCounts[Counter++])); + if (Counter == EdgeCounts.size()) + return; + } } Index: llvm/lib/Analysis/ProfileInfoLoaderPass.cpp diff -u llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.3.2.1 llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.3.2.2 --- llvm/lib/Analysis/ProfileInfoLoaderPass.cpp:1.3.2.1 Mon Mar 1 17:58:12 2004 +++ llvm/lib/Analysis/ProfileInfoLoaderPass.cpp Wed Mar 10 19:31:51 2004 @@ -12,6 +12,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/BasicBlock.h" +#include "llvm/InstrTypes.h" #include "llvm/Pass.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Analysis/ProfileInfoLoader.h" @@ -26,7 +28,6 @@ class LoaderPass : public Pass, public ProfileInfo { std::string Filename; - std::map ExecutionCounts; public: LoaderPass(const std::string &filename = "") : Filename(filename) { @@ -43,11 +44,6 @@ /// run - Load the profile information from the specified file. virtual bool run(Module &M); - - virtual unsigned getExecutionCount(BasicBlock *BB) { - std::map::iterator I = ExecutionCounts.find(BB); - return I != ExecutionCounts.end() ? I->second : 0; - } }; RegisterOpt @@ -65,11 +61,26 @@ } bool LoaderPass::run(Module &M) { - ProfileInfoLoader PIL("opt", Filename, M); - if (PIL.hasAccurateBlockCounts()) { - std::vector > Counts; - PIL.getBlockCounts(Counts); - ExecutionCounts.insert(Counts.begin(), Counts.end()); + ProfileInfoLoader PIL("profile-loader", Filename, M); + EdgeCounts.clear(); + bool PrintedWarning = false; + + std::vector > ECs; + PIL.getEdgeCounts(ECs); + for (unsigned i = 0, e = ECs.size(); i != e; ++i) { + BasicBlock *BB = ECs[i].first.first; + unsigned SuccNum = ECs[i].first.second; + TerminatorInst *TI = BB->getTerminator(); + if (SuccNum >= TI->getNumSuccessors()) { + if (!PrintedWarning) { + std::cerr << "WARNING: profile information is inconsistent with " + << "the current program!\n"; + PrintedWarning = true; + } + } else { + EdgeCounts[std::make_pair(BB, TI->getSuccessor(SuccNum))]+= ECs[i].second; + } } + return false; } From brukman at cs.uiuc.edu Wed Mar 10 19:33:07 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:33:07 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200403110132.TAA08340@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.148.2.2 -> 1.148.2.3 --- Log message: Merge from trunk. --- Diffs of the changes: (+9 -16) Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.148.2.2 llvm/lib/AsmParser/llvmAsmParser.y:1.148.2.3 --- llvm/lib/AsmParser/llvmAsmParser.y:1.148.2.2 Mon Mar 1 17:58:12 2004 +++ llvm/lib/AsmParser/llvmAsmParser.y Wed Mar 10 19:32:41 2004 @@ -73,7 +73,7 @@ // here. This is used for forward references of ConstantPointerRefs. // typedef std::map, GlobalVariable*> GlobalRefsType; + ValID>, GlobalValue*> GlobalRefsType; GlobalRefsType GlobalRefs; void ModuleDone() { @@ -114,7 +114,7 @@ GlobalRefs.find(std::make_pair(GV->getType(), D)); if (I != GlobalRefs.end()) { - GlobalVariable *OldGV = I->second; // Get the placeholder... + GlobalValue *OldGV = I->second; // Get the placeholder... I->first.second.destroy(); // Free string memory if necessary // Loop over all of the uses of the GlobalValue. The only thing they are @@ -125,12 +125,14 @@ // Change the const pool reference to point to the real global variable // now. This should drop a use from the OldGV. - CPR->mutateReferences(OldGV, GV); + CPR->replaceUsesOfWithOnConstant(OldGV, GV); assert(OldGV->use_empty() && "All uses should be gone now!"); // Remove OldGV from the module... - CurrentModule->getGlobalList().remove(OldGV); - delete OldGV; // Delete the old placeholder + if (GlobalVariable *GVar = dyn_cast(OldGV)) + CurrentModule->getGlobalList().erase(GVar); + else + CurrentModule->getFunctionList().erase(cast(OldGV)); // Remove the map entry for the global now that it has been created... GlobalRefs.erase(I); @@ -1293,8 +1295,6 @@ // FunctionList : FunctionList Function { $$ = $1; - assert($2->getParent() == 0 && "Function already in module!"); - $1->getFunctionList().push_back($2); CurFun.FunctionDone(); } | FunctionList FunctionProto { @@ -1469,18 +1469,13 @@ if (!CurFun.isDeclare && !Fn->isExternal()) ThrowException("Redefinition of function '" + FunctionName + "'!"); - // If we found a preexisting function prototype, remove it from the - // module, so that we don't get spurious conflicts with global & local - // variables. - // - CurModule.CurrentModule->getFunctionList().remove(Fn); - // Make sure to strip off any argument names so we can't get conflicts... for (Function::aiterator AI = Fn->abegin(), AE = Fn->aend(); AI != AE; ++AI) AI->setName(""); } else { // Not already defined? - Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName); + Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName, + CurModule.CurrentModule); InsertValue(Fn, CurModule.Values); CurModule.DeclareNewGlobalValue(Fn, ValID::create($2)); } @@ -1532,8 +1527,6 @@ FunctionProto : DECLARE { CurFun.isDeclare = true; } FunctionHeaderH { $$ = CurFun.CurrentFunction; - assert($$->getParent() == 0 && "Function already in module!"); - CurModule.CurrentModule->getFunctionList().push_back($$); CurFun.FunctionDone(); }; From brukman at cs.uiuc.edu Wed Mar 10 19:34:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:34:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/CodeGen/MachineInstr.cpp VirtRegMap.cpp Message-ID: <200403110133.TAA08381@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineInstr.cpp updated: 1.82.2.1 -> 1.82.2.2 VirtRegMap.cpp updated: 1.8.2.1 -> 1.8.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+87 -17) Index: llvm/lib/CodeGen/MachineInstr.cpp diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.82.2.1 llvm/lib/CodeGen/MachineInstr.cpp:1.82.2.2 --- llvm/lib/CodeGen/MachineInstr.cpp:1.82.2.1 Mon Mar 1 17:58:13 2004 +++ llvm/lib/CodeGen/MachineInstr.cpp Wed Mar 10 19:33:31 2004 @@ -100,7 +100,7 @@ Value* V) { assert(i < operands.size()); // may be explicit or implicit op operands[i].opType = opTy; - operands[i].value = V; + operands[i].contents.value = V; operands[i].regNum = -1; } @@ -113,8 +113,8 @@ "immed. constant cannot be defined"); operands[i].opType = opTy; - operands[i].value = NULL; - operands[i].immedVal = intValue; + operands[i].contents.value = NULL; + operands[i].contents.immedVal = intValue; operands[i].regNum = -1; operands[i].flags = 0; } @@ -123,7 +123,7 @@ assert(i < getNumOperands()); // must be explicit op operands[i].opType = MachineOperand::MO_MachineRegister; - operands[i].value = NULL; + operands[i].contents.value = NULL; operands[i].regNum = regNum; } @@ -162,7 +162,7 @@ notDefsAndUses && (O.isDef() && !O.isUse()) || !notDefsAndUses && O.isDef()) { - O.getMachineOperand().value = newVal; + O.getMachineOperand().contents.value = newVal; ++numSubst; } else @@ -175,7 +175,7 @@ notDefsAndUses && (getImplicitOp(i).isDef() && !getImplicitOp(i).isUse()) || !notDefsAndUses && getImplicitOp(i).isDef()) { - getImplicitOp(i).value = newVal; + getImplicitOp(i).contents.value = newVal; ++numSubst; } else Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.8.2.1 llvm/lib/CodeGen/VirtRegMap.cpp:1.8.2.2 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.8.2.1 Mon Mar 1 17:58:13 2004 +++ llvm/lib/CodeGen/VirtRegMap.cpp Wed Mar 10 19:33:31 2004 @@ -36,13 +36,14 @@ Statistic<> numStores("spiller", "Number of stores added"); Statistic<> numLoads ("spiller", "Number of loads added"); - enum SpillerName { local }; + enum SpillerName { simple, local }; cl::opt SpillerOpt("spiller", cl::desc("Spiller to use: (default: local)"), cl::Prefix, - cl::values(clEnumVal(local, " local spiller"), + cl::values(clEnumVal(simple, " simple spiller"), + clEnumVal(local, " local spiller"), 0), cl::init(local)); } @@ -105,6 +106,65 @@ namespace { + class SimpleSpiller : public Spiller { + public: + bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap& vrm) { + DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n"); + DEBUG(std::cerr << "********** Function: " + << mf.getFunction()->getName() << '\n'); + const TargetMachine& tm = mf.getTarget(); + const MRegisterInfo& mri = *tm.getRegisterInfo(); + + typedef DenseMap Loaded; + Loaded loaded; + + for (MachineFunction::iterator mbbi = mf.begin(), + mbbe = mf.end(); mbbi != mbbe; ++mbbi) { + DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n"); + for (MachineBasicBlock::iterator mii = mbbi->begin(), + mie = mbbi->end(); mii != mie; ++mii) { + loaded.grow(mf.getSSARegMap()->getLastVirtReg()); + for (unsigned i = 0,e = mii->getNumOperands(); i != e; ++i){ + MachineOperand& mop = mii->getOperand(i); + if (mop.isRegister() && mop.getReg() && + MRegisterInfo::isVirtualRegister(mop.getReg())) { + unsigned virtReg = mop.getReg(); + unsigned physReg = vrm.getPhys(virtReg); + if (mop.isUse() && + vrm.hasStackSlot(mop.getReg()) && + !loaded[virtReg]) { + mri.loadRegFromStackSlot( + *mbbi, + mii, + physReg, + vrm.getStackSlot(virtReg), + mf.getSSARegMap()->getRegClass(virtReg)); + loaded[virtReg] = true; + DEBUG(std::cerr << '\t'; + prior(mii)->print(std::cerr, tm)); + ++numLoads; + } + if (mop.isDef() && + vrm.hasStackSlot(mop.getReg())) { + mri.storeRegToStackSlot( + *mbbi, + next(mii), + physReg, + vrm.getStackSlot(virtReg), + mf.getSSARegMap()->getRegClass(virtReg)); + ++numStores; + } + mii->SetMachineOperandReg(i, physReg); + } + } + DEBUG(std::cerr << '\t'; mii->print(std::cerr, tm)); + loaded.clear(); + } + } + return true; + } + }; + class LocalSpiller : public Spiller { typedef std::vector Phys2VirtMap; typedef std::vector PhysFlag; @@ -157,10 +217,10 @@ MachineBasicBlock::iterator lastDef = lastDef_[virtReg]; MachineBasicBlock::iterator nextLastRef = next(lastDef); mri_->storeRegToStackSlot(*lastDef->getParent(), - nextLastRef, - physReg, - vrm_->getStackSlot(virtReg), - mri_->getRegClass(physReg)); + nextLastRef, + physReg, + vrm_->getStackSlot(virtReg), + mri_->getRegClass(physReg)); ++numStores; DEBUG(std::cerr << "added: "; prior(nextLastRef)->print(std::cerr, *tm_); @@ -191,8 +251,8 @@ // load if necessary if (vrm_->hasStackSlot(virtReg)) { mri_->loadRegFromStackSlot(mbb, mii, physReg, - vrm_->getStackSlot(virtReg), - mri_->getRegClass(physReg)); + vrm_->getStackSlot(virtReg), + mri_->getRegClass(physReg)); ++numLoads; DEBUG(std::cerr << "added: "; prior(mii)->print(std::cerr, *tm_)); @@ -223,8 +283,8 @@ // the value of the spilled virtual register VirtRegMap::MI2VirtMap::const_iterator i, e; for (tie(i, e) = vrm_->getFoldedVirts(mii); i != e; ++i) { - unsigned physReg = vrm_->getPhys(i->second); - if (physReg) vacateJustPhysReg(mbb, mii, physReg); + if (vrm_->hasPhys(i->second)) + vacateJustPhysReg(mbb, mii, vrm_->getPhys(i->second)); } // rewrite all used operands @@ -244,11 +304,19 @@ } } - // spill implicit defs + // spill implicit physical register defs const TargetInstrDescriptor& tid = tii_->get(mii->getOpcode()); for (const unsigned* id = tid.ImplicitDefs; *id; ++id) vacatePhysReg(mbb, mii, *id); + // spill explicit physical register defs + for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) { + MachineOperand& op = mii->getOperand(i); + if (op.isRegister() && op.getReg() && !op.isUse() && + MRegisterInfo::isPhysicalRegister(op.getReg())) + vacatePhysReg(mbb, mii, op.getReg()); + } + // rewrite def operands (def&use was handled with the // uses so don't check for those here) for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) { @@ -281,5 +349,7 @@ abort(); case local: return new LocalSpiller(); + case simple: + return new SimpleSpiller(); } } From brukman at cs.uiuc.edu Wed Mar 10 19:34:07 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:34:07 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/ExecutionEngine/JIT/Intercept.cpp Message-ID: <200403110133.TAA08399@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: Intercept.cpp updated: 1.13 -> 1.13.2.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+20 -0) Index: llvm/lib/ExecutionEngine/JIT/Intercept.cpp diff -u llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.13 llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.13.2.1 --- llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.13 Fri Dec 26 00:13:47 2003 +++ llvm/lib/ExecutionEngine/JIT/Intercept.cpp Wed Mar 10 19:33:44 2004 @@ -18,6 +18,7 @@ #include "JIT.h" #include "Support/DynamicLinker.h" #include +#include using namespace llvm; // AtExitHandlers - List of functions to call when the program exits, @@ -39,6 +40,25 @@ //===----------------------------------------------------------------------===// // Function stubs that are invoked instead of certain library calls //===----------------------------------------------------------------------===// + +// Force the following functions to be linked in to anything that uses the +// JIT. This is a hack designed to work around the all-too-clever Glibc +// strategy of making these functions work differently when inlined vs. when +// not inlined, and hiding their real definitions in a separate archive file +// that the dynamic linker can't see. For more info, search for +// 'libc_nonshared.a' on Google, or read http://llvm.cs.uiuc.edu/PR274. +#if defined(__linux__) +void *FunctionPointers[] = { + (void *) stat, + (void *) fstat, + (void *) lstat, + (void *) stat64, + (void *) fstat64, + (void *) lstat64, + (void *) atexit, + (void *) mknod +}; +#endif // __linux__ // NoopFn - Used if we have nothing else to call... static void NoopFn() {} From brukman at cs.uiuc.edu Wed Mar 10 19:35:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:35:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Instrumentation/EdgeProfiling.cpp ProfilingUtils.cpp ProfilingUtils.h BlockProfiling.cpp EmitFunctions.cpp Message-ID: <200403110134.TAA08440@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: EdgeProfiling.cpp added (r1.1.2.1) ProfilingUtils.cpp added (r1.1.2.1) ProfilingUtils.h added (r1.1.2.1) BlockProfiling.cpp updated: 1.5.2.1 -> 1.5.2.2 EmitFunctions.cpp updated: 1.14.4.1 -> 1.14.4.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+245 -99) Index: llvm/lib/Transforms/Instrumentation/EdgeProfiling.cpp diff -c /dev/null llvm/lib/Transforms/Instrumentation/EdgeProfiling.cpp:1.1.2.1 *** /dev/null Wed Mar 10 19:34:31 2004 --- llvm/lib/Transforms/Instrumentation/EdgeProfiling.cpp Wed Mar 10 19:34:21 2004 *************** *** 0 **** --- 1,94 ---- + //===- EdgeProfiling.cpp - Insert counters for edge profiling -------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This pass instruments the specified program with counters for edge profiling. + // Edge profiling can give a reasonable approximation of the hot paths through a + // program, and is used for a wide variety of program transformations. + // + // Note that this implementation is very naive. We insert a counter for *every* + // edge in the program, instead of using control flow information to prune the + // number of counters inserted. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Module.h" + #include "llvm/Pass.h" + #include "llvm/Transforms/Utils/BasicBlockUtils.h" + #include "ProfilingUtils.h" + #include + using namespace llvm; + + namespace { + class EdgeProfiler : public Pass { + bool run(Module &M); + }; + + RegisterOpt X("insert-edge-profiling", + "Insert instrumentation for edge profiling"); + } + + bool EdgeProfiler::run(Module &M) { + Function *Main = M.getMainFunction(); + if (Main == 0) { + std::cerr << "WARNING: cannot insert edge profiling into a module" + << " with no main function!\n"; + return false; // No main, no instrumentation! + } + + std::set BlocksToInstrument; + unsigned NumEdges = 0; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + // Keep track of which blocks need to be instrumented. We don't want to + // instrument blocks that are added as the result of breaking critical + // edges! + BlocksToInstrument.insert(BB); + NumEdges += BB->getTerminator()->getNumSuccessors(); + } + + const Type *ATy = ArrayType::get(Type::UIntTy, NumEdges); + GlobalVariable *Counters = + new GlobalVariable(ATy, false, GlobalValue::InternalLinkage, + Constant::getNullValue(ATy), "EdgeProfCounters", &M); + + ConstantPointerRef *CounterCPR = ConstantPointerRef::get(Counters); + + // Instrument all of the edges... + unsigned i = 0; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + if (BlocksToInstrument.count(BB)) { // Don't instrument inserted blocks + // Okay, we have to add a counter of each outgoing edge. If the + // outgoing edge is not critical don't split it, just insert the counter + // in the source or destination of the edge. + TerminatorInst *TI = BB->getTerminator(); + for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { + // If the edge is critical, split it. + SplitCriticalEdge(TI, s, this); + + // Okay, we are guaranteed that the edge is no longer critical. If we + // only have a single successor, insert the counter in this block, + // otherwise insert it in the successor block. + if (TI->getNumSuccessors() == 0) { + // Insert counter at the start of the block + IncrementCounterInBlock(BB, i++, CounterCPR); + } else { + // Insert counter at the start of the block + IncrementCounterInBlock(TI->getSuccessor(s), i++, CounterCPR); + } + } + } + + // Add the initialization call to main. + InsertProfilingInitCall(Main, "llvm_start_edge_profiling", Counters); + return true; + } + Index: llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp diff -c /dev/null llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp:1.1.2.1 *** /dev/null Wed Mar 10 19:34:31 2004 --- llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp Wed Mar 10 19:34:21 2004 *************** *** 0 **** --- 1,102 ---- + //===- ProfilingUtils.cpp - Helper functions shared by profilers ----------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This files implements a few helper functions which are used by profile + // instrumentation code to instrument the code. This allows the profiler pass + // to worry about *what* to insert, and these functions take care of *how* to do + // it. + // + //===----------------------------------------------------------------------===// + + #include "ProfilingUtils.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Instructions.h" + #include "llvm/Module.h" + + void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName, + GlobalValue *Array) { + const Type *ArgVTy = PointerType::get(PointerType::get(Type::SByteTy)); + const Type *UIntPtr = PointerType::get(Type::UIntTy); + Module &M = *MainFn->getParent(); + Function *InitFn = M.getOrInsertFunction(FnName, Type::IntTy, Type::IntTy, + ArgVTy, UIntPtr, Type::UIntTy, 0); + + // This could force argc and argv into programs that wouldn't otherwise have + // them, but instead we just pass null values in. + std::vector Args(4); + Args[0] = Constant::getNullValue(Type::IntTy); + Args[1] = Constant::getNullValue(ArgVTy); + + // Skip over any allocas in the entry block. + BasicBlock *Entry = MainFn->begin(); + BasicBlock::iterator InsertPos = Entry->begin(); + while (isa(InsertPos)) ++InsertPos; + + ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array); + std::vector GEPIndices(2, Constant::getNullValue(Type::LongTy)); + Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices); + + unsigned NumElements = + cast(Array->getType()->getElementType())->getNumElements(); + Args[3] = ConstantUInt::get(Type::UIntTy, NumElements); + + Instruction *InitCall = new CallInst(InitFn, Args, "newargc", InsertPos); + + // If argc or argv are not available in main, just pass null values in. + Function::aiterator AI; + switch (MainFn->asize()) { + default: + case 2: + AI = MainFn->abegin(); ++AI; + if (AI->getType() != ArgVTy) { + InitCall->setOperand(2, new CastInst(AI, ArgVTy, "argv.cast", InitCall)); + } else { + InitCall->setOperand(2, AI); + } + + case 1: + AI = MainFn->abegin(); + // If the program looked at argc, have it look at the return value of the + // init call instead. + if (AI->getType() != Type::IntTy) { + if (!AI->use_empty()) + AI->replaceAllUsesWith(new CastInst(InitCall, AI->getType(), "", + InsertPos)); + InitCall->setOperand(1, new CastInst(AI, Type::IntTy, "argc.cast", + InitCall)); + } else { + AI->replaceAllUsesWith(InitCall); + InitCall->setOperand(1, AI); + } + + case 0: break; + } + } + + void llvm::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, + ConstantPointerRef *CounterArray) { + // Insert the increment after any alloca or PHI instructions... + BasicBlock::iterator InsertPos = BB->begin(); + while (isa(InsertPos) || isa(InsertPos)) + ++InsertPos; + + // Create the getelementptr constant expression + std::vector Indices(2); + Indices[0] = Constant::getNullValue(Type::LongTy); + Indices[1] = ConstantSInt::get(Type::LongTy, CounterNum); + Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray, Indices); + + // Load, increment and store the value back. + Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); + Value *NewVal = BinaryOperator::create(Instruction::Add, OldVal, + ConstantInt::get(Type::UIntTy, 1), + "NewFuncCounter", InsertPos); + new StoreInst(NewVal, ElementPtr, InsertPos); + } Index: llvm/lib/Transforms/Instrumentation/ProfilingUtils.h diff -c /dev/null llvm/lib/Transforms/Instrumentation/ProfilingUtils.h:1.1.2.1 *** /dev/null Wed Mar 10 19:34:31 2004 --- llvm/lib/Transforms/Instrumentation/ProfilingUtils.h Wed Mar 10 19:34:21 2004 *************** *** 0 **** --- 1,32 ---- + //===- ProfilingUtils.h - Helper functions shared by profilers --*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This files defines a few helper functions which are used by profile + // instrumentation code to instrument the code. This allows the profiler pass + // to worry about *what* to insert, and these functions take care of *how* to do + // it. + // + //===----------------------------------------------------------------------===// + + #ifndef PROFILINGUTILS_H + #define PROFILINGUTILS_H + + namespace llvm { + class Function; + class GlobalValue; + class ConstantPointerRef; + class BasicBlock; + + void InsertProfilingInitCall(Function *MainFn, const char *FnName, + GlobalValue *Arr); + void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, + ConstantPointerRef *CounterArray); + } + + #endif Index: llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp diff -u llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp:1.5.2.1 llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp:1.5.2.2 --- llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp:1.5.2.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/Transforms/Instrumentation/BlockProfiling.cpp Wed Mar 10 19:34:21 2004 @@ -21,93 +21,11 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Pass.h" +#include "ProfilingUtils.h" using namespace llvm; -static void insertInitializationCall(Function *MainFn, const char *FnName, - GlobalValue *Array) { - const Type *ArgVTy = PointerType::get(PointerType::get(Type::SByteTy)); - const Type *UIntPtr = PointerType::get(Type::UIntTy); - Module &M = *MainFn->getParent(); - Function *InitFn = M.getOrInsertFunction(FnName, Type::IntTy, Type::IntTy, - ArgVTy, UIntPtr, Type::UIntTy, 0); - - // This could force argc and argv into programs that wouldn't otherwise have - // them, but instead we just pass null values in. - std::vector Args(4); - Args[0] = Constant::getNullValue(Type::IntTy); - Args[1] = Constant::getNullValue(ArgVTy); - - // Skip over any allocas in the entry block. - BasicBlock *Entry = MainFn->begin(); - BasicBlock::iterator InsertPos = Entry->begin(); - while (isa(InsertPos)) ++InsertPos; - - ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array); - std::vector GEPIndices(2, Constant::getNullValue(Type::LongTy)); - Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices); - - unsigned NumElements = - cast(Array->getType()->getElementType())->getNumElements(); - Args[3] = ConstantUInt::get(Type::UIntTy, NumElements); - - Instruction *InitCall = new CallInst(InitFn, Args, "newargc", InsertPos); - - // If argc or argv are not available in main, just pass null values in. - Function::aiterator AI; - switch (MainFn->asize()) { - default: - case 2: - AI = MainFn->abegin(); ++AI; - if (AI->getType() != ArgVTy) { - InitCall->setOperand(2, new CastInst(AI, ArgVTy, "argv.cast", InitCall)); - } else { - InitCall->setOperand(2, AI); - } - - case 1: - AI = MainFn->abegin(); - // If the program looked at argc, have it look at the return value of the - // init call instead. - if (AI->getType() != Type::IntTy) { - if (!AI->use_empty()) - AI->replaceAllUsesWith(new CastInst(InitCall, AI->getType(), "", - InsertPos)); - InitCall->setOperand(1, new CastInst(AI, Type::IntTy, "argc.cast", - InitCall)); - } else { - AI->replaceAllUsesWith(InitCall); - InitCall->setOperand(1, AI); - } - - case 0: break; - } -} - -static void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, - ConstantPointerRef *CounterArray) { - // Insert the increment after any alloca or PHI instructions... - BasicBlock::iterator InsertPos = BB->begin(); - while (isa(InsertPos) || isa(InsertPos)) - ++InsertPos; - - // Create the getelementptr constant expression - std::vector Indices(2); - Indices[0] = Constant::getNullValue(Type::LongTy); - Indices[1] = ConstantSInt::get(Type::LongTy, CounterNum); - Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray, Indices); - - // Load, increment and store the value back. - Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); - Value *NewVal = BinaryOperator::create(Instruction::Add, OldVal, - ConstantInt::get(Type::UIntTy, 1), - "NewFuncCounter", InsertPos); - new StoreInst(NewVal, ElementPtr, InsertPos); -} - - namespace { class FunctionProfiler : public Pass { bool run(Module &M); @@ -145,7 +63,7 @@ IncrementCounterInBlock(I->begin(), i++, CounterCPR); // Add the initialization call to main. - insertInitializationCall(Main, "llvm_start_func_profiling", Counters); + InsertProfilingInitCall(Main, "llvm_start_func_profiling", Counters); return true; } @@ -186,7 +104,7 @@ IncrementCounterInBlock(BB, i++, CounterCPR); // Add the initialization call to main. - insertInitializationCall(Main, "llvm_start_block_profiling", Counters); + InsertProfilingInitCall(Main, "llvm_start_block_profiling", Counters); return true; } Index: llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp diff -u llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp:1.14.4.1 llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp:1.14.4.2 --- llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp:1.14.4.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/Transforms/Instrumentation/EmitFunctions.cpp Wed Mar 10 19:34:21 2004 @@ -7,7 +7,9 @@ // //===----------------------------------------------------------------------===// // -// This inserts a global constant table with function pointers all along +// This inserts a global constant table with function pointers all along. +// +// NOTE: This pass is used by the reoptimizer only. // //===----------------------------------------------------------------------===// @@ -16,24 +18,24 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" - -namespace llvm { - -enum Color{ - WHITE, - GREY, - BLACK -}; +using namespace llvm; namespace { + enum Color{ + WHITE, + GREY, + BLACK + }; + struct EmitFunctionTable : public Pass { bool run(Module &M); }; - RegisterOpt X("emitfuncs", "Emit a Function Table"); + RegisterOpt + X("emitfuncs", "Emit a function table for the reoptimizer"); } -char doDFS(BasicBlock * node,std::map &color){ +static char doDFS(BasicBlock * node,std::map &color){ color[node] = GREY; for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){ @@ -56,7 +58,7 @@ return 1; } -char hasBackEdge(Function *F){ +static char hasBackEdge(Function *F){ std::map color; return doDFS(F->begin(), color); } @@ -106,5 +108,3 @@ M.getGlobalList().push_back(fnCount); return true; // Always modifies program } - -} // End llvm namespace From brukman at cs.uiuc.edu Wed Mar 10 19:35:08 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:35:08 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Support/CommandLine.cpp Message-ID: <200403110134.TAA08420@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: CommandLine.cpp updated: 1.42 -> 1.42.2.1 --- Log message: Merge from trunk. --- Diffs of the changes: (+3 -2) Index: llvm/lib/Support/CommandLine.cpp diff -u llvm/lib/Support/CommandLine.cpp:1.42 llvm/lib/Support/CommandLine.cpp:1.42.2.1 --- llvm/lib/Support/CommandLine.cpp:1.42 Sun Dec 14 15:35:53 2003 +++ llvm/lib/Support/CommandLine.cpp Wed Mar 10 19:34:00 2004 @@ -48,8 +48,9 @@ } static std::vector &getPositionalOpts() { - static std::vector Positional; - return Positional; + static std::vector *Positional = 0; + if (!Positional) Positional = new std::vector(); + return *Positional; } static void AddArgument(const char *ArgName, Option *Opt) { From brukman at cs.uiuc.edu Wed Mar 10 19:35:14 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:35:14 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Scalar/LowerAllocations.cpp SCCP.cpp Message-ID: <200403110134.TAA08466@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerAllocations.cpp updated: 1.43.2.1 -> 1.43.2.2 SCCP.cpp updated: 1.88.2.1 -> 1.88.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+7 -1) Index: llvm/lib/Transforms/Scalar/LowerAllocations.cpp diff -u llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.43.2.1 llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.43.2.2 --- llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.43.2.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/Transforms/Scalar/LowerAllocations.cpp Wed Mar 10 19:34:31 2004 @@ -101,7 +101,7 @@ Value *MallocArg = ConstantUInt::get(Type::UIntTy, Size); if (MI->getNumOperands() && Size == 1) { MallocArg = MI->getOperand(0); // Operand * 1 = Operand - } else if (MI->getNumOperands()) { + } else if (MI->isArrayAllocation()) { // Multiply it by the array size if necessary... MallocArg = BinaryOperator::create(Instruction::Mul, MI->getOperand(0), MallocArg, "", I); Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.88.2.1 llvm/lib/Transforms/Scalar/SCCP.cpp:1.88.2.2 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.88.2.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Wed Mar 10 19:34:31 2004 @@ -713,6 +713,12 @@ if (PtrVal.isUndefined()) return; // The pointer is not resolved yet! if (PtrVal.isConstant() && !I.isVolatile()) { Value *Ptr = PtrVal.getConstant(); + if (isa(Ptr)) { + // load null -> null + markConstant(IV, &I, Constant::getNullValue(I.getType())); + return; + } + if (ConstantPointerRef *CPR = dyn_cast(Ptr)) Ptr = CPR->getValue(); From brukman at cs.uiuc.edu Wed Mar 10 19:37:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:37:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/VMCore/AsmWriter.cpp ConstantFolding.cpp Constants.cpp IntrinsicLowering.cpp Module.cpp Pass.cpp Verifier.cpp Message-ID: <200403110136.TAA08545@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.116.2.1 -> 1.116.2.2 ConstantFolding.cpp updated: 1.50.2.1 -> 1.50.2.2 Constants.cpp updated: 1.71.2.1 -> 1.71.2.2 IntrinsicLowering.cpp updated: 1.5.2.2 -> 1.5.2.3 Module.cpp updated: 1.47 -> 1.47.2.1 Pass.cpp updated: 1.54.4.1 -> 1.54.4.2 Verifier.cpp updated: 1.78.2.3 -> 1.78.2.4 --- Log message: Merge from trunk. --- Diffs of the changes: (+70 -105) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.116.2.1 llvm/lib/VMCore/AsmWriter.cpp:1.116.2.2 --- llvm/lib/VMCore/AsmWriter.cpp:1.116.2.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/VMCore/AsmWriter.cpp Wed Mar 10 19:36:09 2004 @@ -97,9 +97,9 @@ } -// If the module has a symbol table, take all global types and stuff their -// names into the TypeNames map. -// +/// fillTypeNameTable - If the module has a symbol table, take all global types +/// and stuff their names into the TypeNames map. +/// static void fillTypeNameTable(const Module *M, std::map &TypeNames) { if (!M) return; @@ -381,10 +381,10 @@ } -// WriteAsOperand - Write the name of the specified value out to the specified -// ostream. This can be useful when you just want to print int %reg126, not the -// whole instruction that generated it. -// +/// WriteAsOperand - Write the name of the specified value out to the specified +/// ostream. This can be useful when you just want to print int %reg126, not +/// the whole instruction that generated it. +/// static void WriteAsOperandInternal(std::ostream &Out, const Value *V, bool PrintName, std::map &TypeTable, @@ -422,7 +422,6 @@ } - /// WriteAsOperand - Write the name of the specified value out to the specified /// ostream. This can be useful when you just want to print int %reg126, not /// the whole instruction that generated it. @@ -503,9 +502,9 @@ }; } // end of anonymous namespace -// printTypeAtLeastOneLevel - Print out one level of the possibly complex type -// without considering any symbolic types that we may have equal to it. -// +/// printTypeAtLeastOneLevel - Print out one level of the possibly complex type +/// without considering any symbolic types that we may have equal to it. +/// std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { if (const FunctionType *FTy = dyn_cast(Ty)) { printType(FTy->getReturnType()) << " ("; @@ -602,9 +601,9 @@ } -// printSymbolTable - Run through symbol table looking for named constants -// if a named constant is found, emit it's declaration... -// +/// printSymbolTable - Run through symbol table looking for named constants +/// if a named constant is found, emit it's declaration... +/// void AssemblyWriter::printSymbolTable(const SymbolTable &ST) { for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) { SymbolTable::type_const_iterator I = ST.type_begin(TI->first); @@ -628,8 +627,8 @@ } -// printConstant - Print out a constant pool entry... -// +/// printConstant - Print out a constant pool entry... +/// void AssemblyWriter::printConstant(const Constant *CPV) { // Don't print out unnamed constants, they will be inlined if (!CPV->hasName()) return; @@ -644,8 +643,8 @@ Out << "\n"; } -// printFunction - Print all aspects of a function. -// +/// printFunction - Print all aspects of a function. +/// void AssemblyWriter::printFunction(const Function *F) { // Print out the return type and name... Out << "\n"; @@ -699,9 +698,9 @@ Table.purgeFunction(); } -// printArgument - This member is called for every argument that -// is passed into the function. Simply print it out -// +/// printArgument - This member is called for every argument that is passed into +/// the function. Simply print it out +/// void AssemblyWriter::printArgument(const Argument *Arg) { // Insert commas as we go... the first arg doesn't get a comma if (Arg != &Arg->getParent()->afront()) Out << ", "; @@ -716,8 +715,8 @@ Out << ""; } -// printBasicBlock - This member is called for each basic block in a method. -// +/// printBasicBlock - This member is called for each basic block in a method. +/// void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (BB->hasName()) { // Print out the label if it exists... Out << "\n" << BB->getName() << ":"; @@ -753,17 +752,19 @@ Out << "\n"; - if (AnnotationWriter) AnnotationWriter->emitBasicBlockAnnot(BB, Out); + if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out); // Output all of the instructions in the basic block... for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) printInstruction(*I); + + if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } -// printInfoComment - Print a little comment after the instruction indicating -// which slot it occupies. -// +/// printInfoComment - Print a little comment after the instruction indicating +/// which slot it occupies. +/// void AssemblyWriter::printInfoComment(const Value &V) { if (V.getType() != Type::VoidTy) { Out << "\t\t; <"; @@ -778,8 +779,8 @@ } } -// printInstruction - This member is called for each Instruction in a method. -// +/// printInstruction - This member is called for each Instruction in a method. +/// void AssemblyWriter::printInstruction(const Instruction &I) { if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out); Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.50.2.1 llvm/lib/VMCore/ConstantFolding.cpp:1.50.2.2 --- llvm/lib/VMCore/ConstantFolding.cpp:1.50.2.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/VMCore/ConstantFolding.cpp Wed Mar 10 19:36:09 2004 @@ -22,6 +22,7 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/DerivedTypes.h" +#include "llvm/Function.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include using namespace llvm; @@ -523,6 +524,15 @@ const Type *DestTy) { if (V->getType() == DestTy) return (Constant*)V; + // Cast of a global address to boolean is always true. + if (const ConstantPointerRef *CPR = dyn_cast(V)) + if (DestTy == Type::BoolTy) + // FIXME: When we support 'external weak' references, we have to prevent + // this transformation from happening. In the meantime we avoid folding + // any cast of an external symbol. + if (!CPR->getValue()->isExternal()) + return ConstantBool::True; + if (const ConstantExpr *CE = dyn_cast(V)) if (CE->getOpcode() == Instruction::Cast) { Constant *Op = const_cast(CE->getOperand(0)); @@ -873,6 +883,16 @@ if (cast(V2)->isAllOnesValue()) return const_cast(V1); // X & -1 == X if (V2->isNullValue()) return const_cast(V2); // X & 0 == 0 + if (CE1->getOpcode() == Instruction::Cast && + isa(CE1->getOperand(0))) { + ConstantPointerRef *CPR =cast(CE1->getOperand(0)); + + // Functions are at least 4-byte aligned. If and'ing the address of a + // function with a constant < 4, fold it to zero. + if (const ConstantInt *CI = dyn_cast(V2)) + if (CI->getRawValue() < 4 && isa(CPR->getValue())) + return Constant::getNullValue(CI->getType()); + } break; case Instruction::Or: if (V2->isNullValue()) return const_cast(V1); // X | 0 == X Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.71.2.1 llvm/lib/VMCore/Constants.cpp:1.71.2.2 --- llvm/lib/VMCore/Constants.cpp:1.71.2.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/VMCore/Constants.cpp Wed Mar 10 19:36:09 2004 @@ -1119,26 +1119,3 @@ const char *ConstantExpr::getOpcodeName() const { return Instruction::getOpcodeName(getOpcode()); } - -unsigned Constant::mutateReferences(Value *OldV, Value *NewV) { - // Uses of constant pointer refs are global values, not constants! - if (ConstantPointerRef *CPR = dyn_cast(this)) { - GlobalValue *NewGV = cast(NewV); - GlobalValue *OldGV = CPR->getValue(); - - assert(OldGV == OldV && "Cannot mutate old value if I'm not using it!"); - Operands[0] = NewGV; - OldGV->getParent()->mutateConstantPointerRef(OldGV, NewGV); - return 1; - } else { - Constant *NewC = cast(NewV); - unsigned NumReplaced = 0; - for (unsigned i = 0, N = getNumOperands(); i != N; ++i) - if (Operands[i] == OldV) { - ++NumReplaced; - Operands[i] = NewC; - } - return NumReplaced; - } -} - Index: llvm/lib/VMCore/IntrinsicLowering.cpp diff -u llvm/lib/VMCore/IntrinsicLowering.cpp:1.5.2.2 llvm/lib/VMCore/IntrinsicLowering.cpp:1.5.2.3 --- llvm/lib/VMCore/IntrinsicLowering.cpp:1.5.2.2 Mon Mar 1 17:58:16 2004 +++ llvm/lib/VMCore/IntrinsicLowering.cpp Wed Mar 10 19:36:09 2004 @@ -125,11 +125,6 @@ CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); break; // Simply strip out debugging intrinsics - case Intrinsic::join: - // Insert the call to abort - new CallInst(M->getOrInsertFunction("abort", Type::VoidTy, 0), "", CI); - break; - case Intrinsic::memcpy: // The memcpy intrinsic take an extra alignment argument that the memcpy // libc function does not. Index: llvm/lib/VMCore/Module.cpp diff -u llvm/lib/VMCore/Module.cpp:1.47 llvm/lib/VMCore/Module.cpp:1.47.2.1 --- llvm/lib/VMCore/Module.cpp:1.47 Wed Dec 31 02:43:01 2003 +++ llvm/lib/VMCore/Module.cpp Wed Mar 10 19:36:09 2004 @@ -335,28 +335,3 @@ GVRefMap = 0; } } - -void Module::mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV) { - assert(OldGV != NewGV && "Cannot mutate to the same global!"); - GlobalValueRefMap::iterator I = GVRefMap->Map.find(OldGV); - assert(I != GVRefMap->Map.end() && - "mutateConstantPointerRef; OldGV not in table!"); - ConstantPointerRef *Ref = I->second; - - // Remove the old entry... - GVRefMap->Map.erase(I); - - // Check to see if a CPR already exists for NewGV - I = GVRefMap->Map.lower_bound(NewGV); - - if (I == GVRefMap->Map.end() || I->first != NewGV) { - // Insert the new entry... - GVRefMap->Map.insert(I, std::make_pair(NewGV, Ref)); - } else { - // Otherwise, an entry already exists for the current global value. - // Completely replace the old CPR with the existing one... - Ref->replaceAllUsesWith(I->second); - delete Ref; - } -} - Index: llvm/lib/VMCore/Pass.cpp diff -u llvm/lib/VMCore/Pass.cpp:1.54.4.1 llvm/lib/VMCore/Pass.cpp:1.54.4.2 --- llvm/lib/VMCore/Pass.cpp:1.54.4.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/VMCore/Pass.cpp Wed Mar 10 19:36:09 2004 @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/PassManager.h" #include "PassManagerT.h" // PassManagerT implementation +#include "llvm/PassManager.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "Support/STLExtras.h" Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.78.2.3 llvm/lib/VMCore/Verifier.cpp:1.78.2.4 --- llvm/lib/VMCore/Verifier.cpp:1.78.2.3 Mon Mar 1 17:58:16 2004 +++ llvm/lib/VMCore/Verifier.cpp Wed Mar 10 19:36:09 2004 @@ -62,8 +62,8 @@ bool Broken; // Is this module found to be broken? bool RealPass; // Are we not being run by a PassManager? bool AbortBroken; // If broken, should it or should it not abort? - Module *Mod; // Module we are verifying right now - DominatorSet *DS; // Dominator set, caution can be null! + Module *Mod; // Module we are verifying right now + DominatorSet *DS; // Dominator set, caution can be null! Verifier() : Broken(false), RealPass(true), AbortBroken(true), DS(0) {} Verifier(bool AB) : Broken(false), RealPass(true), AbortBroken(AB), DS(0) {} @@ -78,7 +78,6 @@ // If this is a real pass, in a pass manager, we must abort before // returning back to the pass manager, or else the pass manager may try to // run other passes on the broken module. - // if (RealPass) abortIfBroken(); return false; @@ -92,7 +91,6 @@ // If this is a real pass, in a pass manager, we must abort before // returning back to the pass manager, or else the pass manager may try to // run other passes on the broken module. - // if (RealPass) abortIfBroken(); @@ -118,9 +116,9 @@ AU.addRequired(); } - // abortIfBroken - If the module is broken and we are supposed to abort on - // this condition, do so. - // + /// abortIfBroken - If the module is broken and we are supposed to abort on + /// this condition, do so. + /// void abortIfBroken() const { if (Broken && AbortBroken) { std::cerr << "Broken module found, compilation aborted!\n"; @@ -167,7 +165,6 @@ // CheckFailed - A check failed, so print out the condition and the message // that failed. This provides a nice place to put a breakpoint if you want // to see why something is not correct. - // void CheckFailed(const std::string &Message, const Value *V1 = 0, const Value *V2 = 0, const Value *V3 = 0, const Value *V4 = 0) { @@ -338,15 +335,16 @@ visitTerminatorInst(RI); } -// visitUserOp1 - User defined operators shouldn't live beyond the lifetime of a -// pass, if any exist, it's an error. -// +/// visitUserOp1 - User defined operators shouldn't live beyond the lifetime of +/// a pass, if any exist, it's an error. +/// void Verifier::visitUserOp1(Instruction &I) { Assert1(0, "User-defined operators should not live outside of a pass!", &I); } -// visitPHINode - Ensure that a PHI node is well formed. +/// visitPHINode - Ensure that a PHI node is well formed. +/// void Verifier::visitPHINode(PHINode &PN) { // Ensure that the PHI nodes are all grouped together at the top of the block. // This can be tested by checking whether the instruction before this is @@ -397,9 +395,9 @@ visitInstruction(CI); } -// visitBinaryOperator - Check that both arguments to the binary operator are -// of the same type! -// +/// visitBinaryOperator - Check that both arguments to the binary operator are +/// of the same type! +/// void Verifier::visitBinaryOperator(BinaryOperator &B) { Assert1(B.getOperand(0)->getType() == B.getOperand(1)->getType(), "Both operands to a binary operator are not of the same type!", &B); @@ -465,8 +463,8 @@ } -// verifyInstruction - Verify that an instruction is well formed. -// +/// verifyInstruction - Verify that an instruction is well formed. +/// void Verifier::visitInstruction(Instruction &I) { BasicBlock *BB = I.getParent(); Assert1(BB, "Instruction not embedded in basic block!", &I); @@ -486,7 +484,6 @@ // Check that all uses of the instruction, if they are instructions // themselves, actually have parent basic blocks. If the use is not an // instruction, it is an error! - // for (User::use_iterator UI = I.use_begin(), UE = I.use_end(); UI != UE; ++UI) { Assert1(isa(*UI), "Use of instruction is not an instruction!", @@ -507,7 +504,6 @@ BasicBlock *OpBlock = Op->getParent(); // Check that a definition dominates all of its uses. - // if (!isa(I)) { // Invoke results are only usable in the normal destination, not in the // exceptional destination. @@ -531,6 +527,7 @@ } /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways. +/// void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Function *IF = CI.getCalledFunction(); const FunctionType *FT = IF->getFunctionType(); @@ -629,9 +626,9 @@ return V.Broken; } -// verifyModule - Check a module for errors, printing messages on stderr. -// Return true if the module is corrupt. -// +/// verifyModule - Check a module for errors, printing messages on stderr. +/// Return true if the module is corrupt. +/// bool llvm::verifyModule(const Module &M) { PassManager PM; Verifier *V = new Verifier(); From brukman at cs.uiuc.edu Wed Mar 10 19:44:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:44:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp LoopExtractor.cpp Message-ID: <200403110143.TAA08648@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.2.2.1 -> 1.2.2.2 LoopExtractor.cpp updated: 1.2.2.1 -> 1.2.2.2 --- Log message: Merge from trunk. --- Diffs of the changes: (+11 -4) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.2.2.1 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.2.2.2 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.2.2.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Wed Mar 10 19:42:55 2004 @@ -443,7 +443,7 @@ brInst); } - // Rewrite branches into exists which return a value based on which + // Rewrite branches into exits which return a value based on which // exit we take from this function if (brInst->isUnconditional()) { if (!contains(code, brInst->getSuccessor(0))) { @@ -564,6 +564,14 @@ moveCodeToFunction(code, newFunction); return newFunction; +} + +/// ExtractCodeRegion - slurp a sequence of basic blocks into a brand new +/// function +/// +Function* llvm::ExtractCodeRegion(const std::vector &code) { + CodeExtractor CE; + return CE.ExtractCodeRegion(code); } /// ExtractBasicBlock - slurp a natural loop into a brand new function Index: llvm/lib/Transforms/Utils/LoopExtractor.cpp diff -u llvm/lib/Transforms/Utils/LoopExtractor.cpp:1.2.2.1 llvm/lib/Transforms/Utils/LoopExtractor.cpp:1.2.2.2 --- llvm/lib/Transforms/Utils/LoopExtractor.cpp:1.2.2.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/Transforms/Utils/LoopExtractor.cpp Wed Mar 10 19:42:55 2004 @@ -2,7 +2,8 @@ // // A pass wrapper around the ExtractLoop() scalar transformation to extract each // top-level loop into its own new function. If the loop is the ONLY loop in a -// given function, it is not touched. +// given function, it is not touched. This is a pass most useful for debugging +// via bugpoint. // //===----------------------------------------------------------------------===// @@ -57,8 +58,6 @@ return Changed; } - - } // End anonymous namespace From brukman at cs.uiuc.edu Wed Mar 10 19:52:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Mar 10 19:52:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/InstSelectSimple.cpp Makefile README.txt SparcV8.h SparcV8.td SparcV8AsmPrinter.cpp SparcV8CodeEmitter.cpp SparcV8InstrInfo.cpp SparcV8InstrInfo.h SparcV8InstrInfo.td SparcV8InstrInfo_F2.td SparcV8InstrInfo_F3.td SparcV8JITInfo.h SparcV8RegisterInfo.cpp SparcV8RegisterInfo.h SparcV8RegisterInfo.td SparcV8TargetMachine.cpp SparcV8TargetMachine.h Message-ID: <200403110151.TAA08778@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: InstSelectSimple.cpp (r1.6) removed Makefile (r1.2) removed README.txt (r1.1) removed SparcV8.h (r1.3) removed SparcV8.td (r1.3) removed SparcV8AsmPrinter.cpp (r1.3) removed SparcV8CodeEmitter.cpp (r1.1) removed SparcV8InstrInfo.cpp (r1.3) removed SparcV8InstrInfo.h (r1.2) removed SparcV8InstrInfo.td (r1.5) removed SparcV8InstrInfo_F2.td (r1.1) removed SparcV8InstrInfo_F3.td (r1.1) removed SparcV8JITInfo.h (r1.1) removed SparcV8RegisterInfo.cpp (r1.5) removed SparcV8RegisterInfo.h (r1.1) removed SparcV8RegisterInfo.td (r1.7) removed SparcV8TargetMachine.cpp (r1.6) removed SparcV8TargetMachine.h (r1.2) removed --- Log message: These files are being moved out as they are not mature enough to be released. --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Mar 10 20:51:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Mar 10 20:51:01 2004 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200403110250.UAA09109@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.19 -> 1.20 --- Log message: Embed a floating frame of the bugzilla query in the page. This way people looking for open projects cannot miss the link :-) --- Diffs of the changes: (+11 -4) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.19 llvm/docs/OpenProjects.html:1.20 --- llvm/docs/OpenProjects.html:1.19 Wed Mar 10 13:38:33 2004 +++ llvm/docs/OpenProjects.html Wed Mar 10 20:50:35 2004 @@ -52,9 +52,16 @@ to the LLVM Developer's mailing list, so that we know the project is being worked on. Additionally this is a good way to get more information about a specific project -or to suggest other projects to add to this page. Another good place to look -for ideas is the LLVM bug -tracker by querying for unassigned enhancements.

    +or to suggest other projects to add to this page. +

    + +

    The projects in this page are open ended. More specific projects are +filed as unassigned enhancements in our +LLVM bug tracker. Here is the current list: +

    + + @@ -324,7 +331,7 @@
    Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/10 19:38:33 $ + Last modified: $Date: 2004/03/11 02:50:35 $ From gaeke at cs.uiuc.edu Wed Mar 10 22:43:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Mar 10 22:43:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/Makefile Message-ID: <200403110442.WAA09569@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Makefile updated: 1.13 -> 1.14 --- Log message: Remove ghostly directory from the build --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/Makefile diff -u llvm/lib/Target/Makefile:1.13 llvm/lib/Target/Makefile:1.14 --- llvm/lib/Target/Makefile:1.13 Sat Feb 28 13:54:00 2004 +++ llvm/lib/Target/Makefile Wed Mar 10 22:42:41 2004 @@ -7,7 +7,7 @@ # ##===----------------------------------------------------------------------===## LEVEL = ../.. -DIRS = CBackend X86 SparcV9 SparcV8 PowerPC +DIRS = CBackend X86 SparcV9 PowerPC LIBRARYNAME = target BUILD_ARCHIVE = 1 From gaeke at cs.uiuc.edu Thu Mar 11 00:46:07 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Mar 11 00:46:07 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp PhyRegAlloc.h Message-ID: <200403110646.AAA25638@kain.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: PhyRegAlloc.cpp updated: 1.142 -> 1.143 PhyRegAlloc.h updated: 1.63 -> 1.64 --- Log message: In PhyRegAlloc::saveState(), dump Arguments' saved-state, and try to make the output more compact. Divorce state-saving from the doFinalization method; for some reason it's not getting called when I want it to, at Reoptimizer time. Put the guts in PhyRegAlloc::finishSavingState(). Put an abort() in it so that I can be really really sure that it's getting called. Update comments. --- Diffs of the changes: (+31 -10) Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.142 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.143 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.142 Wed Mar 10 16:21:03 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Thu Mar 11 00:45:51 2004 @@ -1186,14 +1186,27 @@ /// void PhyRegAlloc::verifySavedState () { std::vector &state = FnAllocState[Fn]; + int ArgNum = 0; + for (Function::const_aiterator i=Fn->abegin (), e=Fn->aend (); i != e; ++i) { + const Argument *Arg = &*i; + std::cerr << "Argument: " << *Arg << "\n" + << "FnAllocState:\n"; + for (unsigned i = 0; i < state.size (); ++i) { + AllocInfo &S = state[i]; + if (S.Instruction == -1 && S.Operand == ArgNum) + std::cerr << " " << S << "\n"; + } + std::cerr << "----------\n"; + ++ArgNum; + } int Insn = 0; for (const_inst_iterator II=inst_begin (Fn), IE=inst_end (Fn); II!=IE; ++II) { const Instruction *I = *II; MachineCodeForInstruction &Instrs = MachineCodeForInstruction::get (I); - std::cerr << "Instruction:\n" << " " << *I << "\n" + std::cerr << "Instruction: " << *I << "MachineCodeForInstruction:\n"; for (unsigned i = 0, n = Instrs.size (); i != n; ++i) - std::cerr << " " << *Instrs[i] << "\n"; + std::cerr << " " << *Instrs[i]; std::cerr << "FnAllocState:\n"; for (unsigned i = 0; i < state.size (); ++i) { AllocInfo &S = state[i]; @@ -1206,21 +1219,29 @@ } +bool PhyRegAlloc::doFinalization (Module &M) { + if (SaveRegAllocState) finishSavingState (M); + return false; +} + + /// Finish the job of saveState(), by collapsing FnAllocState into an LLVM -/// Constant and stuffing it inside the Module. (NOTE: Soon, there will be -/// other, better ways of storing the saved state; this one is cumbersome and -/// does not work well with the JIT.) +/// Constant and stuffing it inside the Module. /// -bool PhyRegAlloc::doFinalization (Module &M) { - if (!SaveRegAllocState) - return false; // Nothing to do here, unless we're saving state. +/// FIXME: There should be other, better ways of storing the saved +/// state; this one is cumbersome and does not work well with the JIT. +/// +void PhyRegAlloc::finishSavingState (Module &M) { + std::cerr << "---- Saving reg. alloc state; SaveStateToModule = " + << SaveStateToModule << " ----\n"; + abort (); // If saving state into the module, just copy new elements to the // correct global. if (!SaveStateToModule) { ExportedFnAllocState = FnAllocState; // FIXME: should ONLY copy new elements in FnAllocState - return false; + return; } // Convert FnAllocState to a single Constant array and add it @@ -1282,7 +1303,6 @@ new GlobalVariable (ST2, true, GlobalValue::ExternalLinkage, ConstantStruct::get (ST2, CV2), "_llvm_regAllocState", &M); - return false; // No error. } Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.63 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.64 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h:1.63 Mon Mar 8 17:22:03 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h Thu Mar 11 00:45:52 2004 @@ -129,6 +129,7 @@ const Value *V, int Insn, int Opnd); void saveState(); void verifySavedState(); + void finishSavingState(Module &M); void setCallInterferences(const MachineInstr *MI, const ValueSet *LVSetAft); From gaeke at cs.uiuc.edu Thu Mar 11 03:34:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Mar 11 03:34:01 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Message-ID: <200403110933.DAA21192@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: UnpackTraceFunction.cpp updated: 1.43 -> 1.44 --- Log message: Add more debugging info and assertions. --- Diffs of the changes: (+8 -0) Index: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp diff -u reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.43 reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.44 --- reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.43 Wed Mar 10 13:03:45 2004 +++ reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Thu Mar 11 03:33:04 2004 @@ -200,6 +200,8 @@ static AllocInfo getValueAllocStateFromModule (Function *F, Value *V) { unsigned FI = getLLVMFunctionPositionInfo (F); FunctionAllocState *FAllocState = _llvm_regAllocState.functions[FI]; + assert (FAllocState->numTuples > 0 + && "Reg. alloc state for function is empty"); int InstructionKey = -1, OperandKey = -1; if (Argument *A = dyn_cast (V)) { // Find the alloc state of an argument. @@ -236,6 +238,7 @@ unsigned FI = getLLVMFunctionPositionInfo (F); // Get the saved PhyRegAlloc state for F out of ExportedFnAllocState: std::vector &FState = ExportedFnAllocState[F]; + assert (FState.size () > 0 && "Reg. alloc state for function is empty"); int InstructionKey = -1, OperandKey = -1; if (Argument *A = dyn_cast (V)) { // Find the alloc state of an argument. @@ -252,8 +255,13 @@ } // Reconstruct the AllocInfo for V by searching // FState for a tuple that starts with (InstructionKey, OperandKey, ...): + DEBUG(std::cerr << "Looking for " << F->getName () << "()'s value " + << *V << "(Instruction " << InstructionKey << " Operand " + << OperandKey << ")... " << FState.size () + << " tuples to search.\n"); for (unsigned i = 0, s = FState.size (); i < s; ++i) { AllocInfo &T = FState[i]; + DEBUG(std::cerr << "Considering: " << T << "\n"); if (T.Instruction == InstructionKey && T.Operand == OperandKey) return T; } From alkis at cs.uiuc.edu Thu Mar 11 04:15:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Mar 11 04:15:02 2004 Subject: [llvm-commits] CVS: llvm/docs/Stacker.html Message-ID: <200403111014.EAA25996@zion.cs.uiuc.edu> Changes in directory llvm/docs: Stacker.html updated: 1.7 -> 1.8 --- Log message: Fix spelling. --- Diffs of the changes: (+2 -2) Index: llvm/docs/Stacker.html diff -u llvm/docs/Stacker.html:1.7 llvm/docs/Stacker.html:1.8 --- llvm/docs/Stacker.html:1.7 Thu Dec 18 10:43:14 2003 +++ llvm/docs/Stacker.html Thu Mar 11 04:14:21 2004 @@ -346,7 +346,7 @@ carefully. Then, read it again.

    Here are some handy tips that I discovered along the way:

      -
    • Unitialized means external. That is, the symbol is declared in the current +
    • Uninitialized means external. That is, the symbol is declared in the current module and can be used by that module, but it is not defined by that module.
    • Setting an initializer changes a global' linkage type. Setting an initializer changes a global's linkage type from whatever it was to a normal, @@ -1395,6 +1395,6 @@ +
      Last modified: $Date: 2004/03/11 10:14:21 $ From brukman at cs.uiuc.edu Thu Mar 11 12:17:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 12:17:01 2004 Subject: [llvm-commits] CVS: llvm/tools/llc/Makefile llc.cpp Message-ID: <200403111816.MAA02359@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: Makefile updated: 1.49 -> 1.50 llc.cpp updated: 1.94 -> 1.95 --- Log message: SparcV8 removed until it grows up becomes a mature backend. --- Diffs of the changes: (+2 -7) Index: llvm/tools/llc/Makefile diff -u llvm/tools/llc/Makefile:1.49 llvm/tools/llc/Makefile:1.50 --- llvm/tools/llc/Makefile:1.49 Sat Feb 28 13:55:16 2004 +++ llvm/tools/llc/Makefile Thu Mar 11 12:16:33 2004 @@ -1,4 +1,4 @@ -##===- tools/llc/Makefile ------------------------------*- Makefile -*-===## +#===- tools/llc/Makefile ------------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -9,7 +9,6 @@ LEVEL = ../.. TOOLNAME = llc USEDLIBS = cwriter \ - sparcv8 \ sparcv9 \ x86 \ powerpc \ Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.94 llvm/tools/llc/llc.cpp:1.95 --- llvm/tools/llc/llc.cpp:1.94 Sat Feb 28 13:55:16 2004 +++ llvm/tools/llc/llc.cpp Thu Mar 11 12:16:33 2004 @@ -37,12 +37,11 @@ static cl::opt Force("f", cl::desc("Overwrite output files")); -enum ArchName { noarch, X86, SparcV8, SparcV9, PowerPC, CBackend }; +enum ArchName { noarch, X86, SparcV9, PowerPC, CBackend }; static cl::opt Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix, cl::values(clEnumValN(X86, "x86", " IA-32 (Pentium and above)"), - clEnumValN(SparcV8, "sparcv8", " SPARC V8 (experimental)"), clEnumValN(SparcV9, "sparcv9", " SPARC V9"), clEnumValN(PowerPC, "powerpc", " PowerPC (experimental)"), clEnumValN(CBackend, "c", " C backend"), @@ -93,9 +92,6 @@ break; case SparcV9: TargetMachineAllocator = allocateSparcV9TargetMachine; - break; - case SparcV8: - TargetMachineAllocator = allocateSparcV8TargetMachine; break; case PowerPC: TargetMachineAllocator = allocatePowerPCTargetMachine; From brukman at cs.uiuc.edu Thu Mar 11 13:09:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 13:09:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200403111908.NAA04091@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.93 -> 1.94 --- Log message: Fix compilation on Sparc: assert(0) => abort() --- Diffs of the changes: (+5 -5) Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.93 llvm/lib/Target/X86/Printer.cpp:1.94 --- llvm/lib/Target/X86/Printer.cpp:1.93 Tue Mar 9 00:10:15 2004 +++ llvm/lib/Target/X86/Printer.cpp Thu Mar 11 13:08:24 2004 @@ -59,11 +59,11 @@ // These should never be called virtual void emitWord(unsigned W) { assert(0); } - virtual uint64_t getGlobalValueAddress(GlobalValue *V) { assert(0); } - virtual uint64_t getGlobalValueAddress(const std::string &Name) { assert(0); } - virtual uint64_t getConstantPoolEntryAddress(unsigned Index) { assert(0); } - virtual uint64_t getCurrentPCValue() { assert(0); } - virtual uint64_t forceCompilationOf(Function *F) { assert(0); } + virtual uint64_t getGlobalValueAddress(GlobalValue *V) { abort(); } + virtual uint64_t getGlobalValueAddress(const std::string &Name) { abort(); } + virtual uint64_t getConstantPoolEntryAddress(unsigned Index) { abort(); } + virtual uint64_t getCurrentPCValue() { abort(); } + virtual uint64_t forceCompilationOf(Function *F) { abort(); } private: std::ostream& O; From gaeke at cs.uiuc.edu Thu Mar 11 13:24:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Mar 11 13:24:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp Message-ID: <200403111923.NAA21880@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9PreSelection.cpp updated: 1.28 -> 1.29 --- Log message: Give pass a name --- Diffs of the changes: (+1 -0) Index: llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp diff -u llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp:1.28 llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp:1.29 --- llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp:1.28 Wed Feb 25 12:44:15 2004 +++ llvm/lib/Target/SparcV9/SparcV9PreSelection.cpp Thu Mar 11 13:23:15 2004 @@ -48,6 +48,7 @@ visit(F); return true; } + const char *getPassName() const { return "SparcV9 Instr. Pre-selection"; } // These methods do the actual work of specializing code void visitInstruction(Instruction &I); // common work for every instr. From gaeke at cs.uiuc.edu Thu Mar 11 13:47:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Mar 11 13:47:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Message-ID: <200403111946.NAA10237@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: PhyRegAlloc.cpp updated: 1.143 -> 1.144 --- Log message: Get rid of the abort in PhyRegAlloc::finishSavingState(). Make an explicit call to it from runOnFunction() if we know we're supposed to write into the global. This is lame (esp. the const_cast), but it solves the problem. --- Diffs of the changes: (+6 -5) Index: llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp diff -u llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.143 llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.144 --- llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp:1.143 Thu Mar 11 00:45:51 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp Thu Mar 11 13:46:30 2004 @@ -1232,9 +1232,9 @@ /// state; this one is cumbersome and does not work well with the JIT. /// void PhyRegAlloc::finishSavingState (Module &M) { - std::cerr << "---- Saving reg. alloc state; SaveStateToModule = " - << SaveStateToModule << " ----\n"; - abort (); + if (DEBUG_RA) + std::cerr << "---- Saving reg. alloc state; SaveStateToModule = " + << SaveStateToModule << " ----\n"; // If saving state into the module, just copy new elements to the // correct global. @@ -1379,9 +1379,10 @@ // Save register allocation state for this function in a Constant. if (SaveRegAllocState) { saveState(); - if (DEBUG_RA) { // Check our work. + if (DEBUG_RA) // Check our work. verifySavedState (); - } + if (!SaveStateToModule) + finishSavingState (const_cast (*Fn->getParent ())); } // Now update the machine code with register names and add any additional From gaeke at cs.uiuc.edu Thu Mar 11 13:54:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Mar 11 13:54:01 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Message-ID: <200403111953.NAA17717@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: RuntimeOptimizations.cpp updated: 1.22 -> 1.23 --- Log message: Zap unnecessary #include --- Diffs of the changes: (+0 -1) Index: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp diff -u reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.22 reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.23 --- reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.22 Wed Mar 10 16:21:12 2004 +++ reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Thu Mar 11 13:53:16 2004 @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "ReoptimizerInternal.h" -#include "Trace.h" #include "TraceToFunction.h" #include "Support/Debug.h" #include "Support/StringExtras.h" From gaeke at cs.uiuc.edu Thu Mar 11 13:56:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Mar 11 13:56:01 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp Message-ID: <200403111955.NAA18723@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.cpp updated: 1.26 -> 1.27 --- Log message: Zap unnecessary #include --- Diffs of the changes: (+0 -1) Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp diff -u reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.26 reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.27 --- reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.26 Wed Mar 10 16:21:13 2004 +++ reopt/lib/LightWtProfiling/TraceToFunction.cpp Thu Mar 11 13:55:15 2004 @@ -28,7 +28,6 @@ //===----------------------------------------------------------------------===// #include "TraceToFunction.h" -#include "Trace.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Pass.h" #include "llvm/Module.h" From gaeke at cs.uiuc.edu Thu Mar 11 14:56:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Mar 11 14:56:01 2004 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/Makefile Message-ID: <200403112055.OAA21832@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: Makefile updated: 1.13 -> 1.14 --- Log message: Make sure libcrtend.a gets installed when you make install-bytecode. --- Diffs of the changes: (+1 -0) Index: llvm/runtime/GCCLibraries/crtend/Makefile diff -u llvm/runtime/GCCLibraries/crtend/Makefile:1.13 llvm/runtime/GCCLibraries/crtend/Makefile:1.14 --- llvm/runtime/GCCLibraries/crtend/Makefile:1.13 Wed Jan 21 17:57:46 2004 +++ llvm/runtime/GCCLibraries/crtend/Makefile Thu Mar 11 14:55:23 2004 @@ -35,6 +35,7 @@ cp $< $@ install:: $(DESTDIR)$(bytecode_libdir)/libcrtend.a +install-bytecode:: $(DESTDIR)$(bytecode_libdir)/libcrtend.a # The four components described in the README From brukman at cs.uiuc.edu Thu Mar 11 15:27:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 15:27:02 2004 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200403112126.PAA24938@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.20 -> 1.21 --- Log message: Miscellaneous additions are a separate section. --- Diffs of the changes: (+2 -2) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.20 llvm/docs/OpenProjects.html:1.21 --- llvm/docs/OpenProjects.html:1.20 Wed Mar 10 20:50:35 2004 +++ llvm/docs/OpenProjects.html Thu Mar 11 15:26:29 2004 @@ -306,7 +306,7 @@ -
      + @@ -331,7 +331,7 @@
      Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/03/11 02:50:35 $ + Last modified: $Date: 2004/03/11 21:26:29 $
      From brukman at cs.uiuc.edu Thu Mar 11 17:09:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 17:09:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/AliasAnalysis.h DSGraph.h DSNode.h DSSupport.h DataStructure.h DependenceGraph.h Dominators.h Expressions.h FindUnsafePointerTypes.h IPModRef.h MemoryDepAnalysis.h PgmDependenceGraph.h Message-ID: <200403112308.RAA14423@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: AliasAnalysis.h updated: 1.10 -> 1.11 DSGraph.h updated: 1.79 -> 1.80 DSNode.h updated: 1.40 -> 1.41 DSSupport.h updated: 1.30 -> 1.31 DataStructure.h updated: 1.77 -> 1.78 DependenceGraph.h updated: 1.9 -> 1.10 Dominators.h updated: 1.43 -> 1.44 Expressions.h updated: 1.10 -> 1.11 FindUnsafePointerTypes.h updated: 1.15 -> 1.16 IPModRef.h updated: 1.14 -> 1.15 MemoryDepAnalysis.h updated: 1.7 -> 1.8 PgmDependenceGraph.h updated: 1.6 -> 1.7 --- Log message: Doxygenified and cleand up comments. --- Diffs of the changes: (+358 -359) Index: llvm/include/llvm/Analysis/AliasAnalysis.h diff -u llvm/include/llvm/Analysis/AliasAnalysis.h:1.10 llvm/include/llvm/Analysis/AliasAnalysis.h:1.11 --- llvm/include/llvm/Analysis/AliasAnalysis.h:1.10 Tue Feb 10 15:19:49 2004 +++ llvm/include/llvm/Analysis/AliasAnalysis.h Thu Mar 11 17:08:20 2004 @@ -61,6 +61,7 @@ /// getTargetData - Every alias analysis implementation depends on the size of /// data items in the current Target. This provides a uniform way to handle /// it. + /// const TargetData &getTargetData() const { return *TD; } //===--------------------------------------------------------------------===// Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.79 llvm/include/llvm/Analysis/DSGraph.h:1.80 --- llvm/include/llvm/Analysis/DSGraph.h:1.79 Tue Mar 9 13:36:59 2004 +++ llvm/include/llvm/Analysis/DSGraph.h Thu Mar 11 17:08:20 2004 @@ -56,6 +56,7 @@ /// replaceScalar - When an instruction needs to be modified, this method can /// be used to update the scalar map to remove the old and insert the new. + /// void replaceScalar(Value *Old, Value *New) { iterator I = find(Old); assert(I != end() && "Old value is not in the map!"); @@ -189,6 +190,7 @@ /// getFunctionNames - Return a space separated list of the name of the /// functions in this graph (if any) + /// std::string getFunctionNames() const; /// addNode - Add a new node to the graph. @@ -240,6 +242,7 @@ /// getReturnNodes - Return the mapping of functions to their return nodes for /// this graph. + /// const ReturnNodesTy &getReturnNodes() const { return ReturnNodes; } ReturnNodesTy &getReturnNodes() { return ReturnNodes; } @@ -273,6 +276,7 @@ /// viewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, /// then cleanup. For use from the debugger. + /// void viewGraph() const; void writeGraphToFile(std::ostream &O, const std::string &GraphName) const; @@ -354,7 +358,6 @@ void mergeInGraph(const DSCallSite &CS, Function &F, const DSGraph &Graph, unsigned CloneFlags); - /// getCallSiteForArguments - Get the arguments and return value bindings for /// the specified function in the current graph. /// @@ -389,54 +392,57 @@ }; - /// ReachabilityCloner - This class is used to incrementally clone and merge - /// nodes from a non-changing source graph into a potentially mutating - /// destination graph. Nodes are only cloned over on demand, either in - /// responds to a merge() or getClonedNH() call. When a node is cloned over, - /// all of the nodes reachable from it are automatically brought over as well. - class ReachabilityCloner { - DSGraph &Dest; - const DSGraph &Src; - - /// BitsToKeep - These bits are retained from the source node when the - /// source nodes are merged into the destination graph. - unsigned BitsToKeep; - unsigned CloneFlags; - - // NodeMap - A mapping from nodes in the source graph to the nodes that - // represent them in the destination graph. - DSGraph::NodeMapTy NodeMap; - public: - ReachabilityCloner(DSGraph &dest, const DSGraph &src, unsigned cloneFlags) - : Dest(dest), Src(src), CloneFlags(cloneFlags) { - assert(&Dest != &Src && "Cannot clone from graph to same graph!"); - BitsToKeep = ~DSNode::DEAD; - if (CloneFlags & DSGraph::StripAllocaBit) - BitsToKeep &= ~DSNode::AllocaNode; - if (CloneFlags & DSGraph::StripModRefBits) - BitsToKeep &= ~(DSNode::Modified | DSNode::Read); - if (CloneFlags & DSGraph::StripIncompleteBit) - BitsToKeep &= ~DSNode::Incomplete; - } - - DSNodeHandle getClonedNH(const DSNodeHandle &SrcNH); +/// ReachabilityCloner - This class is used to incrementally clone and merge +/// nodes from a non-changing source graph into a potentially mutating +/// destination graph. Nodes are only cloned over on demand, either in +/// responds to a merge() or getClonedNH() call. When a node is cloned over, +/// all of the nodes reachable from it are automatically brought over as well. +/// +class ReachabilityCloner { + DSGraph &Dest; + const DSGraph &Src; + + /// BitsToKeep - These bits are retained from the source node when the + /// source nodes are merged into the destination graph. + unsigned BitsToKeep; + unsigned CloneFlags; + + // NodeMap - A mapping from nodes in the source graph to the nodes that + // represent them in the destination graph. + DSGraph::NodeMapTy NodeMap; +public: + ReachabilityCloner(DSGraph &dest, const DSGraph &src, unsigned cloneFlags) + : Dest(dest), Src(src), CloneFlags(cloneFlags) { + assert(&Dest != &Src && "Cannot clone from graph to same graph!"); + BitsToKeep = ~DSNode::DEAD; + if (CloneFlags & DSGraph::StripAllocaBit) + BitsToKeep &= ~DSNode::AllocaNode; + if (CloneFlags & DSGraph::StripModRefBits) + BitsToKeep &= ~(DSNode::Modified | DSNode::Read); + if (CloneFlags & DSGraph::StripIncompleteBit) + BitsToKeep &= ~DSNode::Incomplete; + } + + DSNodeHandle getClonedNH(const DSNodeHandle &SrcNH); - void merge(const DSNodeHandle &NH, const DSNodeHandle &SrcNH); + void merge(const DSNodeHandle &NH, const DSNodeHandle &SrcNH); - /// mergeCallSite - Merge the nodes reachable from the specified src call - /// site into the nodes reachable from DestCS. - void mergeCallSite(const DSCallSite &DestCS, const DSCallSite &SrcCS); + /// mergeCallSite - Merge the nodes reachable from the specified src call + /// site into the nodes reachable from DestCS. + /// + void mergeCallSite(const DSCallSite &DestCS, const DSCallSite &SrcCS); - bool clonedAnyNodes() const { return !NodeMap.empty(); } + bool clonedAnyNodes() const { return !NodeMap.empty(); } - /// hasClonedNode - Return true if the specified node has been cloned from - /// the source graph into the destination graph. - bool hasClonedNode(const DSNode *N) { - return NodeMap.count(N); - } + /// hasClonedNode - Return true if the specified node has been cloned from + /// the source graph into the destination graph. + bool hasClonedNode(const DSNode *N) { + return NodeMap.count(N); + } + + void destroy() { NodeMap.clear(); } +}; - void destroy() { NodeMap.clear(); } - }; } // End llvm namespace #endif Index: llvm/include/llvm/Analysis/DSNode.h diff -u llvm/include/llvm/Analysis/DSNode.h:1.40 llvm/include/llvm/Analysis/DSNode.h:1.41 --- llvm/include/llvm/Analysis/DSNode.h:1.40 Mon Mar 1 13:36:50 2004 +++ llvm/include/llvm/Analysis/DSNode.h Thu Mar 11 17:08:20 2004 @@ -40,10 +40,12 @@ /// that this node really is. When nodes get folded together, the node to be /// eliminated has these fields filled in, otherwise ForwardNH.getNode() is /// null. + /// DSNodeHandle ForwardNH; /// Next, Prev - These instance variables are used to keep the node on a /// doubly-linked ilist in the DSGraph. + /// DSNode *Next, *Prev; friend class ilist_traits; @@ -105,12 +107,14 @@ /// DSNode ctor - Create a node of the specified type, inserting it into the /// specified graph. + /// DSNode(const Type *T, DSGraph *G); /// DSNode "copy ctor" - Copy the specified node, inserting it into the /// specified graph. If NullLinks is true, then null out all of the links, /// but keep the same number of them. This can be used for efficiency if the /// links are just going to be clobbered anyway. + /// DSNode(const DSNode &, DSGraph *G, bool NullLinks = false); ~DSNode() { @@ -133,8 +137,10 @@ /// unsigned getSize() const { return Size; } - // getType - Return the node type of this object... + /// getType - Return the node type of this object... + /// const Type *getType() const { return Ty; } + bool isArray() const { return NodeType & Array; } /// hasNoReferrers - Return true if nothing is pointing to this node at all. @@ -156,6 +162,7 @@ /// getForwardNode - This method returns the node that this node is forwarded /// to, if any. + /// DSNode *getForwardNode() const { return ForwardNH.getNode(); } /// isForwarding - Return true if this node is forwarding to another. @@ -164,9 +171,10 @@ /// stopForwarding - When the last reference to this forwarding node has been /// dropped, delete the node. + /// void stopForwarding() { assert(isForwarding() && - "Node isn't forwarding, cannot stopForwarding!"); + "Node isn't forwarding, cannot stopForwarding()!"); ForwardNH.setNode(0); assert(ParentGraph == 0 && "Forwarding nodes must have been removed from graph!"); @@ -184,6 +192,7 @@ } /// getLink - Return the link at the specified offset. + /// DSNodeHandle &getLink(unsigned Offset) { assert((Offset & ((1 << DS::PointerShift)-1)) == 0 && "Pointer offset not aligned correctly!"); @@ -283,6 +292,7 @@ /// getNodeFlags - Return all of the flags set on the node. If the DEAD flag /// is set, hide it from the caller. + /// unsigned getNodeFlags() const { return NodeType & ~DEAD; } bool isAllocaNode() const { return NodeType & AllocaNode; } @@ -331,6 +341,7 @@ /// remapLinks - Change all of the Links in the current node according to the /// specified mapping. + /// void remapLinks(hash_map &OldNodeMap); /// markReachableNodes - This method recursively traverses the specified @@ -423,7 +434,7 @@ getNode()->setLink(Off+Offset, NH); } -/// addEdgeTo - Add an edge from the current node to the specified node. This +/// addEdgeTo - Add an edge from the current node to the specified node. This /// can cause merging of nodes in the graph. /// inline void DSNodeHandle::addEdgeTo(unsigned Off, const DSNodeHandle &Node) { Index: llvm/include/llvm/Analysis/DSSupport.h diff -u llvm/include/llvm/Analysis/DSSupport.h:1.30 llvm/include/llvm/Analysis/DSSupport.h:1.31 --- llvm/include/llvm/Analysis/DSSupport.h:1.30 Tue Jan 27 15:49:42 2004 +++ llvm/include/llvm/Analysis/DSSupport.h Thu Mar 11 17:08:20 2004 @@ -35,9 +35,9 @@ PointerSize = 1 << PointerShift }; - // isPointerType - Return true if this first class type is big enough to hold - // a pointer. - // + /// isPointerType - Return true if this first class type is big enough to hold + /// a pointer. + /// bool isPointerType(const Type *Ty); }; @@ -89,6 +89,7 @@ /// isNull - Check to see if getNode() == 0, without going through the trouble /// of checking to see if we are forwarding... + /// bool isNull() const { return N == 0; } // Allow explicit conversion to DSNode... @@ -112,7 +113,8 @@ /// void mergeWith(const DSNodeHandle &N) const; - // hasLink - Return true if there is a link at the specified offset... + /// hasLink - Return true if there is a link at the specified offset... + /// inline bool hasLink(unsigned Num) const; /// getLink - Treat this current node pointer as a pointer to a structure of @@ -262,8 +264,9 @@ } } - // mergeWith - Merge the return value and parameters of the these two call - // sites. + /// mergeWith - Merge the return value and parameters of the these two call + /// sites. + /// void mergeWith(DSCallSite &CS) { getRetVal().mergeWith(CS.getRetVal()); unsigned MinArgs = getNumPtrArgs(); Index: llvm/include/llvm/Analysis/DataStructure.h diff -u llvm/include/llvm/Analysis/DataStructure.h:1.77 llvm/include/llvm/Analysis/DataStructure.h:1.78 --- llvm/include/llvm/Analysis/DataStructure.h:1.77 Wed Nov 12 23:05:34 2003 +++ llvm/include/llvm/Analysis/DataStructure.h Thu Mar 11 17:08:20 2004 @@ -27,9 +27,9 @@ // FIXME: move this stuff to a private header namespace DataStructureAnalysis { - // isPointerType - Return true if this first class type is big enough to hold - // a pointer. - // + /// isPointerType - Return true if this first class type is big enough to hold + /// a pointer. + /// bool isPointerType(const Type *Ty); } @@ -53,7 +53,8 @@ return DSInfo.find(const_cast(&F)) != DSInfo.end(); } - // getDSGraph - Return the data structure graph for the specified function. + /// getDSGraph - Return the data structure graph for the specified function. + /// DSGraph &getDSGraph(const Function &F) const { hash_map::const_iterator I = DSInfo.find(const_cast(&F)); @@ -63,13 +64,17 @@ DSGraph &getGlobalsGraph() const { return *GlobalsGraph; } - // print - Print out the analysis results... + /// print - Print out the analysis results... + /// void print(std::ostream &O, const Module *M) const; - // If the pass pipeline is done with this pass, we can release our memory... + /// releaseMemory - if the pass pipeline is done with this pass, we can + /// release our memory... + /// virtual void releaseMemory(); - // getAnalysisUsage - This obviously provides a data structure graph. + /// getAnalysisUsage - This obviously provides a data structure graph. + /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); @@ -77,10 +82,10 @@ }; -// BUDataStructures - The analysis that computes the interprocedurally closed -// data structure graphs for all of the functions in the program. This pass -// only performs a "Bottom Up" propagation (hence the name). -// +/// BUDataStructures - The analysis that computes the interprocedurally closed +/// data structure graphs for all of the functions in the program. This pass +/// only performs a "Bottom Up" propagation (hence the name). +/// class BUDataStructures : public Pass { protected: // DSInfo, one graph for each function @@ -96,7 +101,8 @@ return DSInfo.find(const_cast(&F)) != DSInfo.end(); } - // getDSGraph - Return the data structure graph for the specified function. + /// getDSGraph - Return the data structure graph for the specified function. + /// DSGraph &getDSGraph(const Function &F) const { hash_map::const_iterator I = DSInfo.find(const_cast(&F)); @@ -106,10 +112,13 @@ DSGraph &getGlobalsGraph() const { return *GlobalsGraph; } - // print - Print out the analysis results... + /// print - Print out the analysis results... + /// void print(std::ostream &O, const Module *M) const; - // If the pass pipeline is done with this pass, we can release our memory... + /// releaseMemory - if the pass pipeline is done with this pass, we can + /// release our memory... + /// virtual void releaseMemory(); virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -136,10 +145,10 @@ }; -// TDDataStructures - Analysis that computes new data structure graphs -// for each function using the closed graphs for the callers computed -// by the bottom-up pass. -// +/// TDDataStructures - Analysis that computes new data structure graphs +/// for each function using the closed graphs for the callers computed +/// by the bottom-up pass. +/// class TDDataStructures : public Pass { // DSInfo, one graph for each function hash_map DSInfo; @@ -154,7 +163,8 @@ return DSInfo.find(const_cast(&F)) != DSInfo.end(); } - // getDSGraph - Return the data structure graph for the specified function. + /// getDSGraph - Return the data structure graph for the specified function. + /// DSGraph &getDSGraph(const Function &F) const { hash_map::const_iterator I = DSInfo.find(const_cast(&F)); @@ -164,13 +174,16 @@ DSGraph &getGlobalsGraph() const { return *GlobalsGraph; } - // print - Print out the analysis results... + /// print - Print out the analysis results... + /// void print(std::ostream &O, const Module *M) const; - // If the pass pipeline is done with this pass, we can release our memory... + /// If the pass pipeline is done with this pass, we can release our memory... + /// virtual void releaseMyMemory(); - // getAnalysisUsage - This obviously provides a data structure graph. + /// getAnalysisUsage - This obviously provides a data structure graph. + /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); @@ -188,11 +201,11 @@ }; -// CompleteBUDataStructures - This is the exact same as the bottom-up graphs, -// but we use take a completed call graph and inline all indirect callees into -// their callers graphs, making the result more useful for things like pool -// allocation. -// +/// CompleteBUDataStructures - This is the exact same as the bottom-up graphs, +/// but we use take a completed call graph and inline all indirect callees into +/// their callers graphs, making the result more useful for things like pool +/// allocation. +/// struct CompleteBUDataStructures : public BUDataStructures { virtual bool run(Module &M); @@ -200,7 +213,8 @@ return DSInfo.find(const_cast(&F)) != DSInfo.end(); } - // getDSGraph - Return the data structure graph for the specified function. + /// getDSGraph - Return the data structure graph for the specified function. + /// DSGraph &getDSGraph(const Function &F) const { hash_map::const_iterator I = DSInfo.find(const_cast(&F)); @@ -217,7 +231,8 @@ AU.addRequired(); } - // print - Print out the analysis results... + /// print - Print out the analysis results... + /// void print(std::ostream &O, const Module *M) const; private: @@ -227,8 +242,6 @@ DSGraph &getOrCreateGraph(Function &F); void processGraph(DSGraph &G); }; - - } // End llvm namespace Index: llvm/include/llvm/Analysis/DependenceGraph.h diff -u llvm/include/llvm/Analysis/DependenceGraph.h:1.9 llvm/include/llvm/Analysis/DependenceGraph.h:1.10 --- llvm/include/llvm/Analysis/DependenceGraph.h:1.9 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Analysis/DependenceGraph.h Thu Mar 11 17:08:20 2004 @@ -25,10 +25,10 @@ #define LLVM_ANALYSIS_DEPENDENCEGRAPH_H #include "Support/hash_map" +#include #include -#include #include -#include +#include namespace llvm { @@ -38,11 +38,9 @@ class DepGraphNode; class DependenceGraph; - //---------------------------------------------------------------------------- -// enum DependenceType: The standard data dependence types. -//---------------------------------------------------------------------------- - +/// enum DependenceType - The standard data dependence types +/// enum DependenceType { NoDependence = 0x0, TrueDependence = 0x1, @@ -52,13 +50,10 @@ IncomingFlag = 0x10 // is this an incoming or outgoing dep? }; - -//---------------------------------------------------------------------------- -// class Dependence: -// -// A representation of a simple (non-loop-related) dependence. //---------------------------------------------------------------------------- - +/// Dependence Class - A representation of a simple (non-loop-related) +/// dependence. +/// class Dependence { DepGraphNode* toOrFromNode; unsigned char depType; @@ -68,8 +63,7 @@ : toOrFromNode(toOrFromN), depType(type | (isIncoming? IncomingFlag : 0x0)) { } - /* copy ctor*/ Dependence (const Dependence& D) - : toOrFromNode(D.toOrFromNode), + Dependence(const Dependence& D) : toOrFromNode(D.toOrFromNode), depType(D.depType) { } bool operator==(const Dependence& D) const { @@ -84,17 +78,17 @@ /// Get source or sink depending on what type of node this is! /// - DepGraphNode* getSrc() { + DepGraphNode* getSrc() { assert(depType & IncomingFlag); return toOrFromNode; } - const DepGraphNode* getSrc() const { + const DepGraphNode* getSrc() const { assert(depType & IncomingFlag); return toOrFromNode; } - DepGraphNode* getSink() { + DepGraphNode* getSink() { assert(! (depType & IncomingFlag)); return toOrFromNode; } - const DepGraphNode* getSink() const { + const DepGraphNode* getSink() const { assert(! (depType & IncomingFlag)); return toOrFromNode; } @@ -104,10 +98,9 @@ // Default constructor: Do not use directly except for graph builder code // - /*ctor*/ Dependence() : toOrFromNode(NULL), depType(NoDependence) { } + Dependence() : toOrFromNode(NULL), depType(NoDependence) { } }; - #ifdef SUPPORTING_LOOP_DEPENDENCES struct LoopDependence: public Dependence { DependenceDirection dir; @@ -119,12 +112,9 @@ //---------------------------------------------------------------------------- -// class DepGraphNode: -// -// A representation of a single node in a dependence graph, corresponding -// to a single instruction. -//---------------------------------------------------------------------------- - +/// DepGraphNode Class - A representation of a single node in a dependence +/// graph, corresponding to a single instruction. +/// class DepGraphNode { Instruction* instr; std::vector inDeps; @@ -134,22 +124,21 @@ typedef std::vector:: iterator iterator; typedef std::vector::const_iterator const_iterator; - iterator inDepBegin() { return inDeps.begin(); } - const_iterator inDepBegin() const { return inDeps.begin(); } - iterator inDepEnd() { return inDeps.end(); } - const_iterator inDepEnd() const { return inDeps.end(); } + iterator inDepBegin() { return inDeps.begin(); } + const_iterator inDepBegin() const { return inDeps.begin(); } + iterator inDepEnd() { return inDeps.end(); } + const_iterator inDepEnd() const { return inDeps.end(); } - iterator outDepBegin() { return outDeps.begin(); } - const_iterator outDepBegin() const { return outDeps.begin(); } - iterator outDepEnd() { return outDeps.end(); } - const_iterator outDepEnd() const { return outDeps.end(); } + iterator outDepBegin() { return outDeps.begin(); } + const_iterator outDepBegin() const { return outDeps.begin(); } + iterator outDepEnd() { return outDeps.end(); } + const_iterator outDepEnd() const { return outDeps.end(); } public: - DepGraphNode(Instruction& I) : instr(&I) { } - Instruction& getInstr() { return *instr; } - const Instruction& getInstr() const { return *instr; } + Instruction& getInstr() { return *instr; } + const Instruction& getInstr() const { return *instr; } /// Debugging support methods /// @@ -158,14 +147,11 @@ //---------------------------------------------------------------------------- -// class DependenceGraph: -// -// A representation of a dependence graph for a procedure. -// The primary query operation here is to look up a DepGraphNode for -// a particular instruction, and then use the in/out dependence iterators -// for the node. -//---------------------------------------------------------------------------- - +/// DependenceGraph Class - A representation of a dependence graph for a +/// procedure. The primary query operation here is to look up a DepGraphNode for +/// a particular instruction, and then use the in/out dependence iterators +/// for the node. +/// class DependenceGraph { DependenceGraph(const DependenceGraph&); // DO NOT IMPLEMENT void operator=(const DependenceGraph&); // DO NOT IMPLEMENT @@ -177,7 +163,7 @@ DepNodeMapType depNodeMap; inline DepGraphNode* getNodeInternal(Instruction& inst, - bool createIfMissing = false) { + bool createIfMissing = false) { map_iterator I = depNodeMap.find(&inst); if (I == depNodeMap.end()) return (!createIfMissing)? NULL : @@ -240,10 +226,10 @@ void print(const Function& func, std::ostream &O) const; public: - /// Functions for adding and modifying the dependence graph. + /// AddSimpleDependence - adding and modifying the dependence graph. /// These should to be used only by dependence analysis implementations. - void AddSimpleDependence(Instruction& fromI, - Instruction& toI, + /// + void AddSimpleDependence(Instruction& fromI, Instruction& toI, DependenceType depType) { DepGraphNode* fromNode = getNodeInternal(fromI, /*create*/ true); DepGraphNode* toNode = getNodeInternal(toI, /*create*/ true); @@ -252,8 +238,8 @@ } #ifdef SUPPORTING_LOOP_DEPENDENCES - /// This interface is a placeholder to show what information is needed. - /// It will probably change when it starts being used. + // This interface is a placeholder to show what information is needed. + // It will probably change when it starts being used. void AddLoopDependence(Instruction& fromI, Instruction& toI, DependenceType depType, @@ -263,8 +249,6 @@ LoopInfo* enclosingLoop); #endif // SUPPORTING_LOOP_DEPENDENCES }; - -//===----------------------------------------------------------------------===// } // End llvm namespace Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.43 llvm/include/llvm/Analysis/Dominators.h:1.44 --- llvm/include/llvm/Analysis/Dominators.h:1.43 Sat Dec 6 18:55:23 2003 +++ llvm/include/llvm/Analysis/Dominators.h Thu Mar 11 17:08:20 2004 @@ -35,10 +35,9 @@ template struct GraphTraits; //===----------------------------------------------------------------------===// -// -// DominatorBase - Base class that other, more interesting dominator analyses -// inherit from. -// +/// DominatorBase - Base class that other, more interesting dominator analyses +/// inherit from. +/// class DominatorBase : public FunctionPass { protected: std::vector Roots; @@ -46,21 +45,22 @@ inline DominatorBase(bool isPostDom) : Roots(), IsPostDominators(isPostDom) {} public: - // Return the root blocks of the current CFG. This may include multiple - // blocks if we are computing post dominators. For forward dominators, this - // will always be a single block (the entry node). + /// getRoots - Return the root blocks of the current CFG. This may include + /// multiple blocks if we are computing post dominators. For forward + /// dominators, this will always be a single block (the entry node). + /// inline const std::vector &getRoots() const { return Roots; } - // Returns true if analysis based of postdoms + /// isPostDominator - Returns true if analysis based of postdoms + /// bool isPostDominator() const { return IsPostDominators; } }; //===----------------------------------------------------------------------===// -// -// ImmediateDominators - Calculate the immediate dominator for each node in a -// function. -// +/// ImmediateDominators - Calculate the immediate dominator for each node in a +/// function. +/// class ImmediateDominatorsBase : public DominatorBase { protected: std::map IDoms; @@ -76,14 +76,15 @@ inline const_iterator end() const { return IDoms.end(); } inline const_iterator find(BasicBlock* B) const { return IDoms.find(B);} - // operator[] - Return the idom for the specified basic block. The start - // node returns null, because it does not have an immediate dominator. - // + /// operator[] - Return the idom for the specified basic block. The start + /// node returns null, because it does not have an immediate dominator. + /// inline BasicBlock *operator[](BasicBlock *BB) const { return get(BB); } - // get() - Synonym for operator[]. + /// get() - Synonym for operator[]. + /// inline BasicBlock *get(BasicBlock *BB) const { std::map::const_iterator I = IDoms.find(BB); return I != IDoms.end() ? I->second : 0; @@ -105,19 +106,21 @@ /// 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 + /// print - Convert to human readable form + /// virtual void print(std::ostream &OS) const; }; //===------------------------------------- -// ImmediateDominators Class - Concrete subclass of ImmediateDominatorsBase that -// is used to compute a normal immediate dominator set. -// +/// ImmediateDominators Class - Concrete subclass of ImmediateDominatorsBase +/// that is used to compute a normal immediate dominator set. +/// struct ImmediateDominators : public ImmediateDominatorsBase { ImmediateDominators() : ImmediateDominatorsBase(false) {} @@ -158,12 +161,11 @@ //===----------------------------------------------------------------------===// -// -// DominatorSet - Maintain a set for every basic block in a -// function, that represents the blocks that dominate the block. If the block -// is unreachable in this function, the set will be empty. This cannot happen -// for reachable code, because every block dominates at least itself. -// +/// DominatorSet - Maintain a set for every basic block in a +/// function, that represents the blocks that dominate the block. If the block +/// is unreachable in this function, the set will be empty. This cannot happen +/// for reachable code, because every block dominates at least itself. +/// struct DominatorSetBase : public DominatorBase { typedef std::set DomSetType; // Dom set for a bb // Map of dom sets @@ -197,6 +199,7 @@ /// isReachable - Return true if the specified basicblock is reachable. If /// the block is reachable, we have dominator set information for it. + /// bool isReachable(BasicBlock *BB) const { return !getDominators(BB).empty(); } @@ -214,6 +217,7 @@ } /// print - Convert to human readable form + /// virtual void print(std::ostream &OS) const; /// dominates - Return true if A dominates B. This performs the special @@ -227,14 +231,15 @@ /// addBasicBlock - Call to update the dominator set with information about a /// new block that was inserted into the function. + /// void addBasicBlock(BasicBlock *BB, const DomSetType &Dominators) { 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. - // + /// 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!"); @@ -244,9 +249,9 @@ //===------------------------------------- -// DominatorSet Class - Concrete subclass of DominatorSetBase that is used to -// compute a normal dominator set. -// +/// DominatorSet Class - Concrete subclass of DominatorSetBase that is used to +/// compute a normal dominator set. +/// struct DominatorSet : public DominatorSetBase { DominatorSet() : DominatorSetBase(false) {} @@ -257,7 +262,8 @@ return Roots[0]; } - // getAnalysisUsage - This simply provides a dominator set + /// getAnalysisUsage - This simply provides a dominator set + /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.setPreservesAll(); @@ -266,9 +272,8 @@ //===----------------------------------------------------------------------===// -// -// DominatorTree - Calculate the immediate dominator tree for a function. -// +/// DominatorTree - Calculate the immediate dominator tree for a function. +/// struct DominatorTreeBase : public DominatorBase { class Node; protected: @@ -298,18 +303,18 @@ inline Node *getIDom() const { return IDom; } inline const std::vector &getChildren() const { return Children; } - // dominates - Returns true iff this dominates N. Note that this is not a - // constant time operation! + /// dominates - Returns true iff this dominates N. Note that this is not a + /// constant time operation! + /// inline bool dominates(const Node *N) const { const Node *IDom; while ((IDom = N->getIDom()) != 0 && IDom != this) - N = IDom; // Walk up the tree + N = IDom; // Walk up the tree return IDom != 0; } private: - inline Node(BasicBlock *BB, Node *iDom) - : TheBB(BB), IDom(iDom) {} + inline Node(BasicBlock *BB, Node *iDom) : TheBB(BB), IDom(iDom) {} inline Node *addChild(Node *C) { Children.push_back(C); return C; } void setIDom(Node *NewIDom); @@ -333,13 +338,13 @@ return getNode(BB); } - // getRootNode - This returns the entry node for the CFG of the function. If - // this tree represents the post-dominance relations for a function, however, - // this root may be a node with the block == NULL. This is the case when - // there are multiple exit nodes from a particular function. Consumers of - // post-dominance information must be capable of dealing with this - // possibility. - // + /// getRootNode - This returns the entry node for the CFG of the function. If + /// this tree represents the post-dominance relations for a function, however, + /// this root may be a node with the block == NULL. This is the case when + /// there are multiple exit nodes from a particular function. Consumers of + /// post-dominance information must be capable of dealing with this + /// possibility. + /// Node *getRootNode() { return RootNode; } const Node *getRootNode() const { return RootNode; } @@ -366,14 +371,15 @@ } /// print - Convert to human readable form + /// virtual void print(std::ostream &OS) const; }; //===------------------------------------- -// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to -// compute a normal dominator tree. -// +/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to +/// compute a normal dominator tree. +/// struct DominatorTree : public DominatorTreeBase { DominatorTree() : DominatorTreeBase(false) {} @@ -400,9 +406,9 @@ }; //===------------------------------------- -// DominatorTree GraphTraits specialization so the DominatorTree can be -// iterable by generic graph iterators. - +/// DominatorTree GraphTraits specialization so the DominatorTree can be +/// iterable by generic graph iterators. +/// template <> struct GraphTraits { typedef DominatorTree::Node NodeType; typedef NodeType::iterator ChildIteratorType; @@ -426,9 +432,8 @@ }; //===----------------------------------------------------------------------===// -// -// DominanceFrontier - Calculate the dominance frontiers for a function. -// +/// DominanceFrontier - Calculate the dominance frontiers for a function. +/// struct DominanceFrontierBase : public DominatorBase { typedef std::set DomSetType; // Dom set for a bb typedef std::map DomSetMapType; // Dom set map @@ -465,15 +470,16 @@ I->second.erase(Node); } - // print - Convert to human readable form + /// print - Convert to human readable form + /// virtual void print(std::ostream &OS) const; }; //===------------------------------------- -// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to -// compute a normal dominator tree. -// +/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to +/// compute a normal dominator tree. +/// struct DominanceFrontier : public DominanceFrontierBase { DominanceFrontier() : DominanceFrontierBase(false) {} Index: llvm/include/llvm/Analysis/Expressions.h diff -u llvm/include/llvm/Analysis/Expressions.h:1.10 llvm/include/llvm/Analysis/Expressions.h:1.11 --- llvm/include/llvm/Analysis/Expressions.h:1.10 Tue Dec 23 02:03:40 2003 +++ llvm/include/llvm/Analysis/Expressions.h Thu Mar 11 17:08:20 2004 @@ -25,15 +25,15 @@ struct ExprType; -/// ClassifyExpr: Analyze an expression to determine the complexity of the +/// ClassifyExpr - Analyze an expression to determine the complexity of the /// expression, and which other values it depends on. /// ExprType ClassifyExpr(Value *Expr); -// ExprType - Represent an expression of the form CONST*VAR+CONST -// or simpler. The expression form that yields the least information about the -// expression is just the Linear form with no offset. -// +/// ExprType Class - Represent an expression of the form CONST*VAR+CONST +/// or simpler. The expression form that yields the least information about the +/// expression is just the Linear form with no offset. +/// struct ExprType { enum ExpressionType { Constant, // Expr is a simple constant, Offset is value @@ -52,9 +52,9 @@ ExprType(Value *Val); // Create a linear or constant expression ExprType(const ConstantInt *scale, Value *var, const ConstantInt *offset); - // If this expression has an intrinsic type, return it. If it is zero, return - // the specified type. - // + /// If this expression has an intrinsic type, return it. If it is zero, + /// return the specified type. + /// const Type *getExprType(const Type *Default) const; }; Index: llvm/include/llvm/Analysis/FindUnsafePointerTypes.h diff -u llvm/include/llvm/Analysis/FindUnsafePointerTypes.h:1.15 llvm/include/llvm/Analysis/FindUnsafePointerTypes.h:1.16 --- llvm/include/llvm/Analysis/FindUnsafePointerTypes.h:1.15 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Analysis/FindUnsafePointerTypes.h Thu Mar 11 17:08:20 2004 @@ -40,18 +40,18 @@ return UnsafeTypes; } - // run - Inspect the operations that the specified module does on - // values of various types. If they are deemed to be 'unsafe' note that the - // type is not safe to transform. - // + /// run - Inspect the operations that the specified module does on + /// values of various types. If they are deemed to be 'unsafe' note that the + /// type is not safe to transform. + /// virtual bool run(Module &M); - // print - Loop over the results of the analysis, printing out unsafe types. - // + /// print - Loop over the results of the analysis, printing out unsafe types. + /// void print(std::ostream &o, const Module *Mod) const; - // getAnalysisUsage - Of course, we provide ourself... - // + /// getAnalysisUsage - Of course, we provide ourself... + /// virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } Index: llvm/include/llvm/Analysis/IPModRef.h diff -u llvm/include/llvm/Analysis/IPModRef.h:1.14 llvm/include/llvm/Analysis/IPModRef.h:1.15 --- llvm/include/llvm/Analysis/IPModRef.h:1.14 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Analysis/IPModRef.h Thu Mar 11 17:08:20 2004 @@ -65,23 +65,18 @@ class FunctionModRefInfo; // ModRefInfo for a func and all calls in it class IPModRef; // Pass that computes IP Mod/Ref info -//--------------------------------------------------------------------------- -// class ModRefInfo -// -// Purpose: -// Representation of Mod/Ref information for a single function or callsite. -// This is represented as a pair of bit vectors, one each for Mod and Ref. -// Each bit vector is indexed by the node id of the DS graph node index. -//--------------------------------------------------------------------------- - +//---------------------------------------------------------------------------- +/// ModRefInfo Class - Representation of Mod/Ref information for a single +/// function or callsite. This is represented as a pair of bit vectors, one each +/// for Mod and Ref. Each bit vector is indexed by the node id of the DS graph +/// node index. +/// class ModRefInfo { BitSetVector modNodeSet; // set of modified nodes BitSetVector refNodeSet; // set of referenced nodes public: - // // Methods to construct ModRefInfo objects. - // ModRefInfo(unsigned int numNodes) : modNodeSet(numNodes), refNodeSet(numNodes) { } @@ -95,9 +90,7 @@ void setNodeIsMod (unsigned nodeId) { modNodeSet[nodeId] = true; } void setNodeIsRef (unsigned nodeId) { refNodeSet[nodeId] = true; } - // // Methods to query the mod/ref info - // bool nodeIsMod (unsigned nodeId) const { return modNodeSet.test(nodeId); } bool nodeIsRef (unsigned nodeId) const { return refNodeSet.test(nodeId); } bool nodeIsKill(unsigned nodeId) const { return false; } @@ -115,15 +108,12 @@ //---------------------------------------------------------------------------- -// class FunctionModRefInfo -// -// Representation of the results of IP Mod/Ref analysis for a function -// and for each of the call sites within the function. -// Each of these are represented as bit vectors of size = the number of -// nodes in the top-dwon DS graph of the function. Nodes are identified by -// their nodeId, in the range [0 .. funcTDGraph.size()-1]. -//---------------------------------------------------------------------------- - +/// FunctionModRefInfo Class - Representation of the results of IP Mod/Ref +/// analysis for a function and for each of the call sites within the function. +/// Each of these are represented as bit vectors of size = the number of nodes +/// in the top-dwon DS graph of the function. Nodes are identified by their +/// nodeId, in the range [0 .. funcTDGraph.size()-1]. +/// class FunctionModRefInfo { const Function& F; // The function IPModRef& IPModRefObj; // The IPModRef Object owning this @@ -135,33 +125,33 @@ friend class IPModRef; - void computeModRef (const Function &func); - void computeModRef (CallSite call); - DSGraph *ResolveCallSiteModRefInfo(CallSite CS, - hash_map &NodeMap); + void computeModRef(const Function &func); + void computeModRef(CallSite call); + DSGraph* + ResolveCallSiteModRefInfo(CallSite CS, + hash_map &NodeMap); public: - /* ctor */ FunctionModRefInfo (const Function& func, - IPModRef& IPModRefObj, - DSGraph* tdgClone); - /* dtor */ ~FunctionModRefInfo (); + FunctionModRefInfo(const Function& func, IPModRef &IPModRefObj, + DSGraph* tdgClone); + ~FunctionModRefInfo(); // Identify the function and its relevant DS graph // - const Function& getFunction() const { return F; } - const DSGraph& getFuncGraph() const { return *funcTDGraph; } + const Function& getFunction() const { return F; } + const DSGraph& getFuncGraph() const { return *funcTDGraph; } // Retrieve Mod/Ref results for a single call site and for the function body // - const ModRefInfo* getModRefInfo (const Function& func) const { + const ModRefInfo* getModRefInfo(const Function& func) const { return &funcModRefInfo; } - const ModRefInfo* getModRefInfo (const CallInst& callInst) const { + const ModRefInfo* getModRefInfo(const CallInst& callInst) const { std::map::const_iterator I = callSiteModRefInfo.find((Instruction*)&callInst); return (I == callSiteModRefInfo.end()) ? NULL : I->second; } - const ModRefInfo* getModRefInfo (const InvokeInst& II) const { + const ModRefInfo* getModRefInfo(const InvokeInst& II) const { std::map::const_iterator I = callSiteModRefInfo.find((Instruction*)&II); return (I == callSiteModRefInfo.end()) ? NULL : I->second; @@ -169,13 +159,13 @@ // Get the nodeIds used to index all Mod/Ref information for current function // - unsigned getNodeId (const DSNode* node) const { + unsigned getNodeId(const DSNode* node) const { std::map::const_iterator iter = NodeIds.find(node); assert(iter != NodeIds.end() && iter->second < funcModRefInfo.getSize()); return iter->second; } - unsigned getNodeId (const Value* value) const; + unsigned getNodeId(const Value* value) const; // Debugging support methods void print(std::ostream &O) const; @@ -184,19 +174,15 @@ //---------------------------------------------------------------------------- -// class IPModRef -// -// Purpose: -// An interprocedural pass that computes IP Mod/Ref info for functions and -// for individual call sites. -// -// Given the DSGraph of a function, this class can be queried for -// a ModRefInfo object describing all the nodes in the DSGraph that are -// (a) modified, and (b) referenced during an execution of the function -// from an arbitrary callsite, or during an execution of a single call-site -// within the function. -//---------------------------------------------------------------------------- - +/// IPModRef Class - An interprocedural pass that computes IP Mod/Ref info for +/// functions and for individual call sites. +/// +/// Given the DSGraph of a function, this class can be queried for +/// a ModRefInfo object describing all the nodes in the DSGraph that are +/// (a) modified, and (b) referenced during an execution of the function +/// from an arbitrary callsite, or during an execution of a single call-site +/// within the function. +/// class IPModRef : public Pass { std::map funcToModRefInfoMap; Module* M; @@ -204,17 +190,18 @@ FunctionModRefInfo& getFuncInfo(const Function& func, bool computeIfMissing = false); public: - IPModRef() : M(NULL) { } - ~IPModRef() { } + IPModRef() : M(NULL) {} + ~IPModRef() {} - // Driver function to run IP Mod/Ref on a Module. - // This initializes the module reference, and then computes IPModRef - // results immediately if demand-driven analysis was *not* specified. - // + /// run - Driver function to run IP Mod/Ref on a Module. + /// This initializes the module reference, and then computes IPModRef + /// results immediately if demand-driven analysis was *not* specified. + /// virtual bool run(Module &M); - // Retrieve the Mod/Ref information for a single function - // + /// getFunctionModRefInfo - Retrieve the Mod/Ref information for a single + /// function + /// const FunctionModRefInfo& getFunctionModRefInfo(const Function& func) { return getFuncInfo(func); } @@ -229,17 +216,16 @@ void print(std::ostream &O) const; void dump() const; - // Release memory held by this pass when the pass pipeline is done - // + /// releaseMemory - Release memory held by this pass when the pass pipeline is + /// done + /// virtual void releaseMemory(); - // getAnalysisUsage - This pass requires top-down data structure graphs. - // It modifies nothing. - // + /// getAnalysisUsage - This pass requires top-down data structure graphs. + /// It modifies nothing. + /// virtual void getAnalysisUsage(AnalysisUsage &AU) const; }; - -//===----------------------------------------------------------------------===// } // End llvm namespace Index: llvm/include/llvm/Analysis/MemoryDepAnalysis.h diff -u llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.7 llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.8 --- llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.7 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Analysis/MemoryDepAnalysis.h Thu Mar 11 17:08:20 2004 @@ -42,7 +42,7 @@ class MemoryDepAnalysis : public Pass { /// The following map and depGraph pointer are temporary until this class - /// becomes a FunctionPass instead of a module Pass. */ + /// becomes a FunctionPass instead of a module Pass. hash_map funcMap; DependenceGraph* funcDepGraph; @@ -51,6 +51,7 @@ const FunctionModRefInfo* funcModRef; /// Internal routine that processes each SCC of the CFG. + /// void ProcessSCC(std::vector &SCC, ModRefTable& ModRefAfter, bool HasLoop); @@ -61,9 +62,10 @@ ~MemoryDepAnalysis(); /// Driver function to compute dependence graphs for every function. + /// bool run(Module &M); - /// getGraph() -- Retrieve the dependence graph for a function. + /// getGraph - Retrieve the dependence graph for a function. /// This is temporary and will go away once this is a FunctionPass. /// At that point, this class should directly inherit from DependenceGraph. /// @@ -73,8 +75,7 @@ return *I->second; } const DependenceGraph& getGraph(Function& F) const { - hash_map::const_iterator - I = funcMap.find(&F); + hash_map::const_iterator I = funcMap.find(&F); assert(I != funcMap.end()); return *I->second; } @@ -82,7 +83,6 @@ /// Release depGraphs held in the Function -> DepGraph map. /// virtual void releaseMemory(); - /// Driver functions to compute the Load/Store Dep. Graph per function. /// Index: llvm/include/llvm/Analysis/PgmDependenceGraph.h diff -u llvm/include/llvm/Analysis/PgmDependenceGraph.h:1.6 llvm/include/llvm/Analysis/PgmDependenceGraph.h:1.7 --- llvm/include/llvm/Analysis/PgmDependenceGraph.h:1.6 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Analysis/PgmDependenceGraph.h Thu Mar 11 17:08:20 2004 @@ -52,14 +52,11 @@ class DependenceGraph; class PgmDependenceGraph; - -///--------------------------------------------------------------------------- -/// enum PDGIteratorFlags -/// -/// These bit flags specify which dependences incident on a statement are to be -/// enumerated: Memory deps, SSA deps, Control deps, or any combination thereof. -///--------------------------------------------------------------------------- - +//--------------------------------------------------------------------------- +/// enum PDGIteratorFlags - specify which dependences incident on a statement +/// are to be enumerated: Memory deps, SSA deps, Control deps, or any +/// combination thereof. +/// enum PDGIteratorFlags { MemoryDeps = 0x1, // load/store/call deps SSADeps = 0x2, // SSA deps (true) @@ -68,16 +65,12 @@ AllDeps = MemoryDeps | SSADeps | ControlDeps // shorthand for all three }; - -///--------------------------------------------------------------------------- -/// struct DepIterState -/// -/// This data type is primarily an internal implementation detail. +//--------------------------------------------------------------------------- +/// struct DepIterState - an internal implementation detail. /// It are exposed here only to give inlinable access to field dep, /// which is the representation for the current dependence pointed to by /// a PgmDependenceGraph::iterator. -///--------------------------------------------------------------------------- - +/// class DepIterState { private: typedef char IterStateFlags; @@ -93,12 +86,12 @@ PDGIteratorFlags depFlags:8; // which deps are we enumerating? IterStateFlags iterFlags:8; // marking where the iter stands - /*ctor*/ DepIterState (DependenceGraph* _memDepGraph, - Instruction& I, - bool incomingDeps, - PDGIteratorFlags whichDeps); + DepIterState(DependenceGraph* _memDepGraph, + Instruction& I, + bool incomingDeps, + PDGIteratorFlags whichDeps); - bool operator==(const DepIterState& S) { + bool operator==(const DepIterState& S) { assert(memDepGraph == S.memDepGraph && "Incompatible iterators! This is a probable sign of something BAD."); return (iterFlags == S.iterFlags && @@ -109,39 +102,38 @@ // Is the iteration completely done? // - bool done () const { return iterFlags & AllDone; } + bool done() const { return iterFlags & AllDone; } - // Bump this iterator logically by 1 (to next dependence) and reset the - // dep field to represent the new dependence if there is one. - // Set done = true otherwise. - // - void Next (); + /// Next - Bump this iterator logically by 1 (to next dependence) and reset + /// the dep field to represent the new dependence if there is one. + /// Set done = true otherwise. + /// + void Next(); - // Find the first memory dependence for the current Mem In/Out iterators. - // Sets dep to that dependence and returns true if one is found. - // Returns false and leaves dep unchanged otherwise. - // - bool SetFirstMemoryDep(); + /// SetFirstMemoryDep - Find the first memory dependence for the current Mem + /// In/Out iterators. Sets dep to that dependence and returns true if one is + /// found. Returns false and leaves dep unchanged otherwise. + /// + bool SetFirstMemoryDep(); - // Find the next valid data dependence for the current SSA In/Out iterators. - // A valid data dependence is one that is to/from an Instruction. - // E.g., an SSA edge from a formal parameter is not a valid dependence. - // Sets dep to that dependence and returns true if a valid one is found. - // Returns false and leaves dep unchanged otherwise. - // - bool SetFirstSSADep (); + /// SetFirstSSADep - Find the next valid data dependence for the current SSA + /// In/Out iterators. A valid data dependence is one that is to/from an + /// Instruction. E.g., an SSA edge from a formal parameter is not a valid + /// dependence. Sets dep to that dependence and returns true if a valid one is + /// found. Returns false and leaves dep unchanged otherwise. + /// + bool SetFirstSSADep(); }; -///--------------------------------------------------------------------------- -/// The dependence iterator class. This class represents a pointer to -/// a single dependence in the program dependence graph. It is essentially -/// like a pointer to an object of class Dependence but it is much more -/// efficient to retrieve information about the dependence directly rather -/// than constructing the equivalent Dependence object (since that object -/// is normally not constructed for SSA def-use dependences). -///--------------------------------------------------------------------------- - +//--------------------------------------------------------------------------- +/// PDGIterator Class - represents a pointer to a single dependence in the +/// program dependence graph. It is essentially like a pointer to an object of +/// class Dependence but it is much more efficient to retrieve information about +/// the dependence directly rather than constructing the equivalent Dependence +/// object (since that object is normally not constructed for SSA def-use +/// dependences). +/// class PDGIterator: public forward_iterator { DepIterState* istate; @@ -159,44 +151,43 @@ public: typedef PDGIterator _Self; - /*ctor*/ PDGIterator (DepIterState* _istate) : istate(_istate) { } - /*dtor*/ ~PDGIterator () { delete istate; } + PDGIterator(DepIterState* _istate) : istate(_istate) {} + ~PDGIterator() { delete istate; } - /*copy*/ PDGIterator (const PDGIterator& I) - : istate(new DepIterState(*I.istate)) { } + PDGIterator(const PDGIterator& I) :istate(new DepIterState(*I.istate)) {} - PDGIterator& operator= (const PDGIterator& I) { + PDGIterator& operator=(const PDGIterator& I) { if (istate) delete istate; istate = new DepIterState(*I.istate); return *this; } - // Check if the iteration is complete - // - bool fini() const { return !istate || istate->done(); } + /// fini - check if the iteration is complete + /// + bool fini() const { return !istate || istate->done(); } // Retrieve the underlying Dependence. Returns NULL if fini(). // - Dependence* operator*() const { return fini() ? NULL : &istate->dep; } - Dependence* operator->() const { assert(!fini()); return &istate->dep; } + Dependence* operator*() const { return fini() ? NULL : &istate->dep; } + Dependence* operator->() const { assert(!fini()); return &istate->dep; } // Increment the iterator // - _Self& operator++() { if (!fini()) istate->Next(); return *this;} - _Self& operator++(int); // do not implement! + _Self& operator++() { if (!fini()) istate->Next(); return *this;} + _Self& operator++(int); // do not implement! // Equality comparison: a "null" state should compare equal to done // This is efficient for comparing with "end" or with itself, but could // be quite inefficient for other cases. // - bool operator==(const PDGIterator& I) const { + bool operator==(const PDGIterator& I) const { if (I.istate == NULL) // most common case: iter == end() return (istate == NULL || istate->done()); if (istate == NULL) return (I.istate == NULL || I.istate->done()); return (*istate == *I.istate); } - bool operator!=(const PDGIterator& I) const { + bool operator!=(const PDGIterator& I) const { return ! (*this == I); } }; @@ -219,15 +210,15 @@ // print helper function. void printOutgoingSSADeps(Instruction& I, std::ostream &O); - // MakeIterator -- - // The first version creates and initializes an iterator as specified. - // The second version creates a null iterator representing end-of-iteration. - // - PDGIterator MakeIterator (Instruction& I, - bool incomingDeps, - PDGIteratorFlags whichDeps); + /// MakeIterator - creates and initializes an iterator as specified. + /// + PDGIterator MakeIterator(Instruction& I, + bool incomingDeps, + PDGIteratorFlags whichDeps); - PDGIterator MakeIterator () { return PDGIterator(NULL); } + /// MakeIterator - creates a null iterator representing end-of-iteration. + /// + PDGIterator MakeIterator() { return PDGIterator(NULL); } friend class PDGIterator; friend class DepIterState; @@ -237,13 +228,13 @@ /* typedef PDGIterator const iterator; */ public: - PgmDependenceGraph() : memDepGraph(NULL) { } - ~PgmDependenceGraph() { } + PgmDependenceGraph() : memDepGraph(NULL) {} + ~PgmDependenceGraph() {} /// Iterators to enumerate the program dependence graph for a function. /// Note that this does not provide "end" iterators to check for completion. /// Instead, just use iterator::fini() or iterator::operator*() == NULL - // + /// iterator inDepBegin(Instruction& I, PDGIteratorFlags whichDeps = AllDeps) { return MakeIterator(I, /*inDeps*/ true, whichDeps); } @@ -257,7 +248,7 @@ return MakeIterator(); } - ///------------------------------------------------------------------------ + //------------------------------------------------------------------------ /// TEMPORARY FUNCTIONS TO MAKE THIS A MODULE PASS --- /// These functions will go away once this class becomes a FunctionPass. @@ -305,8 +296,6 @@ void print(std::ostream &O) const; void dump() const; }; - -//===----------------------------------------------------------------------===// } // End llvm namespace From brukman at cs.uiuc.edu Thu Mar 11 17:43:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 17:43:00 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Argument.h Message-ID: <200403112342.RAA14560@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Argument.h updated: 1.7 -> 1.8 --- Log message: Forward-declare templates for fix compilation when Argument.h is included first. --- Diffs of the changes: (+4 -0) Index: llvm/include/llvm/Argument.h diff -u llvm/include/llvm/Argument.h:1.7 llvm/include/llvm/Argument.h:1.8 --- llvm/include/llvm/Argument.h:1.7 Tue Nov 11 16:41:29 2003 +++ llvm/include/llvm/Argument.h Thu Mar 11 17:42:24 2004 @@ -19,6 +19,10 @@ namespace llvm { +template struct ilist_traits; +template class SymbolTableListTraits; + class Argument : public Value { // Defined in the Function.cpp file Function *Parent; From brukman at cs.uiuc.edu Thu Mar 11 17:53:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 17:53:02 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetFrameInfo.h Message-ID: <200403112352.RAA14647@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetFrameInfo.h updated: 1.10 -> 1.11 --- Log message: Move function implementations to a .cpp file, avoid #including here. --- Diffs of the changes: (+21 -23) Index: llvm/include/llvm/Target/TargetFrameInfo.h diff -u llvm/include/llvm/Target/TargetFrameInfo.h:1.10 llvm/include/llvm/Target/TargetFrameInfo.h:1.11 --- llvm/include/llvm/Target/TargetFrameInfo.h:1.10 Wed Jan 21 16:50:12 2004 +++ llvm/include/llvm/Target/TargetFrameInfo.h Thu Mar 11 17:52:03 2004 @@ -14,8 +14,6 @@ #ifndef LLVM_TARGET_TARGETFRAMEINFO_H #define LLVM_TARGET_TARGETFRAMEINFO_H -#include - namespace llvm { class MachineFunction; @@ -56,15 +54,15 @@ // are Sparc specific. //===--------------------------------------------------------------------===// - virtual int getStackFrameSizeAlignment () const { abort(); } - virtual int getMinStackFrameSize () const { abort(); } - virtual int getNumFixedOutgoingArgs () const { abort(); } - virtual int getSizeOfEachArgOnStack () const { abort(); } - virtual bool argsOnStackHaveFixedSize () const { abort(); } + virtual int getStackFrameSizeAlignment () const; + virtual int getMinStackFrameSize () const; + virtual int getNumFixedOutgoingArgs () const; + virtual int getSizeOfEachArgOnStack () const; + virtual bool argsOnStackHaveFixedSize () const; // This method adjusts a stack offset to meet alignment rules of target. virtual int adjustAlignment(int unalignedOffset, bool growUp, - unsigned align) const { abort(); } + unsigned align) const; // These methods compute offsets using the frame contents for a particular // function. The frame contents are obtained from the MachineFunction object @@ -72,35 +70,35 @@ // machine-specific subclass. // virtual int getIncomingArgOffset (MachineFunction& mcInfo, - unsigned argNum)const{abort();} + unsigned argNum) const; virtual int getOutgoingArgOffset (MachineFunction& mcInfo, - unsigned argNum)const{abort();} + unsigned argNum) const; virtual int getFirstIncomingArgOffset (MachineFunction& mcInfo, - bool& growUp) const { abort();} + bool& growUp) const; virtual int getFirstOutgoingArgOffset (MachineFunction& mcInfo, - bool& growUp) const {abort();} + bool& growUp) const; virtual int getFirstOptionalOutgoingArgOffset (MachineFunction&, - bool& growUp) const {abort();} + bool& growUp) const; virtual int getFirstAutomaticVarOffset (MachineFunction& mcInfo, - bool& growUp) const {abort();} + bool& growUp) const; virtual int getRegSpillAreaOffset (MachineFunction& mcInfo, - bool& growUp) const {abort();} + bool& growUp) const; virtual int getTmpAreaOffset (MachineFunction& mcInfo, - bool& growUp) const {abort();} + bool& growUp) const; virtual int getDynamicAreaOffset (MachineFunction& mcInfo, - bool& growUp) const {abort();} + bool& growUp) const; // // These methods specify the base register used for each stack area // (generally FP or SP) // - virtual int getIncomingArgBaseRegNum() const { abort(); } - virtual int getOutgoingArgBaseRegNum() const { abort(); } - virtual int getOptionalOutgoingArgBaseRegNum() const { abort(); } - virtual int getAutomaticVarBaseRegNum() const { abort(); } - virtual int getRegSpillAreaBaseRegNum() const { abort(); } - virtual int getDynamicAreaBaseRegNum() const { abort(); } + virtual int getIncomingArgBaseRegNum() const; + virtual int getOutgoingArgBaseRegNum() const; + virtual int getOptionalOutgoingArgBaseRegNum() const; + virtual int getAutomaticVarBaseRegNum() const; + virtual int getRegSpillAreaBaseRegNum() const; + virtual int getDynamicAreaBaseRegNum() const; }; } // End llvm namespace From brukman at cs.uiuc.edu Thu Mar 11 17:53:10 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 17:53:10 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetFrameInfo.cpp Message-ID: <200403112352.RAA14664@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetFrameInfo.cpp added (r1.1) --- Log message: Move implementations of functions here, which avoids #including in the header file and all those who #include it. --- Diffs of the changes: (+86 -0) Index: llvm/lib/Target/TargetFrameInfo.cpp diff -c /dev/null llvm/lib/Target/TargetFrameInfo.cpp:1.1 *** /dev/null Thu Mar 11 17:52:54 2004 --- llvm/lib/Target/TargetFrameInfo.cpp Thu Mar 11 17:52:43 2004 *************** *** 0 **** --- 1,86 ---- + //===-- TargetFrameInfo.cpp - Implement machine frame interface -*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // Implements the layout of a stack frame on the target machine. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Target/TargetFrameInfo.h" + #include + + using namespace llvm; + + //===--------------------------------------------------------------------===// + // These methods provide details of the stack frame used by Sparc, thus they + // are Sparc specific. + //===--------------------------------------------------------------------===// + + int TargetFrameInfo::getStackFrameSizeAlignment() const { abort(); } + int TargetFrameInfo::getMinStackFrameSize() const { abort(); } + int TargetFrameInfo::getNumFixedOutgoingArgs() const { abort(); } + int TargetFrameInfo::getSizeOfEachArgOnStack() const { abort(); } + bool TargetFrameInfo::argsOnStackHaveFixedSize() const { abort(); } + + // This method adjusts a stack offset to meet alignment rules of target. + int + TargetFrameInfo::adjustAlignment(int unalignedOffset, bool growUp, + unsigned align) const { abort(); } + + // These methods compute offsets using the frame contents for a particular + // function. The frame contents are obtained from the MachineFunction object + // for the given function. The rest must be implemented by the + // machine-specific subclass. + // + int + TargetFrameInfo::getIncomingArgOffset(MachineFunction& mcInfo, unsigned argNum) + const{ abort(); } + + int + TargetFrameInfo::getOutgoingArgOffset(MachineFunction& mcInfo, + unsigned argNum) const { abort(); } + + int + TargetFrameInfo::getFirstIncomingArgOffset(MachineFunction& mcInfo, + bool& growUp) const { abort(); } + + int + TargetFrameInfo::getFirstOutgoingArgOffset(MachineFunction& mcInfo, + bool& growUp) const { abort(); } + + int + TargetFrameInfo::getFirstOptionalOutgoingArgOffset(MachineFunction&, + bool& growUp) const { abort(); } + + int + TargetFrameInfo::getFirstAutomaticVarOffset(MachineFunction& mcInfo, + bool& growUp) const { abort(); } + + int + TargetFrameInfo::getRegSpillAreaOffset(MachineFunction& mcInfo, bool& growUp) + const { abort(); } + + int + TargetFrameInfo::getTmpAreaOffset(MachineFunction& mcInfo, bool& growUp) const + { abort(); } + + int + TargetFrameInfo::getDynamicAreaOffset(MachineFunction& mcInfo, bool& growUp) + const { abort(); } + + // + // These methods specify the base register used for each stack area + // (generally FP or SP) + // + int TargetFrameInfo::getIncomingArgBaseRegNum() const { abort(); } + int TargetFrameInfo::getOutgoingArgBaseRegNum() const { abort(); } + int TargetFrameInfo::getOptionalOutgoingArgBaseRegNum() const {abort();} + int TargetFrameInfo::getAutomaticVarBaseRegNum() const { abort(); } + int TargetFrameInfo::getRegSpillAreaBaseRegNum() const { abort(); } + int TargetFrameInfo::getDynamicAreaBaseRegNum() const { abort(); } + From brukman at cs.uiuc.edu Thu Mar 11 17:55:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 17:55:02 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/iMemory.cpp Message-ID: <200403112354.RAA14709@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: iMemory.cpp updated: 1.34 -> 1.35 --- Log message: Fix indentation. --- Diffs of the changes: (+2 -2) Index: llvm/lib/VMCore/iMemory.cpp diff -u llvm/lib/VMCore/iMemory.cpp:1.34 llvm/lib/VMCore/iMemory.cpp:1.35 --- llvm/lib/VMCore/iMemory.cpp:1.34 Fri Nov 21 14:23:48 2003 +++ llvm/lib/VMCore/iMemory.cpp Thu Mar 11 17:53:51 2004 @@ -116,8 +116,8 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, const std::string &Name, Instruction *InBe) : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), - Idx, true))), - GetElementPtr, Name, InBe) { + Idx, true))), + GetElementPtr, Name, InBe) { Operands.reserve(1+Idx.size()); Operands.push_back(Use(Ptr, this)); From brukman at cs.uiuc.edu Thu Mar 11 18:41:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 18:41:02 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200403120040.SAA15507@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.149.2.2 -> 1.149.2.3 --- Log message: Fix the incorrect merge from trunk. --- Diffs of the changes: (+0 -5) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.149.2.2 llvm/lib/Target/X86/InstSelectSimple.cpp:1.149.2.3 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.149.2.2 Wed Mar 10 19:01:46 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Mar 11 18:40:32 2004 @@ -720,11 +720,6 @@ ++NumFPKill; } } - // If we got this far, there is no need to insert the kill instruction. - return false; -#else - return true; -#endif } // canFoldSetCCIntoBranch - Return the setcc instruction if we can fold it into From brukman at cs.uiuc.edu Thu Mar 11 18:43:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 18:43:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/PassAnalysisSupport.h Message-ID: <200403120042.SAA15552@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: PassAnalysisSupport.h updated: 1.17 -> 1.17.4.1 --- Log message: Add ability to specify transitive requirements of analyses: analyses that need to be alive AFTER the current analysis has run, in order to query it. --- Diffs of the changes: (+17 -4) Index: llvm/include/llvm/PassAnalysisSupport.h diff -u llvm/include/llvm/PassAnalysisSupport.h:1.17 llvm/include/llvm/PassAnalysisSupport.h:1.17.4.1 --- llvm/include/llvm/PassAnalysisSupport.h:1.17 Tue Nov 11 16:41:30 2003 +++ llvm/include/llvm/PassAnalysisSupport.h Thu Mar 11 18:42:25 2004 @@ -25,14 +25,15 @@ //===----------------------------------------------------------------------===// // AnalysisUsage - Represent the analysis usage information of a pass. This -// tracks analyses that the pass REQUIRES (must available when the pass runs), -// and analyses that the pass PRESERVES (the pass does not invalidate the -// results of these analyses). This information is provided by a pass to the +// tracks analyses that the pass REQUIRES (must be available when the pass +// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the +// pass), and analyses that the pass PRESERVES (the pass does not invalidate the +// results of these analyses). This information is provided by a pass to the // Pass infrastructure through the getAnalysisUsage virtual function. // class AnalysisUsage { // Sets of analyses required and preserved by a pass - std::vector Required, Preserved; + std::vector Required, RequiredTransitive, Preserved; bool PreservesAll; public: AnalysisUsage() : PreservesAll(false) {} @@ -51,6 +52,15 @@ return *this; } + template + AnalysisUsage &addRequiredTransitive() { + AnalysisID ID = Pass::getClassPassInfo(); + assert(ID && "Pass class not registered!"); + Required.push_back(ID); + RequiredTransitive.push_back(ID); + return *this; + } + // addPreserved - Add the specified ID to the set of analyses preserved by // this pass // @@ -82,6 +92,9 @@ void setPreservesCFG(); const std::vector &getRequiredSet() const { return Required; } + const std::vector &getRequiredTransitiveSet() const { + return RequiredTransitive; + } const std::vector &getPreservedSet() const { return Preserved; } }; From brukman at cs.uiuc.edu Thu Mar 11 18:44:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 18:44:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200403120043.SAA15583@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.13.4.2 -> 1.13.4.3 --- Log message: Renamed addRequiredLive() => addRequiredTransitive() --- Diffs of the changes: (+4 -4) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.13.4.2 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.13.4.3 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.13.4.2 Wed Mar 10 19:29:34 2004 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Thu Mar 11 18:43:18 2004 @@ -41,10 +41,10 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AliasAnalysis::getAnalysisUsage(AU); - AU.setPreservesAll(); // Does not transform code... - AU.addRequiredLive(); // Uses TD Datastructures - AU.addRequiredLive(); // Uses BU Datastructures - AU.addRequired(); // Chains to another AA impl... + AU.setPreservesAll(); // Does not transform code + AU.addRequiredTransitive(); // Uses TD Datastructures + AU.addRequiredTransitive(); // Uses BU Datastructures + AU.addRequired(); // Chains to another AA impl } //------------------------------------------------ From brukman at cs.uiuc.edu Thu Mar 11 18:45:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 18:45:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200403120044.SAA15607@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp updated: 1.10 -> 1.10.4.1 --- Log message: Test mod/ref info analysis, now that DSA supports it with functions vs. values. --- Diffs of the changes: (+93 -24) Index: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp diff -u llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.10 llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.10.4.1 --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.10 Wed Dec 10 09:33:59 2003 +++ llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Thu Mar 11 18:44:05 2004 @@ -17,23 +17,31 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Pass.h" #include "llvm/Function.h" +#include "llvm/iOther.h" +#include "llvm/iTerminators.h" +#include "llvm/Pass.h" #include "llvm/Type.h" -#include "llvm/Support/InstIterator.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Assembly/Writer.h" +#include "llvm/Support/InstIterator.h" #include "Support/CommandLine.h" #include using namespace llvm; namespace { - cl::opt PrintNo ("print-no-aliases", cl::ReallyHidden); - cl::opt PrintMay ("print-may-aliases", cl::ReallyHidden); - cl::opt PrintMust("print-must-aliases", cl::ReallyHidden); + cl::opt PrintNoAlias("print-no-aliases", cl::ReallyHidden); + cl::opt PrintMayAlias("print-may-aliases", cl::ReallyHidden); + cl::opt PrintMustAlias("print-must-aliases", cl::ReallyHidden); + + cl::opt PrintNoModRef("print-no-modref", cl::ReallyHidden); + cl::opt PrintMod("print-mod", cl::ReallyHidden); + cl::opt PrintRef("print-ref", cl::ReallyHidden); + cl::opt PrintModRef("print-modref", cl::ReallyHidden); class AAEval : public FunctionPass { - unsigned No, May, Must; + unsigned NoAlias, MayAlias, MustAlias; + unsigned NoModRef, Mod, Ref, ModRef; public: virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -41,7 +49,12 @@ AU.setPreservesAll(); } - bool doInitialization(Module &M) { No = May = Must = 0; return false; } + bool doInitialization(Module &M) { + NoAlias = MayAlias = MustAlias = 0; + NoModRef = Mod = Ref = ModRef = 0; + return false; + } + bool runOnFunction(Function &F); bool doFinalization(Module &M); }; @@ -63,6 +76,7 @@ AliasAnalysis &AA = getAnalysis(); std::set Pointers; + std::set CallSites; for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I) if (isa(I->getType())) // Add all pointer arguments @@ -76,7 +90,15 @@ Pointers.insert(*OI); } - if (PrintNo || PrintMay || PrintMust) + for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { + if (CallInst *CI = dyn_cast(*I)) + CallSites.insert(CallSite(CI)); + else if (InvokeInst *II = dyn_cast(*I)) + CallSites.insert(CallSite(II)); + } + + if (PrintNoAlias || PrintMayAlias || PrintMustAlias || + PrintNoModRef || PrintMod || PrintRef || PrintModRef) std::cerr << "Function: " << F.getName() << "\n"; // iterate over the worklist, and run the full (n^2)/2 disambiguations @@ -85,34 +107,81 @@ for (std::set::iterator I2 = Pointers.begin(); I2 != I1; ++I2) switch (AA.alias(*I1, 0, *I2, 0)) { case AliasAnalysis::NoAlias: - PrintResults("No", PrintNo, *I1, *I2, F.getParent()); - ++No; break; + PrintResults("NoAlias", PrintNoAlias, *I1, *I2, F.getParent()); + ++NoAlias; break; case AliasAnalysis::MayAlias: - PrintResults("May", PrintMay, *I1, *I2, F.getParent()); - ++May; break; + PrintResults("MayAlias", PrintMayAlias, *I1, *I2, F.getParent()); + ++MayAlias; break; case AliasAnalysis::MustAlias: - PrintResults("Must", PrintMust, *I1, *I2, F.getParent()); - ++Must; break; + PrintResults("MustAlias", PrintMustAlias, *I1, *I2, F.getParent()); + ++MustAlias; break; default: std::cerr << "Unknown alias query result!\n"; } + // Mod/ref alias analysis: compare all pairs of calls and values + for (std::set::iterator V = Pointers.begin(), Ve = Pointers.end(); + V != Ve; ++V) + for (std::set::iterator C = CallSites.begin(), + Ce = CallSites.end(); C != Ce; ++C) { + Instruction *I = C->getInstruction(); + switch (AA.getModRefInfo(*C, *V, (*V)->getType()->getPrimitiveSize())) { + case AliasAnalysis::NoModRef: + PrintResults("NoModRef", PrintNoModRef, I, *V, F.getParent()); + ++NoModRef; break; + case AliasAnalysis::Mod: + PrintResults("Mod", PrintMod, I, *V, F.getParent()); + ++Mod; break; + case AliasAnalysis::Ref: + PrintResults("Ref", PrintRef, I, *V, F.getParent()); + ++Ref; break; + case AliasAnalysis::ModRef: + PrintResults("ModRef", PrintModRef, I, *V, F.getParent()); + ++ModRef; break; + default: + std::cerr << "Unknown alias query result!\n"; + } + } + return false; } bool AAEval::doFinalization(Module &M) { - unsigned Sum = No+May+Must; + unsigned AliasSum = NoAlias + MayAlias + MustAlias; std::cerr << "===== Alias Analysis Evaluator Report =====\n"; - if (Sum == 0) { + if (AliasSum == 0) { std::cerr << " Alias Analysis Evaluator Summary: No pointers!\n"; - return false; + } else { + std::cerr << " " << AliasSum << " Total Alias Queries Performed\n"; + std::cerr << " " << NoAlias << " no alias responses (" + << NoAlias*100/AliasSum << "%)\n"; + std::cerr << " " << MayAlias << " may alias responses (" + << MayAlias*100/AliasSum << "%)\n"; + std::cerr << " " << MustAlias << " must alias responses (" + << MustAlias*100/AliasSum <<"%)\n"; + std::cerr << " Alias Analysis Evaluator Pointer Alias Summary: " + << NoAlias*100/AliasSum << "%/" << MayAlias*100/AliasSum << "%/" + << MustAlias*100/AliasSum << "%\n"; + } + + // Display the summary for mod/ref analysis + unsigned ModRefSum = NoModRef + Mod + Ref + ModRef; + if (ModRefSum == 0) { + std::cerr << " Alias Analysis Mod/Ref Evaluator Summary: no mod/ref!\n"; + } else { + std::cerr << " " << ModRefSum << " Total ModRef Queries Performed\n"; + std::cerr << " " << NoModRef << " no mod/ref responses (" + << NoModRef*100/ModRefSum << "%)\n"; + std::cerr << " " << Mod << " mod responses (" + << Mod*100/ModRefSum << "%)\n"; + std::cerr << " " << Ref << " ref responses (" + << Ref*100/ModRefSum <<"%)\n"; + std::cerr << " " << ModRef << " mod & ref responses (" + << ModRef*100/ModRefSum <<"%)\n"; + std::cerr << " Alias Analysis Evaluator Mod/Ref Summary: " + << NoModRef*100/ModRefSum << "%/" << Mod*100/ModRefSum << "%/" + << Ref*100/ModRefSum << "%/" << ModRef*100/ModRefSum << "%\n"; } - std::cerr << " " << Sum << " Total Alias Queries Performed\n"; - std::cerr << " " << No << " no alias responses (" << No*100/Sum << "%)\n"; - std::cerr << " " << May << " may alias responses (" << May*100/Sum << "%)\n"; - std::cerr << " " << Must << " must alias responses (" < Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.46.4.1 -> 1.46.4.2 --- Log message: Implement keeping analyses alive transitively. --- Diffs of the changes: (+10 -1) Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.46.4.1 llvm/lib/VMCore/PassManagerT.h:1.46.4.2 --- llvm/lib/VMCore/PassManagerT.h:1.46.4.1 Mon Mar 1 17:58:16 2004 +++ llvm/lib/VMCore/PassManagerT.h Thu Mar 11 18:44:57 2004 @@ -208,7 +208,6 @@ E = LastUseOf.end(); I != E; ++I) LastUserOf[I->second].push_back(I->first); - // Output debug information... if (Parent == 0) PMDebug::PerformPassStartupStuff(this); @@ -397,6 +396,16 @@ if (I != CurrentAnalyses.end()) { LastUseOf[I->second] = User; // Local pass, extend the lifetime + + // Prolong live range of analyses that are needed after an analysis pass + // is destroyed, for querying by subsequent passes + AnalysisUsage AnUsage; + I->second->getAnalysisUsage(AnUsage); + const std::vector &IDs = AnUsage.getRequiredLiveSet(); + for (std::vector::const_iterator i = IDs.begin(), + e = IDs.end(); i != e; ++i) + markPassUsed(*i, User); + } else { // Pass not in current available set, must be a higher level pass // available to us, propagate to parent pass manager... We tell the From brukman at cs.uiuc.edu Thu Mar 11 18:46:09 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 18:46:09 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Regression/Analysis/DSGraph/2004-03-10-ElimLoad.ll 2004-03-10-NoElimLoad.ll Message-ID: <200403120045.SAA15667@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: 2004-03-10-ElimLoad.ll added (r1.1.2.1) 2004-03-10-NoElimLoad.ll added (r1.1.2.1) --- Log message: Add test cases for exercising the Mod/Ref analysis of DSA. --- Diffs of the changes: (+27 -0) Index: llvm/test/Regression/Analysis/DSGraph/2004-03-10-ElimLoad.ll diff -c /dev/null llvm/test/Regression/Analysis/DSGraph/2004-03-10-ElimLoad.ll:1.1.2.1 *** /dev/null Thu Mar 11 18:45:43 2004 --- llvm/test/Regression/Analysis/DSGraph/2004-03-10-ElimLoad.ll Thu Mar 11 18:45:33 2004 *************** *** 0 **** --- 1,13 ---- + ; RUN: llvm-as < %s | opt -ds-aa -load-vn -gcse -instcombine | llvm-dis | not grep sub + + void %bar(int* %p) { + ret void + } + + int %foo(int* %a) { + %b = load int* %a + call void %bar(int* %a) + %d = load int* %a + %e = sub int %b, %d + ret int %e + } Index: llvm/test/Regression/Analysis/DSGraph/2004-03-10-NoElimLoad.ll diff -c /dev/null llvm/test/Regression/Analysis/DSGraph/2004-03-10-NoElimLoad.ll:1.1.2.1 *** /dev/null Thu Mar 11 18:45:43 2004 --- llvm/test/Regression/Analysis/DSGraph/2004-03-10-NoElimLoad.ll Thu Mar 11 18:45:33 2004 *************** *** 0 **** --- 1,14 ---- + ; RUN: llvm-as < %s | opt -ds-aa -load-vn -gcse -instcombine | llvm-dis | grep sub + + void %bar(int* %p) { + store int 15, int* %p + ret void + } + + int %foo(int* %a) { + %b = load int* %a + call void %bar(int* %a) + %d = load int* %a + %e = sub int %b, %d + ret int %e + } From brukman at cs.uiuc.edu Thu Mar 11 18:59:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Mar 11 18:59:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Message-ID: <200403120058.SAA15905@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: MemoryDepAnalysis.cpp updated: 1.12 -> 1.13 --- Log message: Make code more readable. --- Diffs of the changes: (+31 -35) Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.12 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.13 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.12 Tue Nov 11 18:40:34 2003 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Thu Mar 11 18:58:41 2004 @@ -53,7 +53,7 @@ struct ModRefTable { typedef hash_map ModRefMap; typedef ModRefMap::const_iterator const_map_iterator; - typedef ModRefMap:: iterator map_iterator; + typedef ModRefMap:: iterator map_iterator; typedef std::vector::const_iterator const_ref_iterator; typedef std::vector:: iterator ref_iterator; @@ -131,9 +131,9 @@ void operator=(const ModRefInfoBuilder&); // DO NOT IMPLEMENT public: - /*ctor*/ ModRefInfoBuilder(const DSGraph& _funcGraph, - const FunctionModRefInfo& _funcModRef, - ModRefTable& _modRefTable) + ModRefInfoBuilder(const DSGraph& _funcGraph, + const FunctionModRefInfo& _funcModRef, + ModRefTable& _modRefTable) : funcGraph(_funcGraph), funcModRef(_funcModRef), modRefTable(_modRefTable) { } @@ -142,15 +142,15 @@ // Add the call to the defs list if it modifies any nodes and to the uses // list if it refs any nodes. // - void visitCallInst (CallInst& callInst) { + void visitCallInst(CallInst& callInst) { ModRefInfo safeModRef(funcGraph.getGraphSize()); const ModRefInfo* callModRef = funcModRef.getModRefInfo(callInst); - if (callModRef == NULL) - { // call to external/unknown function: mark all nodes as Mod and Ref - safeModRef.getModSet().set(); - safeModRef.getRefSet().set(); - callModRef = &safeModRef; - } + if (callModRef == NULL) { + // call to external/unknown function: mark all nodes as Mod and Ref + safeModRef.getModSet().set(); + safeModRef.getRefSet().set(); + callModRef = &safeModRef; + } modRefTable.modRefMap.insert(std::make_pair(&callInst, ModRefInfo(*callModRef))); @@ -163,40 +163,36 @@ // At a store instruction, add to the mod set the single node pointed to // by the pointer argument of the store. Interestingly, if there is no // such node, that would be a null pointer reference! - void visitStoreInst (StoreInst& storeInst) { + void visitStoreInst(StoreInst& storeInst) { const DSNodeHandle& ptrNode = funcGraph.getNodeForValue(storeInst.getPointerOperand()); - if (const DSNode* target = ptrNode.getNode()) - { - unsigned nodeId = funcModRef.getNodeId(target); - ModRefInfo& minfo = - modRefTable.modRefMap.insert( - std::make_pair(&storeInst, - ModRefInfo(funcGraph.getGraphSize()))).first->second; - minfo.setNodeIsMod(nodeId); - modRefTable.AddDef(&storeInst); - } - else + if (const DSNode* target = ptrNode.getNode()) { + unsigned nodeId = funcModRef.getNodeId(target); + ModRefInfo& minfo = + modRefTable.modRefMap.insert( + std::make_pair(&storeInst, + ModRefInfo(funcGraph.getGraphSize()))).first->second; + minfo.setNodeIsMod(nodeId); + modRefTable.AddDef(&storeInst); + } else std::cerr << "Warning: Uninitialized pointer reference!\n"; } // At a load instruction, add to the ref set the single node pointed to // by the pointer argument of the load. Interestingly, if there is no // such node, that would be a null pointer reference! - void visitLoadInst (LoadInst& loadInst) { + void visitLoadInst(LoadInst& loadInst) { const DSNodeHandle& ptrNode = funcGraph.getNodeForValue(loadInst.getPointerOperand()); - if (const DSNode* target = ptrNode.getNode()) - { - unsigned nodeId = funcModRef.getNodeId(target); - ModRefInfo& minfo = - modRefTable.modRefMap.insert( - std::make_pair(&loadInst, - ModRefInfo(funcGraph.getGraphSize()))).first->second; - minfo.setNodeIsRef(nodeId); - modRefTable.AddUse(&loadInst); - } - else + if (const DSNode* target = ptrNode.getNode()) { + unsigned nodeId = funcModRef.getNodeId(target); + ModRefInfo& minfo = + modRefTable.modRefMap.insert( + std::make_pair(&loadInst, + ModRefInfo(funcGraph.getGraphSize()))).first->second; + minfo.setNodeIsRef(nodeId); + modRefTable.AddUse(&loadInst); + } else std::cerr << "Warning: Uninitialized pointer reference!\n"; } }; From lattner at cs.uiuc.edu Thu Mar 11 23:51:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:51:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/select.ll Message-ID: <200403120550.XAA17471@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: select.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+7 -0) Index: llvm/test/Regression/Assembler/select.ll diff -c /dev/null llvm/test/Regression/Assembler/select.ll:1.1 *** /dev/null Thu Mar 11 23:50:13 2004 --- llvm/test/Regression/Assembler/select.ll Thu Mar 11 23:50:02 2004 *************** *** 0 **** --- 1,7 ---- + + + int %test(bool %C, int %V1, int %V2) { + %X = select bool true, bool false, bool true + %V = select bool %X, int %V1, int %V2 + ret int %V + } From lattner at cs.uiuc.edu Thu Mar 11 23:51:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:51:10 2004 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200403120550.XAA17494@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.52 -> 1.53 --- Log message: Cleanup the cast section, add the select instruction --- Diffs of the changes: (+96 -22) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.52 llvm/docs/LangRef.html:1.53 --- llvm/docs/LangRef.html:1.52 Mon Mar 8 10:49:10 2004 +++ llvm/docs/LangRef.html Thu Mar 11 23:50:16 2004 @@ -80,6 +80,7 @@
      1. 'phi' Instruction
      2. 'cast .. to' Instruction
      3. +
      4. 'select' Instruction
      5. 'call' Instruction
      6. 'vanext' Instruction
      7. 'vaarg' Instruction
      8. @@ -1506,38 +1507,111 @@
        Example:
        Loop:       ; Infinite loop that counts from 0 on up...
        %indvar = phi uint [ 0, %LoopHeader ], [ %nextindvar, %Loop ]
        %nextindvar = add uint %indvar, 1
        br label %Loop
        + - + +
        +
        Syntax:
        -
          <result> = cast <ty> <value> to <ty2>             ; yields ty2
        +
        +
        +  <result> = cast <ty> <value> to <ty2>             ; yields ty2
         
        +
        Overview:
        -

        The 'cast' instruction is used as the primitive means to -convert integers to floating point, change data type sizes, and break -type safety (by casting pointers).

        + +

        +The 'cast' instruction is used as the primitive means to convert +integers to floating point, change data type sizes, and break type safety (by +casting pointers). +

        + +
        Arguments:
        -

        The 'cast' instruction takes a value to cast, which must be -a first class value, and a type to cast it to, which must also be a first class type.

        + +

        +The 'cast' instruction takes a value to cast, which must be a first +class value, and a type to cast it to, which must also be a first class type. +

        +
        Semantics:
        -

        This instruction follows the C rules for explicit casts when -determining how the data being cast must change to fit in its new -container.

        -

        When casting to bool, any value that would be considered true in the -context of a C 'if' condition is converted to the boolean 'true' -values, all else are 'false'.

        -

        When extending an integral value from a type of one signness to -another (for example 'sbyte' to 'ulong'), the value -is sign-extended if the source value is signed, and -zero-extended if the source value is unsigned. bool values -are always zero extended into either zero or one.

        + +

        +This instruction follows the C rules for explicit casts when determining how the +data being cast must change to fit in its new container. +

        + +

        +When casting to bool, any value that would be considered true in the context of +a C 'if' condition is converted to the boolean 'true' values, +all else are 'false'. +

        + +

        +When extending an integral value from a type of one signness to another (for +example 'sbyte' to 'ulong'), the value is sign-extended if the +source value is signed, and zero-extended if the source value is +unsigned. bool values are always zero extended into either zero or +one. +

        +
        Example:
        -
          %X = cast int 257 to ubyte              ; yields ubyte:1
        +
        +
        +  %X = cast int 257 to ubyte              ; yields ubyte:1
           %Y = cast int 123 to bool               ; yields bool:true
         
        + + + + +
        + +
        Syntax:
        + +
        +  <result> = select bool <cond>, <ty> <val1>, <ty> <val2>             ; yields ty
        +
        + +
        Overview:
        + +

        +The 'select' instruction is used to choose one value based on a +condition, without branching. +

        + + +
        Arguments:
        + +

        +The 'select' instruction requires a boolean value indicating the condition, and two values of the same first class type. +

        + +
        Semantics:
        + +

        +If the boolean condition evaluates to true, the instruction returns the first +value argument, otherwise it returns the second value argument. +

        + +
        Example:
        + +
        +  %X = select bool true, ubyte 17, ubyte 42          ; yields ubyte:17
        +
        +
        + + + + + @@ -2074,7 +2148,7 @@ Chris Lattner
        The LLVM Compiler Infrastructure
        - Last modified: $Date: 2004/03/08 16:49:10 $ + Last modified: $Date: 2004/03/12 05:50:16 $ From lattner at cs.uiuc.edu Thu Mar 11 23:51:17 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:51:17 2004 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200403120550.XAA17939@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.21 -> 1.22 --- Log message: This is no longer an open project --- Diffs of the changes: (+1 -5) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.21 llvm/docs/OpenProjects.html:1.22 --- llvm/docs/OpenProjects.html:1.21 Thu Mar 11 15:26:29 2004 +++ llvm/docs/OpenProjects.html Thu Mar 11 23:50:24 2004 @@ -143,10 +143,6 @@
          - -
        1. Add a new conditional move instruction: X = select bool Cond, Y, - Z
        2. -
        3. Add support for platform-independent prefetch support. The GCC prefetch project page has a good survey of the prefetching capabilities of a variety of modern @@ -331,7 +327,7 @@
          Chris Lattner
          The LLVM Compiler Infrastructure
          - Last modified: $Date: 2004/03/11 21:26:29 $ + Last modified: $Date: 2004/03/12 05:50:24 $
        From lattner at cs.uiuc.edu Thu Mar 11 23:52:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:52:00 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Constants.h Message-ID: <200403120551.XAA18403@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constants.h updated: 1.43 -> 1.44 --- Log message: Add support for select constant exprs --- Diffs of the changes: (+11 -0) Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.43 llvm/include/llvm/Constants.h:1.44 --- llvm/include/llvm/Constants.h:1.43 Sat Feb 14 23:52:14 2004 +++ llvm/include/llvm/Constants.h Thu Mar 11 23:50:39 2004 @@ -518,6 +518,8 @@ ConstantExpr(unsigned Opcode, Constant *C, const Type *Ty); // Binary/Shift instruction creation ctor ConstantExpr(unsigned Opcode, Constant *C1, Constant *C2); + // Select instruction creation ctor + ConstantExpr(Constant *C, Constant *V1, Constant *V2); // GEP instruction creation ctor ConstantExpr(Constant *C, const std::vector &IdxList, const Type *DestTy); @@ -528,6 +530,8 @@ Constant *C1, Constant *C2); static Constant *getShiftTy(const Type *Ty, unsigned Opcode, Constant *C1, Constant *C2); + static Constant *getSelectTy(const Type *Ty, + Constant *C1, Constant *C2, Constant *C3); static Constant *getGetElementPtrTy(const Type *Ty, Constant *C, const std::vector &IdxList); @@ -540,6 +544,13 @@ /// Cast constant expr /// static Constant *getCast(Constant *C, const Type *Ty); + + /// Select constant expr + /// + static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) { + return getSelectTy(V1->getType(), C, V1, V2); + } + /// ConstantExpr::get - Return a binary or shift operator constant expression, /// folding if possible. From lattner at cs.uiuc.edu Thu Mar 11 23:52:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:52:08 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/iOther.h Message-ID: <200403120551.XAA18398@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: iOther.h updated: 1.44 -> 1.45 --- Log message: Add the SelectInst class --- Diffs of the changes: (+48 -0) Index: llvm/include/llvm/iOther.h diff -u llvm/include/llvm/iOther.h:1.44 llvm/include/llvm/iOther.h:1.45 --- llvm/include/llvm/iOther.h:1.44 Tue Feb 10 10:39:05 2004 +++ llvm/include/llvm/iOther.h Thu Mar 11 23:51:05 2004 @@ -133,6 +133,49 @@ } }; +//===----------------------------------------------------------------------===// +// SelectInst Class +//===----------------------------------------------------------------------===// + +/// SelectInst - This class represents the LLVM 'select' instruction. +/// +class SelectInst : public Instruction { + SelectInst(const SelectInst &SI) : Instruction(SI.getType(), SI.getOpcode()) { + Operands.reserve(3); + Operands.push_back(Use(SI.Operands[0], this)); + Operands.push_back(Use(SI.Operands[1], this)); + Operands.push_back(Use(SI.Operands[2], this)); + } +public: + SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", + Instruction *InsertBefore = 0) + : Instruction(S1->getType(), Instruction::Select, Name, InsertBefore) { + Operands.reserve(3); + Operands.push_back(Use(C, this)); + Operands.push_back(Use(S1, this)); + Operands.push_back(Use(S2, this)); + } + + Value *getCondition() const { return Operands[0]; } + Value *getTrueValue() const { return Operands[1]; } + Value *getFalseValue() const { return Operands[2]; } + + OtherOps getOpcode() const { + return static_cast(Instruction::getOpcode()); + } + + virtual Instruction *clone() const { return new SelectInst(*this); } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SelectInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Select; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + //===----------------------------------------------------------------------===// // VANextInst Class @@ -170,6 +213,11 @@ return isa(V) && classof(cast(V)); } }; + + +//===----------------------------------------------------------------------===// +// VAArgInst Class +//===----------------------------------------------------------------------===// /// VAArgInst - This class represents the va_arg llvm instruction, which returns /// an argument of the specified type given a va_list. From lattner at cs.uiuc.edu Thu Mar 11 23:52:16 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:52:16 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/InstVisitor.h Message-ID: <200403120551.XAA18414@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: InstVisitor.h updated: 1.27 -> 1.28 --- Log message: Add the visitSelectInst visitor method --- Diffs of the changes: (+1 -0) Index: llvm/include/llvm/Support/InstVisitor.h diff -u llvm/include/llvm/Support/InstVisitor.h:1.27 llvm/include/llvm/Support/InstVisitor.h:1.28 --- llvm/include/llvm/Support/InstVisitor.h:1.27 Thu Nov 27 19:46:06 2003 +++ llvm/include/llvm/Support/InstVisitor.h Thu Mar 11 23:51:22 2004 @@ -163,6 +163,7 @@ RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); } RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); } RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); } + RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction); } RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); } RetTy visitShiftInst(ShiftInst &I) { DELEGATE(Instruction); } RetTy visitVANextInst(VANextInst &I) { DELEGATE(Instruction); } From lattner at cs.uiuc.edu Thu Mar 11 23:52:23 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:52:23 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Instruction.def Message-ID: <200403120551.XAA18419@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Instruction.def updated: 1.12 -> 1.13 --- Log message: Add the Instruction::Select enum --- Diffs of the changes: (+4 -3) Index: llvm/include/llvm/Instruction.def diff -u llvm/include/llvm/Instruction.def:1.12 llvm/include/llvm/Instruction.def:1.13 --- llvm/include/llvm/Instruction.def:1.12 Tue Nov 11 16:41:29 2003 +++ llvm/include/llvm/Instruction.def Thu Mar 11 23:50:53 2004 @@ -129,10 +129,11 @@ HANDLE_OTHER_INST(30, Shr , ShiftInst ) HANDLE_OTHER_INST(31, VANext , VANextInst ) // vanext instruction HANDLE_OTHER_INST(32, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(33, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(33, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(34, UserOp2, Instruction) - LAST_OTHER_INST(34) +HANDLE_OTHER_INST(34, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(35, UserOp2, Instruction) + LAST_OTHER_INST(35) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST From lattner at cs.uiuc.edu Thu Mar 11 23:52:32 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:52:32 2004 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/Lexer.l llvmAsmParser.y Message-ID: <200403120551.XAA18432@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: Lexer.l updated: 1.45 -> 1.46 llvmAsmParser.y updated: 1.158 -> 1.159 --- Log message: Allow parsing select instruction and constant expr --- Diffs of the changes: (+16 -1) Index: llvm/lib/AsmParser/Lexer.l diff -u llvm/lib/AsmParser/Lexer.l:1.45 llvm/lib/AsmParser/Lexer.l:1.46 --- llvm/lib/AsmParser/Lexer.l:1.45 Sun Feb 8 15:48:25 2004 +++ llvm/lib/AsmParser/Lexer.l Thu Mar 11 23:51:36 2004 @@ -234,6 +234,7 @@ phi { RET_TOK(OtherOpVal, PHI, PHI_TOK); } call { RET_TOK(OtherOpVal, Call, CALL); } cast { RET_TOK(OtherOpVal, Cast, CAST); } +select { RET_TOK(OtherOpVal, Select, SELECT); } shl { RET_TOK(OtherOpVal, Shl, SHL); } shr { RET_TOK(OtherOpVal, Shr, SHR); } va_arg { return VA_ARG; /* FIXME: OBSOLETE */} Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.158 llvm/lib/AsmParser/llvmAsmParser.y:1.159 --- llvm/lib/AsmParser/llvmAsmParser.y:1.158 Mon Mar 8 10:14:19 2004 +++ llvm/lib/AsmParser/llvmAsmParser.y Thu Mar 11 23:51:36 2004 @@ -876,7 +876,7 @@ // Other Operators %type ShiftOps -%token PHI_TOK CALL CAST SHL SHR VAARG VANEXT +%token PHI_TOK CALL CAST SELECT SHL SHR VAARG VANEXT %token VA_ARG // FIXME: OBSOLETE %start Module @@ -1251,6 +1251,13 @@ $$ = ConstantExpr::getGetElementPtr($3, IdxVec); } + | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' { + if ($3->getType() != Type::BoolTy) + ThrowException("Select condition must be of boolean type!"); + if ($5->getType() != $7->getType()) + ThrowException("Select operand types must match!"); + $$ = ConstantExpr::getSelect($3, $5, $7); + } | BinaryOps '(' ConstVal ',' ConstVal ')' { if ($3->getType() != $5->getType()) ThrowException("Binary operator types must match!"); @@ -1801,6 +1808,13 @@ $4->get()->getDescription() + "'!"); $$ = new CastInst($2, *$4); delete $4; + } + | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { + if ($2->getType() != Type::BoolTy) + ThrowException("select condition must be boolean!"); + if ($4->getType() != $6->getType()) + ThrowException("select value types should match!"); + $$ = new SelectInst($2, $4, $6); } | VA_ARG ResolvedVal ',' Types { // FIXME: This is emulation code for an obsolete syntax. This should be From lattner at cs.uiuc.edu Thu Mar 11 23:52:40 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:52:40 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/InstructionReader.cpp Message-ID: <200403120551.XAA18443@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: InstructionReader.cpp updated: 1.67 -> 1.68 --- Log message: Read select instrs from bytecode --- Diffs of the changes: (+5 -0) Index: llvm/lib/Bytecode/Reader/InstructionReader.cpp diff -u llvm/lib/Bytecode/Reader/InstructionReader.cpp:1.67 llvm/lib/Bytecode/Reader/InstructionReader.cpp:1.68 --- llvm/lib/Bytecode/Reader/InstructionReader.cpp:1.67 Sun Feb 8 22:13:38 2004 +++ llvm/lib/Bytecode/Reader/InstructionReader.cpp Thu Mar 11 23:51:49 2004 @@ -156,6 +156,11 @@ case Instruction::Cast: Result = new CastInst(getValue(RI.Type, Args[0]), getType(Args[1])); break; + case Instruction::Select: + Result = new SelectInst(getValue(Type::BoolTyID, Args[0]), + getValue(RI.Type, Args[1]), + getValue(RI.Type, Args[2])); + break; case Instruction::PHI: { if (Args.size() == 0 || (Args.size() & 1)) throw std::string("Invalid phi node encountered!\n"); From lattner at cs.uiuc.edu Thu Mar 11 23:53:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:53:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200403120552.XAA18480@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.168 -> 1.169 --- Log message: Add trivial optimizations for select instructions --- Diffs of the changes: (+15 -0) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.168 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.169 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.168 Fri Feb 27 23:22:00 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Mar 11 23:52:32 2004 @@ -108,6 +108,7 @@ Instruction *visitSetCondInst(BinaryOperator &I); Instruction *visitShiftInst(ShiftInst &I); Instruction *visitCastInst(CastInst &CI); + Instruction *visitSelectInst(SelectInst &CI); Instruction *visitCallInst(CallInst &CI); Instruction *visitInvokeInst(InvokeInst &II); Instruction *visitPHINode(PHINode &PN); @@ -1930,6 +1931,20 @@ return 0; } + +Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { + if (ConstantBool *C = dyn_cast(SI.getCondition())) + if (C == ConstantBool::True) + return ReplaceInstUsesWith(SI, SI.getTrueValue()); + else { + assert(C == ConstantBool::False); + return ReplaceInstUsesWith(SI, SI.getFalseValue()); + } + // Other transformations are possible! + + return 0; +} + // CallInst simplification // From lattner at cs.uiuc.edu Thu Mar 11 23:53:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:53:08 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200403120552.XAA18489@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SCCP.cpp updated: 1.90 -> 1.91 --- Log message: Add sccp support for select instructions --- Diffs of the changes: (+23 -0) Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.90 llvm/lib/Transforms/Scalar/SCCP.cpp:1.91 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.90 Sun Mar 7 16:16:24 2004 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Thu Mar 11 23:52:44 2004 @@ -212,6 +212,7 @@ void visitTerminatorInst(TerminatorInst &TI); void visitCastInst(CastInst &I); + void visitSelectInst(SelectInst &I); void visitBinaryOperator(Instruction &I); void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); } @@ -563,6 +564,28 @@ markOverdefined(&I); else if (VState.isConstant()) // Propagate constant value markConstant(&I, ConstantExpr::getCast(VState.getConstant(), I.getType())); +} + +void SCCP::visitSelectInst(SelectInst &I) { + InstVal &CondValue = getValueState(I.getCondition()); + if (CondValue.isOverdefined()) + markOverdefined(&I); + else if (CondValue.isConstant()) { + if (CondValue.getConstant() == ConstantBool::True) { + InstVal &Val = getValueState(I.getTrueValue()); + if (Val.isOverdefined()) + markOverdefined(&I); + else if (Val.isConstant()) + markConstant(&I, Val.getConstant()); + } else if (CondValue.getConstant() == ConstantBool::False) { + InstVal &Val = getValueState(I.getFalseValue()); + if (Val.isOverdefined()) + markOverdefined(&I); + else if (Val.isConstant()) + markConstant(&I, Val.getConstant()); + } else + markOverdefined(&I); + } } // Handle BinaryOperators and Shift Instructions... From lattner at cs.uiuc.edu Thu Mar 11 23:53:16 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:53:16 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200403120552.XAA18465@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.165 -> 1.166 --- Log message: ADd support for select instructions --- Diffs of the changes: (+12 -0) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.165 llvm/lib/Target/CBackend/Writer.cpp:1.166 --- llvm/lib/Target/CBackend/Writer.cpp:1.165 Thu Feb 26 16:20:58 2004 +++ llvm/lib/Target/CBackend/Writer.cpp Thu Mar 11 23:52:14 2004 @@ -140,6 +140,7 @@ void visitBinaryOperator(Instruction &I); void visitCastInst (CastInst &I); + void visitSelectInst(SelectInst &I); void visitCallInst (CallInst &I); void visitCallSite (CallSite CS); void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); } @@ -1184,6 +1185,17 @@ writeOperand(I.getOperand(0)); } + +void CWriter::visitSelectInst(SelectInst &I) { + Out << "(("; + writeOperand(I.getCondition()); + Out << ") ? ("; + writeOperand(I.getTrueValue()); + Out << ") : ("; + writeOperand(I.getFalseValue()); + Out << "))"; +} + void CWriter::lowerIntrinsics(Module &M) { for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) From lattner at cs.uiuc.edu Thu Mar 11 23:53:24 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:53:24 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Writer/InstructionWriter.cpp Message-ID: <200403120552.XAA18454@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Writer: InstructionWriter.cpp updated: 1.39 -> 1.40 --- Log message: Write select instructions to bytecode --- Diffs of the changes: (+2 -1) Index: llvm/lib/Bytecode/Writer/InstructionWriter.cpp diff -u llvm/lib/Bytecode/Writer/InstructionWriter.cpp:1.39 llvm/lib/Bytecode/Writer/InstructionWriter.cpp:1.40 --- llvm/lib/Bytecode/Writer/InstructionWriter.cpp:1.39 Sat Jan 31 19:50:31 2004 +++ llvm/lib/Bytecode/Writer/InstructionWriter.cpp Thu Mar 11 23:52:01 2004 @@ -207,9 +207,10 @@ // const Type *Ty; switch (I.getOpcode()) { + case Instruction::Select: case Instruction::Malloc: case Instruction::Alloca: - Ty = I.getType(); // Malloc & Alloca ALWAYS want to encode the return type + Ty = I.getType(); // These ALWAYS want to encode the return type break; case Instruction::Store: Ty = I.getOperand(1)->getType(); // Encode the pointer type... From lattner at cs.uiuc.edu Thu Mar 11 23:54:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:54:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200403120553.XAA18506@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.17 -> 1.18 --- Log message: Add constant folding wrapper support for select instructions. --- Diffs of the changes: (+4 -0) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.17 llvm/lib/Transforms/Utils/Local.cpp:1.18 --- llvm/lib/Transforms/Utils/Local.cpp:1.17 Mon Jan 12 13:56:36 2004 +++ llvm/lib/Transforms/Utils/Local.cpp Thu Mar 11 23:53:03 2004 @@ -79,6 +79,10 @@ default: return 0; case Instruction::Cast: return ConstantExpr::getCast(Op0, I->getType()); + case Instruction::Select: + if (Constant *Op2 = dyn_cast(I->getOperand(2))) + return ConstantExpr::getSelect(Op0, Op1, Op2); + return 0; case Instruction::GetElementPtr: std::vector IdxList; IdxList.reserve(I->getNumOperands()-1); From lattner at cs.uiuc.edu Thu Mar 11 23:54:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:54:09 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp Message-ID: <200403120553.XAA18525@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.cpp updated: 1.54 -> 1.55 --- Log message: Teach the constant folder how to do select instructions --- Diffs of the changes: (+11 -0) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.54 llvm/lib/VMCore/ConstantFolding.cpp:1.55 --- llvm/lib/VMCore/ConstantFolding.cpp:1.54 Mon Mar 8 00:17:35 2004 +++ llvm/lib/VMCore/ConstantFolding.cpp Thu Mar 11 23:53:32 2004 @@ -582,6 +582,17 @@ } } +Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond, + const Constant *V1, + const Constant *V2) { + if (Cond == ConstantBool::True) + return const_cast(V1); + else if (Cond == ConstantBool::False) + return const_cast(V2); + return 0; +} + + /// IdxCompare - Compare the two constants as though they were getelementptr /// indices. This allows coersion of the types to be the same thing. /// From lattner at cs.uiuc.edu Thu Mar 11 23:55:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:55:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.h Message-ID: <200403120554.XAA18542@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.h updated: 1.40 -> 1.41 --- Log message: Add new function --- Diffs of the changes: (+3 -0) Index: llvm/lib/VMCore/ConstantFolding.h diff -u llvm/lib/VMCore/ConstantFolding.h:1.40 llvm/lib/VMCore/ConstantFolding.h:1.41 --- llvm/lib/VMCore/ConstantFolding.h:1.40 Mon Jan 12 15:13:12 2004 +++ llvm/lib/VMCore/ConstantFolding.h Thu Mar 11 23:53:41 2004 @@ -27,6 +27,9 @@ // Constant fold various types of instruction... Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy); + Constant *ConstantFoldSelectInstruction(const Constant *Cond, + const Constant *V1, + const Constant *V2); Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, const Constant *V2); Constant *ConstantFoldGetElementPtr(const Constant *C, From lattner at cs.uiuc.edu Thu Mar 11 23:55:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:55:09 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200403120554.XAA18557@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.84 -> 1.85 --- Log message: Add support for checking the select instruction --- Diffs of the changes: (+11 -0) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.84 llvm/lib/VMCore/Verifier.cpp:1.85 --- llvm/lib/VMCore/Verifier.cpp:1.84 Mon Mar 1 18:22:19 2004 +++ llvm/lib/VMCore/Verifier.cpp Thu Mar 11 23:54:31 2004 @@ -144,6 +144,7 @@ void visitInstruction(Instruction &I); void visitTerminatorInst(TerminatorInst &I); void visitReturnInst(ReturnInst &RI); + void visitSelectInst(SelectInst &SI); void visitUserOp1(Instruction &I); void visitUserOp2(Instruction &I) { visitUserOp1(I); } void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); @@ -334,6 +335,16 @@ // terminators... visitTerminatorInst(RI); } + +void Verifier::visitSelectInst(SelectInst &SI) { + Assert1(SI.getCondition()->getType() == Type::BoolTy, + "Select condition type must be bool!", &SI); + Assert1(SI.getTrueValue()->getType() == SI.getFalseValue()->getType(), + "Select values must have identical types!", &SI); + Assert1(SI.getTrueValue()->getType() == SI.getType(), + "Select values must have same type as select instruction!", &SI); +} + /// visitUserOp1 - User defined operators shouldn't live beyond the lifetime of /// a pass, if any exist, it's an error. From lattner at cs.uiuc.edu Thu Mar 11 23:55:17 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:55:17 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200403120554.XAA18562@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.81 -> 1.82 --- Log message: Add support for select constant expressions. Use reserve a bit more to avoid memory wasteage. --- Diffs of the changes: (+35 -0) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.81 llvm/lib/VMCore/Constants.cpp:1.82 --- llvm/lib/VMCore/Constants.cpp:1.81 Mon Mar 8 00:11:10 2004 +++ llvm/lib/VMCore/Constants.cpp Thu Mar 11 23:54:04 2004 @@ -267,14 +267,26 @@ ConstantPointerRef::ConstantPointerRef(GlobalValue *GV) : Constant(GV->getType()) { + Operands.reserve(1); Operands.push_back(Use(GV, this)); } ConstantExpr::ConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) : Constant(Ty), iType(Opcode) { + Operands.reserve(1); Operands.push_back(Use(C, this)); } +// Select instruction creation ctor +ConstantExpr::ConstantExpr(Constant *C, Constant *V1, Constant *V2) + : Constant(V1->getType()), iType(Instruction::Select) { + Operands.reserve(3); + Operands.push_back(Use(C, this)); + Operands.push_back(Use(V1, this)); + Operands.push_back(Use(V2, this)); +} + + static bool isSetCC(unsigned Opcode) { return Opcode == Instruction::SetEQ || Opcode == Instruction::SetNE || Opcode == Instruction::SetLT || Opcode == Instruction::SetGT || @@ -283,6 +295,7 @@ ConstantExpr::ConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) : Constant(isSetCC(Opcode) ? Type::BoolTy : C1->getType()), iType(Opcode) { + Operands.reserve(2); Operands.push_back(Use(C1, this)); Operands.push_back(Use(C2, this)); } @@ -997,6 +1010,11 @@ case Instruction::Cast: New = ConstantExpr::getCast(OldC->getOperand(0), NewTy); break; + case Instruction::Select: + New = ConstantExpr::getSelectTy(NewTy, OldC->getOperand(0), + OldC->getOperand(1), + OldC->getOperand(2)); + break; case Instruction::Shl: case Instruction::Shr: New = ConstantExpr::getShiftTy(NewTy, OldC->getOpcode(), @@ -1056,6 +1074,23 @@ std::vector argVec(1, C1); argVec.push_back(C2); ExprMapKeyType Key = std::make_pair(Opcode, argVec); + return ExprConstants.getOrCreate(ReqTy, Key); +} + +Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, + Constant *V1, Constant *V2) { + assert(C->getType() == Type::BoolTy && "Select condition must be bool!"); + assert(V1->getType() == V2->getType() && "Select value types must match!"); + assert(V1->getType()->isFirstClassType() && "Cannot select aggregate type!"); + + if (ReqTy == V1->getType()) + if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2)) + return SC; // Fold common cases + + std::vector argVec(3, C); + argVec[1] = V1; + argVec[2] = V2; + ExprMapKeyType Key = std::make_pair(Instruction::Select, argVec); return ExprConstants.getOrCreate(ReqTy, Key); } From lattner at cs.uiuc.edu Thu Mar 11 23:55:26 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:55:26 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200403120554.XAA18571@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.125 -> 1.126 --- Log message: Print select instructions correctly --- Diffs of the changes: (+3 -2) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.125 llvm/lib/VMCore/AsmWriter.cpp:1.126 --- llvm/lib/VMCore/AsmWriter.cpp:1.125 Mon Mar 8 12:51:45 2004 +++ llvm/lib/VMCore/AsmWriter.cpp Thu Mar 11 23:53:14 2004 @@ -915,8 +915,9 @@ bool PrintAllTypes = false; const Type *TheType = Operand->getType(); - // Shift Left & Right print both types even for Ubyte LHS - if (isa(I)) { + // Shift Left & Right print both types even for Ubyte LHS, and select prints + // types even if all operands are bools. + if (isa(I) || isa(I)) { PrintAllTypes = true; } else { for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) { From lattner at cs.uiuc.edu Thu Mar 11 23:55:34 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:55:34 2004 Subject: [llvm-commits] CVS: llvm/utils/emacs/llvm-mode.el Message-ID: <200403120554.XAA18578@zion.cs.uiuc.edu> Changes in directory llvm/utils/emacs: llvm-mode.el updated: 1.11 -> 1.12 --- Log message: Teach emacs about the select instruction --- Diffs of the changes: (+1 -1) Index: llvm/utils/emacs/llvm-mode.el diff -u llvm/utils/emacs/llvm-mode.el:1.11 llvm/utils/emacs/llvm-mode.el:1.12 --- llvm/utils/emacs/llvm-mode.el:1.11 Sun Oct 26 23:09:11 2003 +++ llvm/utils/emacs/llvm-mode.el Thu Mar 11 23:54:48 2004 @@ -31,7 +31,7 @@ ;; Arithmetic and Logical Operators '("add\\|sub\\|mul\\|div\\|rem\\|and\\|or\\|xor\\|set\\(ne\\|eq\\|lt\\|gt\\|le\\|ge\\)" . font-lock-keyword-face) ;; Special instructions - '("phi\\|call\\|cast\\|to\\|shl\\|shr\\|vaarg\\|vanext" . font-lock-keyword-face) + '("phi\\|call\\|cast\\|select\\|to\\|shl\\|shr\\|vaarg\\|vanext" . font-lock-keyword-face) ;; Control instructions '("ret\\|br\\|switch\\|invoke\\|unwind" . font-lock-keyword-face) ;; Memory operators From lattner at cs.uiuc.edu Thu Mar 11 23:56:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:56:00 2004 Subject: [llvm-commits] CVS: llvm/utils/vim/llvm.vim Message-ID: <200403120555.XAA18597@zion.cs.uiuc.edu> Changes in directory llvm/utils/vim: llvm.vim updated: 1.9 -> 1.10 --- Log message: Teach vim about the select instruction. Allow it to forget about the long-dead not instruction. --- Diffs of the changes: (+2 -2) Index: llvm/utils/vim/llvm.vim diff -u llvm/utils/vim/llvm.vim:1.9 llvm/utils/vim/llvm.vim:1.10 --- llvm/utils/vim/llvm.vim:1.9 Sun Oct 26 23:09:15 2003 +++ llvm/utils/vim/llvm.vim Thu Mar 11 23:55:07 2004 @@ -20,7 +20,7 @@ syn keyword llvmStatement and or xor syn keyword llvmStatement setne seteq setlt setgt setle setge -syn keyword llvmStatement phi call cast to shl shr vaarg vanext +syn keyword llvmStatement phi call cast to select shl shr vaarg vanext syn keyword llvmStatement ret br switch invoke unwind syn keyword llvmStatement malloc alloca free load store getelementptr @@ -28,7 +28,7 @@ syn keyword llvmStatement declare global constant const syn keyword llvmStatement internal uninitialized external implementation syn keyword llvmStatement linkonce weak appending -syn keyword llvmStatement null to except not target endian pointersize +syn keyword llvmStatement null to except target endian pointersize syn keyword llvmStatement big little volatile "syn match llvmFunction /%[a-zA-Z\$._\-][a-zA-Z\$._\-0-9]*/ From lattner at cs.uiuc.edu Thu Mar 11 23:56:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Mar 11 23:56:08 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Instruction.cpp Message-ID: <200403120555.XAA18586@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Instruction.cpp updated: 1.34 -> 1.35 --- Log message: Know the opcode name of the select instruction --- Diffs of the changes: (+1 -0) Index: llvm/lib/VMCore/Instruction.cpp diff -u llvm/lib/VMCore/Instruction.cpp:1.34 llvm/lib/VMCore/Instruction.cpp:1.35 --- llvm/lib/VMCore/Instruction.cpp:1.34 Tue Feb 3 19:06:38 2004 +++ llvm/lib/VMCore/Instruction.cpp Thu Mar 11 23:54:20 2004 @@ -97,6 +97,7 @@ // Other instructions... case PHI: return "phi"; case Cast: return "cast"; + case Select: return "select"; case Call: return "call"; case Shl: return "shl"; case Shr: return "shr"; From lattner at cs.uiuc.edu Fri Mar 12 00:02:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 00:02:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/select.ll Message-ID: <200403120601.AAA18651@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: select.ll added (r1.1) --- Log message: test instruction combiner opts for select instruction --- Diffs of the changes: (+18 -0) Index: llvm/test/Regression/Transforms/InstCombine/select.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/select.ll:1.1 *** /dev/null Fri Mar 12 00:01:10 2004 --- llvm/test/Regression/Transforms/InstCombine/select.ll Fri Mar 12 00:01:00 2004 *************** *** 0 **** --- 1,18 ---- + ; This test makes sure that these instructions are properly eliminated. + ; + + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep select + + implementation + + int %test1(int %A, int %B) { + %C = select bool false, int %A, int %B + ret int %C + } + + int %test2(int %A, int %B) { + %C = select bool true, int %A, int %B + ret int %C + } + + From brukman at cs.uiuc.edu Fri Mar 12 00:14:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Mar 12 00:14:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/PassAnalysisSupport.h Message-ID: <200403120613.AAA18805@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: PassAnalysisSupport.h updated: 1.17 -> 1.18 --- Log message: Add AnalysisUsage::addRequiredTransitive() to keep analysis info alive for future queries by clients. --- Diffs of the changes: (+17 -4) Index: llvm/include/llvm/PassAnalysisSupport.h diff -u llvm/include/llvm/PassAnalysisSupport.h:1.17 llvm/include/llvm/PassAnalysisSupport.h:1.18 --- llvm/include/llvm/PassAnalysisSupport.h:1.17 Tue Nov 11 16:41:30 2003 +++ llvm/include/llvm/PassAnalysisSupport.h Fri Mar 12 00:13:15 2004 @@ -25,14 +25,15 @@ //===----------------------------------------------------------------------===// // AnalysisUsage - Represent the analysis usage information of a pass. This -// tracks analyses that the pass REQUIRES (must available when the pass runs), -// and analyses that the pass PRESERVES (the pass does not invalidate the -// results of these analyses). This information is provided by a pass to the +// tracks analyses that the pass REQUIRES (must be available when the pass +// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the +// pass), and analyses that the pass PRESERVES (the pass does not invalidate the +// results of these analyses). This information is provided by a pass to the // Pass infrastructure through the getAnalysisUsage virtual function. // class AnalysisUsage { // Sets of analyses required and preserved by a pass - std::vector Required, Preserved; + std::vector Required, RequiredTransitive, Preserved; bool PreservesAll; public: AnalysisUsage() : PreservesAll(false) {} @@ -51,6 +52,15 @@ return *this; } + template + AnalysisUsage &addRequiredTransitive() { + AnalysisID ID = Pass::getClassPassInfo(); + assert(ID && "Pass class not registered!"); + Required.push_back(ID); + RequiredTransitive.push_back(ID); + return *this; + } + // addPreserved - Add the specified ID to the set of analyses preserved by // this pass // @@ -82,6 +92,9 @@ void setPreservesCFG(); const std::vector &getRequiredSet() const { return Required; } + const std::vector &getRequiredTransitiveSet() const { + return RequiredTransitive; + } const std::vector &getPreservedSet() const { return Preserved; } }; From brukman at cs.uiuc.edu Fri Mar 12 00:15:05 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Mar 12 00:15:05 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200403120614.AAA18830@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.15 -> 1.16 --- Log message: Implement getModRefInfo() for DSA to calculate whether a function modifies or references a pointer. --- Diffs of the changes: (+39 -5) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.15 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.16 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.15 Fri Jan 30 16:20:55 2004 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Fri Mar 12 00:14:22 2004 @@ -12,15 +12,16 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Module.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/DataStructure.h" #include "llvm/Analysis/DSGraph.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Module.h" using namespace llvm; namespace { class DSAA : public Pass, public AliasAnalysis { TDDataStructures *TD; + BUDataStructures *BU; public: DSAA() : TD(0) {} @@ -34,14 +35,16 @@ bool run(Module &M) { InitializeAliasAnalysis(this); TD = &getAnalysis(); + BU = &getAnalysis(); return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AliasAnalysis::getAnalysisUsage(AU); - AU.setPreservesAll(); // Does not transform code... - AU.addRequired(); // Uses TD Datastructures - AU.addRequired(); // Chains to another AA impl... + AU.setPreservesAll(); // Does not transform code + AU.addRequiredTransitive(); // Uses TD Datastructures + AU.addRequiredTransitive(); // Uses BU Datastructures + AU.addRequired(); // Chains to another AA impl } //------------------------------------------------ @@ -56,6 +59,9 @@ bool pointsToConstantMemory(const Value *P) { return getAnalysis().pointsToConstantMemory(P); } + + AliasAnalysis::ModRefResult + getModRefInfo(CallSite CS, Value *P, unsigned Size); private: DSGraph *getGraphForValue(const Value *V); @@ -150,6 +156,34 @@ // FIXME: we could improve on this by checking the globals graph for aliased // global queries... return getAnalysis().alias(V1, V1Size, V2, V2Size); +} + +/// getModRefInfo - does a callsite modify or reference a value? +/// +AliasAnalysis::ModRefResult +DSAA::getModRefInfo(CallSite CS, Value *P, unsigned Size) { + Function *F = CS.getCalledFunction(); + if (!F) return pointsToConstantMemory(P) ? Ref : ModRef; + if (F->isExternal()) return ModRef; + + // Clone the function TD graph, clearing off Mod/Ref flags + const Function *csParent = CS.getInstruction()->getParent()->getParent(); + DSGraph TDGraph(TD->getDSGraph(*csParent)); + TDGraph.maskNodeTypes(0); + + // Insert the callee's BU graph into the TD graph + const DSGraph &BUGraph = BU->getDSGraph(*F); + TDGraph.mergeInGraph(TDGraph.getDSCallSiteForCallSite(CS), + *F, BUGraph, 0); + + // Report the flags that have been added + const DSNodeHandle &DSH = TDGraph.getNodeForValue(P); + if (const DSNode *N = DSH.getNode()) + if (N->isModified()) + return N->isRead() ? ModRef : Mod; + else + return N->isRead() ? Ref : NoModRef; + return NoModRef; } From brukman at cs.uiuc.edu Fri Mar 12 00:16:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Mar 12 00:16:00 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200403120615.AAA18848@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp updated: 1.10 -> 1.11 --- Log message: Evaluate ModRef information in addition to regular ol' pointer analysis. --- Diffs of the changes: (+93 -24) Index: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp diff -u llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.10 llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.11 --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.10 Wed Dec 10 09:33:59 2003 +++ llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Fri Mar 12 00:15:08 2004 @@ -17,23 +17,31 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Pass.h" #include "llvm/Function.h" +#include "llvm/iOther.h" +#include "llvm/iTerminators.h" +#include "llvm/Pass.h" #include "llvm/Type.h" -#include "llvm/Support/InstIterator.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Assembly/Writer.h" +#include "llvm/Support/InstIterator.h" #include "Support/CommandLine.h" #include using namespace llvm; namespace { - cl::opt PrintNo ("print-no-aliases", cl::ReallyHidden); - cl::opt PrintMay ("print-may-aliases", cl::ReallyHidden); - cl::opt PrintMust("print-must-aliases", cl::ReallyHidden); + cl::opt PrintNoAlias("print-no-aliases", cl::ReallyHidden); + cl::opt PrintMayAlias("print-may-aliases", cl::ReallyHidden); + cl::opt PrintMustAlias("print-must-aliases", cl::ReallyHidden); + + cl::opt PrintNoModRef("print-no-modref", cl::ReallyHidden); + cl::opt PrintMod("print-mod", cl::ReallyHidden); + cl::opt PrintRef("print-ref", cl::ReallyHidden); + cl::opt PrintModRef("print-modref", cl::ReallyHidden); class AAEval : public FunctionPass { - unsigned No, May, Must; + unsigned NoAlias, MayAlias, MustAlias; + unsigned NoModRef, Mod, Ref, ModRef; public: virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -41,7 +49,12 @@ AU.setPreservesAll(); } - bool doInitialization(Module &M) { No = May = Must = 0; return false; } + bool doInitialization(Module &M) { + NoAlias = MayAlias = MustAlias = 0; + NoModRef = Mod = Ref = ModRef = 0; + return false; + } + bool runOnFunction(Function &F); bool doFinalization(Module &M); }; @@ -63,6 +76,7 @@ AliasAnalysis &AA = getAnalysis(); std::set Pointers; + std::set CallSites; for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I) if (isa(I->getType())) // Add all pointer arguments @@ -76,7 +90,15 @@ Pointers.insert(*OI); } - if (PrintNo || PrintMay || PrintMust) + for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { + if (CallInst *CI = dyn_cast(*I)) + CallSites.insert(CallSite(CI)); + else if (InvokeInst *II = dyn_cast(*I)) + CallSites.insert(CallSite(II)); + } + + if (PrintNoAlias || PrintMayAlias || PrintMustAlias || + PrintNoModRef || PrintMod || PrintRef || PrintModRef) std::cerr << "Function: " << F.getName() << "\n"; // iterate over the worklist, and run the full (n^2)/2 disambiguations @@ -85,34 +107,81 @@ for (std::set::iterator I2 = Pointers.begin(); I2 != I1; ++I2) switch (AA.alias(*I1, 0, *I2, 0)) { case AliasAnalysis::NoAlias: - PrintResults("No", PrintNo, *I1, *I2, F.getParent()); - ++No; break; + PrintResults("NoAlias", PrintNoAlias, *I1, *I2, F.getParent()); + ++NoAlias; break; case AliasAnalysis::MayAlias: - PrintResults("May", PrintMay, *I1, *I2, F.getParent()); - ++May; break; + PrintResults("MayAlias", PrintMayAlias, *I1, *I2, F.getParent()); + ++MayAlias; break; case AliasAnalysis::MustAlias: - PrintResults("Must", PrintMust, *I1, *I2, F.getParent()); - ++Must; break; + PrintResults("MustAlias", PrintMustAlias, *I1, *I2, F.getParent()); + ++MustAlias; break; default: std::cerr << "Unknown alias query result!\n"; } + // Mod/ref alias analysis: compare all pairs of calls and values + for (std::set::iterator V = Pointers.begin(), Ve = Pointers.end(); + V != Ve; ++V) + for (std::set::iterator C = CallSites.begin(), + Ce = CallSites.end(); C != Ce; ++C) { + Instruction *I = C->getInstruction(); + switch (AA.getModRefInfo(*C, *V, (*V)->getType()->getPrimitiveSize())) { + case AliasAnalysis::NoModRef: + PrintResults("NoModRef", PrintNoModRef, I, *V, F.getParent()); + ++NoModRef; break; + case AliasAnalysis::Mod: + PrintResults("Mod", PrintMod, I, *V, F.getParent()); + ++Mod; break; + case AliasAnalysis::Ref: + PrintResults("Ref", PrintRef, I, *V, F.getParent()); + ++Ref; break; + case AliasAnalysis::ModRef: + PrintResults("ModRef", PrintModRef, I, *V, F.getParent()); + ++ModRef; break; + default: + std::cerr << "Unknown alias query result!\n"; + } + } + return false; } bool AAEval::doFinalization(Module &M) { - unsigned Sum = No+May+Must; + unsigned AliasSum = NoAlias + MayAlias + MustAlias; std::cerr << "===== Alias Analysis Evaluator Report =====\n"; - if (Sum == 0) { + if (AliasSum == 0) { std::cerr << " Alias Analysis Evaluator Summary: No pointers!\n"; - return false; + } else { + std::cerr << " " << AliasSum << " Total Alias Queries Performed\n"; + std::cerr << " " << NoAlias << " no alias responses (" + << NoAlias*100/AliasSum << "%)\n"; + std::cerr << " " << MayAlias << " may alias responses (" + << MayAlias*100/AliasSum << "%)\n"; + std::cerr << " " << MustAlias << " must alias responses (" + << MustAlias*100/AliasSum <<"%)\n"; + std::cerr << " Alias Analysis Evaluator Pointer Alias Summary: " + << NoAlias*100/AliasSum << "%/" << MayAlias*100/AliasSum << "%/" + << MustAlias*100/AliasSum << "%\n"; + } + + // Display the summary for mod/ref analysis + unsigned ModRefSum = NoModRef + Mod + Ref + ModRef; + if (ModRefSum == 0) { + std::cerr << " Alias Analysis Mod/Ref Evaluator Summary: no mod/ref!\n"; + } else { + std::cerr << " " << ModRefSum << " Total ModRef Queries Performed\n"; + std::cerr << " " << NoModRef << " no mod/ref responses (" + << NoModRef*100/ModRefSum << "%)\n"; + std::cerr << " " << Mod << " mod responses (" + << Mod*100/ModRefSum << "%)\n"; + std::cerr << " " << Ref << " ref responses (" + << Ref*100/ModRefSum <<"%)\n"; + std::cerr << " " << ModRef << " mod & ref responses (" + << ModRef*100/ModRefSum <<"%)\n"; + std::cerr << " Alias Analysis Evaluator Mod/Ref Summary: " + << NoModRef*100/ModRefSum << "%/" << Mod*100/ModRefSum << "%/" + << Ref*100/ModRefSum << "%/" << ModRef*100/ModRefSum << "%\n"; } - std::cerr << " " << Sum << " Total Alias Queries Performed\n"; - std::cerr << " " << No << " no alias responses (" << No*100/Sum << "%)\n"; - std::cerr << " " << May << " may alias responses (" << May*100/Sum << "%)\n"; - std::cerr << " " << Must << " must alias responses (" < Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.47 -> 1.48 --- Log message: Keep transitively-required passes alive for queries to work after the initial user pass is destroyed. --- Diffs of the changes: (+10 -1) Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.47 llvm/lib/VMCore/PassManagerT.h:1.48 --- llvm/lib/VMCore/PassManagerT.h:1.47 Sun Feb 29 16:37:04 2004 +++ llvm/lib/VMCore/PassManagerT.h Fri Mar 12 00:16:28 2004 @@ -208,7 +208,6 @@ E = LastUseOf.end(); I != E; ++I) LastUserOf[I->second].push_back(I->first); - // Output debug information... if (Parent == 0) PMDebug::PerformPassStartupStuff(this); @@ -397,6 +396,16 @@ if (I != CurrentAnalyses.end()) { LastUseOf[I->second] = User; // Local pass, extend the lifetime + + // Prolong live range of analyses that are needed after an analysis pass + // is destroyed, for querying by subsequent passes + AnalysisUsage AnUsage; + I->second->getAnalysisUsage(AnUsage); + const std::vector &IDs = AnUsage.getRequiredTransitiveSet(); + for (std::vector::const_iterator i = IDs.begin(), + e = IDs.end(); i != e; ++i) + markPassUsed(*i, User); + } else { // Pass not in current available set, must be a higher level pass // available to us, propagate to parent pass manager... We tell the From brukman at cs.uiuc.edu Fri Mar 12 00:18:03 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Mar 12 00:18:03 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/DSGraph/2004-03-10-ElimLoad.ll 2004-03-10-NoElimLoad.ll Message-ID: <200403120617.AAA18921@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: 2004-03-10-ElimLoad.ll updated: 1.1 -> 1.2 2004-03-10-NoElimLoad.ll updated: 1.1 -> 1.2 --- Log message: Test the mod/ref analysis in DSA. --- Diffs of the changes: (+27 -0) Index: llvm/test/Regression/Analysis/DSGraph/2004-03-10-ElimLoad.ll diff -u /dev/null llvm/test/Regression/Analysis/DSGraph/2004-03-10-ElimLoad.ll:1.2 --- /dev/null Fri Mar 12 00:17:32 2004 +++ llvm/test/Regression/Analysis/DSGraph/2004-03-10-ElimLoad.ll Fri Mar 12 00:17:22 2004 @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | opt -ds-aa -load-vn -gcse -instcombine | llvm-dis | not grep sub + +void %bar(int* %p) { + ret void +} + +int %foo(int* %a) { + %b = load int* %a + call void %bar(int* %a) + %d = load int* %a + %e = sub int %b, %d + ret int %e +} Index: llvm/test/Regression/Analysis/DSGraph/2004-03-10-NoElimLoad.ll diff -u /dev/null llvm/test/Regression/Analysis/DSGraph/2004-03-10-NoElimLoad.ll:1.2 --- /dev/null Fri Mar 12 00:17:32 2004 +++ llvm/test/Regression/Analysis/DSGraph/2004-03-10-NoElimLoad.ll Fri Mar 12 00:17:22 2004 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | opt -ds-aa -load-vn -gcse -instcombine | llvm-dis | grep sub + +void %bar(int* %p) { + store int 15, int* %p + ret void +} + +int %foo(int* %a) { + %b = load int* %a + call void %bar(int* %a) + %d = load int* %a + %e = sub int %b, %d + ret int %e +} From brukman at cs.uiuc.edu Fri Mar 12 10:22:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Mar 12 10:22:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200403121621.KAA14230@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp updated: 1.11 -> 1.12 --- Log message: Simplify code to process CallSites (thanks to Chris). --- Diffs of the changes: (+2 -4) Index: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp diff -u llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.11 llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.12 --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.11 Fri Mar 12 00:15:08 2004 +++ llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Fri Mar 12 10:20:49 2004 @@ -91,10 +91,8 @@ } for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { - if (CallInst *CI = dyn_cast(*I)) - CallSites.insert(CallSite(CI)); - else if (InvokeInst *II = dyn_cast(*I)) - CallSites.insert(CallSite(II)); + CallSite CS = CallSite::get(*I); + if (CS.getInstruction()) CallSites.insert(CS); } if (PrintNoAlias || PrintMayAlias || PrintMustAlias || From criswell at cs.uiuc.edu Fri Mar 12 11:29:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Mar 12 11:29:01 2004 Subject: [llvm-commits] CVS: llvm-gcc/README.llvm README Message-ID: <200403121728.LAA31821@choi.cs.uiuc.edu> Changes in directory llvm-gcc: README.llvm added (r1.1) README updated: 1.1.1.1 -> 1.2 --- Log message: Adding big notice that we wrote some of the code and that it comes with no warranty. --- Diffs of the changes: (+53 -1) Index: llvm-gcc/README.llvm diff -c /dev/null llvm-gcc/README.llvm:1.1 *** /dev/null Fri Mar 12 11:28:54 2004 --- llvm-gcc/README.llvm Fri Mar 12 11:28:42 2004 *************** *** 0 **** --- 1,48 ---- + License Information + =================== + This is the LLVM GCC front end. The code is licensed to you under the GNU + General Public License and the GNU Lesser General Public License. + Please see the file COPYING and COPYING.LIB for more details. + + The software also has the following additional copyrights: + + Copyright (c) 2003, 2004 University of Illinois at Urbana-Champaign. + All rights reserved. + + Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.cs.uiuc.edu + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE + SOFTWARE. + + Copyright (c) 1994 + Hewlett-Packard Company + + Permission to use, copy, modify, distribute and sell this software + and its documentation for any purpose is hereby granted without fee, + provided that the above copyright notice appear in all copies and + that both that copyright notice and this permission notice appear + in supporting documentation. Hewlett-Packard Company makes no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied warranty. + + Copyright (c) 1996, 1997, 1998, 1999 + Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, distribute and sell this software + and its documentation for any purpose is hereby granted without fee, + provided that the above copyright notice appear in all copies and + that both that copyright notice and this permission notice appear + in supporting documentation. Silicon Graphics makes no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied warranty. Index: llvm-gcc/README diff -u llvm-gcc/README:1.1.1.1 llvm-gcc/README:1.2 --- llvm-gcc/README:1.1.1.1 Thu Jan 8 15:58:37 2004 +++ llvm-gcc/README Fri Mar 12 11:28:41 2004 @@ -1,4 +1,4 @@ -This directory contains the GNU Compiler Collection (GCC). +This directory contains the LLVM version of the GNU Compiler Collection (GCC). The GNU Compiler Collection is free software. See the file COPYING for copying permission. The manuals, and some of the runtime @@ -15,3 +15,7 @@ version of the manual is in the files gcc/doc/gcc.info*. See http://gcc.gnu.org/bugs.html for how to report bugs usefully. + +Additionally, please see the README.llvm file for more information about +copyrights and licensing. + From criswell at cs.uiuc.edu Fri Mar 12 11:30:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Mar 12 11:30:01 2004 Subject: [llvm-commits] CVS: llvm/LICENSE.TXT Message-ID: <200403121729.LAA28845@zion.cs.uiuc.edu> Changes in directory llvm: LICENSE.TXT updated: 1.11 -> 1.12 --- Log message: Updated copyright to year 2004. --- Diffs of the changes: (+2 -2) Index: llvm/LICENSE.TXT diff -u llvm/LICENSE.TXT:1.11 llvm/LICENSE.TXT:1.12 --- llvm/LICENSE.TXT:1.11 Fri Feb 27 12:02:06 2004 +++ llvm/LICENSE.TXT Fri Mar 12 11:29:20 2004 @@ -4,8 +4,8 @@ University of Illinois/NCSA Open Source License -Copyright (c) 2003, University of Illinois at Urbana-Champaign. All rights -reserved. +Copyright (c) 2003, 2004 University of Illinois at Urbana-Champaign. +All rights reserved. Developed by: From alkis at niobe.cs.uiuc.edu Fri Mar 12 12:02:08 2004 From: alkis at niobe.cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Mar 12 12:02:08 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200403121800.i2CI07Z06279@niobe.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.60 -> 1.61 --- Log message: Add support for a wider range of CMOV instructions. --- Diffs of the changes: (+54 -2) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.60 llvm/lib/Target/X86/X86InstrInfo.td:1.61 --- llvm/lib/Target/X86/X86InstrInfo.td:1.60 Mon Mar 8 21:37:54 2004 +++ llvm/lib/Target/X86/X86InstrInfo.td Fri Mar 12 11:59:56 2004 @@ -292,14 +292,66 @@ // let isTwoAddress = 1 in { -// Conditional moves. These are modelled as X = cmovXX Y, Z. Eventually -// register allocated to cmovXX XY, Z +// Conditional moves +def CMOVB16rr : I <"cmove", 0x42, MRMSrcReg>, TB, OpSize; // if , TB, OpSize; // if , TB; // if , TB; // if , TB, OpSize; // if >=u, R16 = R16 +def CMOVAE16rm: Im16<"cmove", 0x43, MRMSrcMem>, TB, OpSize; // if >=u, R16 = [mem16] +def CMOVAE32rr: I <"cmove", 0x43, MRMSrcReg>, TB; // if >=u, R32 = R32 +def CMOVAE32rm: Im32<"cmove", 0x43, MRMSrcMem>, TB; // if >=u, R32 = [mem32] + def CMOVE16rr : I <"cmove", 0x44, MRMSrcReg>, TB, OpSize; // if ==, R16 = R16 def CMOVE16rm : Im16<"cmove", 0x44, MRMSrcMem>, TB, OpSize; // if ==, R16 = [mem16] +def CMOVE32rr : I <"cmove", 0x44, MRMSrcReg>, TB; // if ==, R32 = R32 +def CMOVE32rm : Im32<"cmove", 0x44, MRMSrcMem>, TB; // if ==, R32 = [mem32] + +def CMOVNE16rr: I <"cmovne",0x45, MRMSrcReg>, TB, OpSize; // if !=, R16 = R16 +def CMOVNE16rm: Im16<"cmovne",0x45, MRMSrcMem>, TB, OpSize; // if !=, R16 = [mem16] def CMOVNE32rr: I <"cmovne",0x45, MRMSrcReg>, TB; // if !=, R32 = R32 def CMOVNE32rm: Im32<"cmovne",0x45, MRMSrcMem>, TB; // if !=, R32 = [mem32] + +def CMOVBE16rr: I <"cmovne",0x46, MRMSrcReg>, TB, OpSize; // if <=u, R16 = R16 +def CMOVBE16rm: Im16<"cmovne",0x46, MRMSrcMem>, TB, OpSize; // if <=u, R16 = [mem16] +def CMOVBE32rr: I <"cmovne",0x46, MRMSrcReg>, TB; // if <=u, R32 = R32 +def CMOVBE32rm: Im32<"cmovne",0x46, MRMSrcMem>, TB; // if <=u, R32 = [mem32] + +def CMOVA16rr : I <"cmove", 0x47, MRMSrcReg>, TB, OpSize; // if >u, R16 = R16 +def CMOVA16rm : Im16<"cmove", 0x47, MRMSrcMem>, TB, OpSize; // if >u, R16 = [mem16] +def CMOVA32rr : I <"cmove", 0x47, MRMSrcReg>, TB; // if >u, R32 = R32 +def CMOVA32rm : Im32<"cmove", 0x47, MRMSrcMem>, TB; // if >u, R32 = [mem32] + +def CMOVS16rr : I <"cmovs", 0x48, MRMSrcReg>, TB, OpSize; // if signed, R16 = R16 +def CMOVS16rm : Im16<"cmovs", 0x48, MRMSrcMem>, TB, OpSize; // if signed, R16 = [mem16] def CMOVS32rr : I <"cmovs", 0x48, MRMSrcReg>, TB; // if signed, R32 = R32 def CMOVS32rm : Im32<"cmovs", 0x48, MRMSrcMem>, TB; // if signed, R32 = [mem32] + +def CMOVNS16rr: I <"cmovs", 0x49, MRMSrcReg>, TB, OpSize; // if !signed, R16 = R16 +def CMOVNS16rm: Im16<"cmovs", 0x49, MRMSrcMem>, TB, OpSize; // if !signed, R16 = [mem16] +def CMOVNS32rr: I <"cmovs", 0x49, MRMSrcReg>, TB; // if !signed, R32 = R32 +def CMOVNS32rm: Im32<"cmovs", 0x49, MRMSrcMem>, TB; // if !signed, R32 = [mem32] + +def CMOVL16rr : I <"cmove", 0x4C, MRMSrcReg>, TB, OpSize; // if , TB, OpSize; // if , TB; // if , TB; // if , TB, OpSize; // if >=s, R16 = R16 +def CMOVGE16rm: Im16<"cmove", 0x4D, MRMSrcMem>, TB, OpSize; // if >=s, R16 = [mem16] +def CMOVGE32rr: I <"cmove", 0x4D, MRMSrcReg>, TB; // if >=s, R32 = R32 +def CMOVGE32rm: Im32<"cmove", 0x4D, MRMSrcMem>, TB; // if >=s, R32 = [mem32] + +def CMOVLE16rr: I <"cmovne",0x4E, MRMSrcReg>, TB, OpSize; // if <=s, R16 = R16 +def CMOVLE16rm: Im16<"cmovne",0x4E, MRMSrcMem>, TB, OpSize; // if <=s, R16 = [mem16] +def CMOVLE32rr: I <"cmovne",0x4E, MRMSrcReg>, TB; // if <=s, R32 = R32 +def CMOVLE32rm: Im32<"cmovne",0x4E, MRMSrcMem>, TB; // if <=s, R32 = [mem32] + +def CMOVG16rr : I <"cmove", 0x4F, MRMSrcReg>, TB, OpSize; // if >s, R16 = R16 +def CMOVG16rm : Im16<"cmove", 0x4F, MRMSrcMem>, TB, OpSize; // if >s, R16 = [mem16] +def CMOVG32rr : I <"cmove", 0x4F, MRMSrcReg>, TB; // if >s, R32 = R32 +def CMOVG32rm : Im32<"cmove", 0x4F, MRMSrcMem>, TB; // if >s, R32 = [mem32] // unary instructions def NEG8r : I <"neg", 0xF6, MRM3r>; // R8 = -R8 = 0-R8 From criswell at gally.cs.uiuc.edu Fri Mar 12 12:03:03 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 12:03:03 2004 Subject: [llvm-commits] CVS: llvm/docs/CFEBuildInstrs.html Message-ID: <200403121802.i2CI2Rr23749@gally.cs.uiuc.edu> Changes in directory llvm/docs: CFEBuildInstrs.html updated: 1.13 -> 1.14 --- Log message: Added a header indicating that the Linux and MacOS configure procedures are the same. Added LLVM copyright and warranty disclaimer information. --- Diffs of the changes: (+23 -1) Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.13 llvm/docs/CFEBuildInstrs.html:1.14 --- llvm/docs/CFEBuildInstrs.html:1.13 Wed Mar 10 13:08:52 2004 +++ llvm/docs/CFEBuildInstrs.html Fri Mar 12 12:02:17 2004 @@ -89,6 +89,8 @@

        Linux/x86: +
        +MacOS X/PowerPC:

        @@ -218,6 +220,26 @@
         

        +
        +Copyright (c) 2003, 2004 University of Illinois at Urbana-Champaign.
        +All rights reserved.
        +
        +Developed by:
        +
        +    LLVM Team
        +
        +    University of Illinois at Urbana-Champaign
        +
        +    http://llvm.cs.uiuc.edu
        +
        +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
        +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
        +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
        +SOFTWARE.
        +
         Copyright (c) 1994
         Hewlett-Packard Company
         
        @@ -250,7 +272,7 @@
           
        Brian Gaeke
        The LLVM Compiler Infrastructure
        - Last modified: $Date: 2004/03/10 19:08:52 $ + Last modified: $Date: 2004/03/12 18:02:17 $ From criswell at gally.cs.uiuc.edu Fri Mar 12 12:15:03 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 12:15:03 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.2/ Message-ID: <200403121814.i2CIE2N23931@gally.cs.uiuc.edu> Changes in directory llvm-www/releases/1.2: --- Log message: Directory /home/vadve/shared/InternalCVS/llvm-www/releases/1.2 added to the repository --- Diffs of the changes: (+0 -0) From criswell at gally.cs.uiuc.edu Fri Mar 12 12:16:02 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 12:16:02 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.2/LICENSE.TXT announcement.txt index.html Message-ID: <200403121815.i2CIFHd24056@gally.cs.uiuc.edu> Changes in directory llvm-www/releases/1.2: LICENSE.TXT added (r1.1) announcement.txt added (r1.1) index.html added (r1.1) --- Log message: Initial creation of the LLVM 1.2 release tree. LICENSE.TXT has been updated to reflect our work in 2004. The file announcement.txt has been updated somewhat, but more information needs to be gathered and replaced. --- Diffs of the changes: (+98 -0) Index: llvm-www/releases/1.2/LICENSE.TXT diff -c /dev/null llvm-www/releases/1.2/LICENSE.TXT:1.1 *** /dev/null Fri Mar 12 12:15:16 2004 --- llvm-www/releases/1.2/LICENSE.TXT Fri Mar 12 12:15:06 2004 *************** *** 0 **** --- 1,51 ---- + ============================================================================== + LLVM Release License + ============================================================================== + University of Illinois/NCSA + Open Source License + + Copyright (c) 2003, 2004 University of Illinois at Urbana-Champaign. + All rights reserved. + + Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.cs.uiuc.edu + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal with + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE + SOFTWARE. + + ============================================================================== + Copyrights and Licenses for Third Party Software Distributed with LLVM: + ============================================================================== + The LLVM software contains code written by third parties. Such software will + have its own individual LICENSE.TXT file in the directory in which it appears. + This file will describe the copyrights, license, and restrictions which apply + to that code. Index: llvm-www/releases/1.2/announcement.txt diff -c /dev/null llvm-www/releases/1.2/announcement.txt:1.1 *** /dev/null Fri Mar 12 12:15:16 2004 --- llvm-www/releases/1.2/announcement.txt Fri Mar 12 12:15:06 2004 *************** *** 0 **** --- 1,40 ---- + LLVM Compiler Infrastructure -- Release 1.2 + http://llvm.cs.uiuc.edu + + We are pleased to announce the release of version 1.2 of the LLVM Compiler + Infrastructure. If you are new to LLVM, please see "WHAT IS LLVM?" below. + If you are already familiar with LLVM, skip to "WHAT IS NEW IN LLVM 1.2?" + + WHAT IS LLVM? + + LLVM is a new infrastructure designed for compile-time, link-time, runtime, + and "idle-time" optimization of programs from arbitrary programming + languages. LLVM is written in C++ and has been developed over the past 3 + years at the University of Illinois. It currently supports compilation of + C and C++ programs using front-ends derived from GCC 3.4. New front-ends + are being written for Java bytecode and CAML. + + The LLVM infrastructure is publicly available under a non-restrictive open + source license. More information about LLVM and the contents of the + publicly released software is available at the LLVM Web site above. + + WHAT IS NEW IN LLVM 1.2? + + This release is primarily a bugfix release, dramatically improving the C/C++ + front-end and improving support for C++ in the LLVM core. This release also + includes a few new features, such as a simple profiler, support for Mac OS X, + better interoperability with external source bases, a new example language + front-end, and improvements in a few optimizations. This release also + features several substantial speedups and implementation of missing features. + + A full list of new features and bug-fixes are listed in the Release Notes: + http://llvm.cs.uiuc.edu/releases/1.2/docs/ReleaseNotes.html#whatsnew + + For an easier to read set of changes, please see the status updates: + http://mail.cs.uiuc.edu/pipermail/llvm-announce/2003-November/000003.html + http://mail.cs.uiuc.edu/pipermail/llvm-announce/2003-December/000004.html + + HOW DO I GET IT? + + Please see: http://llvm.cs.uiuc.edu/releases + Index: llvm-www/releases/1.2/index.html diff -c /dev/null llvm-www/releases/1.2/index.html:1.1 *** /dev/null Fri Mar 12 12:15:16 2004 --- llvm-www/releases/1.2/index.html Fri Mar 12 12:15:06 2004 *************** *** 0 **** --- 1,7 ---- + + + + + + + From criswell at gally.cs.uiuc.edu Fri Mar 12 12:21:01 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 12:21:01 2004 Subject: [llvm-commits] CVS: llvm/docs/FAQ.html Message-ID: <200403121820.i2CIKQS24188@gally.cs.uiuc.edu> Changes in directory llvm/docs: FAQ.html updated: 1.18 -> 1.19 --- Log message: Point to the new license (includes year 2004). Changed crtend.o to libcrtend.a. --- Diffs of the changes: (+4 -4) Index: llvm/docs/FAQ.html diff -u llvm/docs/FAQ.html:1.18 llvm/docs/FAQ.html:1.19 --- llvm/docs/FAQ.html:1.18 Tue Dec 23 16:22:10 2003 +++ llvm/docs/FAQ.html Fri Mar 12 12:20:15 2004 @@ -111,7 +111,7 @@

        Yes. The modified source distribution must retain the copyright notice and follow the three bulletted conditions listed in the LLVM license.

        +href="http://llvm.cs.uiuc.edu/releases/1.2/LICENSE.TXT">LLVM license.

        @@ -388,13 +388,13 @@

        When I compile code using the LLVM GCC front end, it complains that it cannot -find crtend.o. +find libcrtend.a.

        -In order to find crtend.o, you must have the directory in which it lives in +In order to find libcrtend.a, you must have the directory in which it lives in your LLVM_LIB_SEARCH_PATH environment variable. For the binary distribution of the LLVM GCC front end, this will be the full path of the bytecode-libs directory inside of the LLVM GCC distribution. @@ -456,7 +456,7 @@

        From lattner at cs.uiuc.edu Fri Mar 12 13:52:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 13:52:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Module.h Message-ID: <200403121951.NAA32253@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Module.h updated: 1.43 -> 1.44 --- Log message: Fix PR266: Make Module Not Inherit From Annotable --- Diffs of the changes: (+1 -1) Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.43 llvm/include/llvm/Module.h:1.44 --- llvm/include/llvm/Module.h:1.43 Mon Mar 8 00:15:33 2004 +++ llvm/include/llvm/Module.h Fri Mar 12 13:51:16 2004 @@ -43,7 +43,7 @@ static iplist &getList(Module *M); }; -struct Module : public Annotable { +struct Module { typedef iplist GlobalListType; typedef iplist FunctionListType; From criswell at gally.cs.uiuc.edu Fri Mar 12 14:32:01 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 14:32:01 2004 Subject: [llvm-commits] CVS: llvm/docs/GettingStarted.html Message-ID: <200403122031.i2CKVoE24592@gally.cs.uiuc.edu> Changes in directory llvm/docs: GettingStarted.html updated: 1.50 -> 1.51 --- Log message: Updated to LLVM 1.2. Added information on getting the LLVM GCC front end from CVS. Added new configure script options. Made other minor corrections and modifications. --- Diffs of the changes: (+38 -15) Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.50 llvm/docs/GettingStarted.html:1.51 --- llvm/docs/GettingStarted.html:1.50 Fri Feb 13 19:07:17 2004 +++ llvm/docs/GettingStarted.html Fri Mar 12 14:31:37 2004 @@ -96,8 +96,8 @@
        1. cd where-you-want-the-C-front-end-to-live
        2. gunzip --stdout cfrontend.platform.tar.gz | tar -xvf - -
        3. Sparc Only:
          - cd cfrontend/sparc
          +
        4. Sparc and MacOS X Only:
          + cd cfrontend/platform
          ./fixheaders
        @@ -106,7 +106,7 @@
      9. With the distributed files:
        1. cd where-you-want-llvm-to-live -
        2. gunzip --stdout llvm.tar.gz | tar -xvf - +
        3. gunzip --stdout llvm-version.tar.gz | tar -xvf -
        4. cd llvm
      10. @@ -382,23 +382,23 @@

        The files are as follows:

        -
        llvm-1.1.tar.gz +
        llvm-1.2.tar.gz
        This is the source code to the LLVM suite.

        -

        cfrontend-1.1.sparc-sun-solaris2.8.tar.gz +
        cfrontend-1.2.sparc-sun-solaris2.8.tar.gz
        This is the binary release of the GCC front end for Solaris/Sparc.

        -

        cfrontend-1.1.i686-redhat-linux-gnu.tar.gz +
        cfrontend-1.2.i686-redhat-linux-gnu.tar.gz
        This is the binary release of the GCC front end for Linux/x86.

        -

        cfrontend-1.1.i386-unknown-freebsd5.1.tar.gz +
        cfrontend-1.2.i386-unknown-freebsd5.1.tar.gz
        This is the binary release of the GCC front end for FreeBSD/x86.

        -

        cfrontend-1.1.powerpc-apple-darwin7.0.0.tar.gz +
        cfrontend-1.2.powerpc-apple-darwin7.0.0.tar.gz
        This is the binary release of the GCC front end for MacOS X/PPC.
        @@ -433,6 +433,10 @@
        • + Release 1.2: RELEASE_12 +
        • + +
        • Release 1.1: RELEASE_11
        • @@ -441,8 +445,14 @@
        -

        Note that the GCC front end is not included in the CVS repository. You -should have downloaded the binary distribution for your platform.

        +

        +If you would like to get the GCC front end source code, you can also get it +from the CVS repository: +

          +
        • cvs -z3 -d :pserver:anon at llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co + llvm-gcc +
        +

        @@ -469,7 +479,7 @@

        If you are using Solaris/Sparc or MacOS X/PPC, you will need to fix the header files:

        -

        cd cfrontend/sparc
        +

        cd cfrontend/platform
        ./fixheaders

        The binary versions of the GCC front end may not suit all of your needs. For @@ -527,7 +537,7 @@

        --with-llvmgccdir=LLVMGCCDIR
        - Path to the location where the LLVM C front end binaries and + Path to the location where the LLVM GCC front end binaries and associated libraries were installed. This must be specified as an absolute pathname.

        @@ -553,6 +563,19 @@ benchmarks. If directory is left unspecified, configure uses the default value /home/vadve/shared/benchmarks/speccpu2000/benchspec. +

        +

        --enable-spec95 +
        --enable-spec95=<directory> +
        + Enable the use of SPEC95 when testing LLVM. It is similar to the + --enable-spec2000 option. +

        +

        --enable-povray +
        --enable-povray=<directory> +
        + Enable the use of Povray as an external test. Versions of Povray written + in C should work. This option is similar to the --enable-spec2000 + option.

        To configure LLVM, follow these steps:

        @@ -751,7 +774,7 @@

        One useful source of information about the LLVM source base is the LLVM doxygen documentation, available at doxygen documentation available at http://llvm.cs.uiuc.edu/doxygen/. The following is a brief introduction to code layout:

        @@ -888,7 +911,7 @@

        The tools directory contains the executables built out of the libraries above, which form the main part of the user interface. You can always get help for a tool by typing tool_name --help. The -following is a brief introduction to the most important tools.

        +following is a brief introduction to the most important tools:

        analyze
        analyze is used to run a specific @@ -1147,7 +1170,7 @@ Chris Lattner
        The LLVM Compiler Infrastructure
        - Last modified: $Date: 2004/02/14 01:07:17 $ + Last modified: $Date: 2004/03/12 20:31:37 $ From criswell at gally.cs.uiuc.edu Fri Mar 12 14:43:01 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 14:43:01 2004 Subject: [llvm-commits] CVS: llvm/docs/HowToSubmitABug.html Message-ID: <200403122042.i2CKgSb24733@gally.cs.uiuc.edu> Changes in directory llvm/docs: HowToSubmitABug.html updated: 1.12 -> 1.13 --- Log message: Added minor information on C++. --- Diffs of the changes: (+6 -4) Index: llvm/docs/HowToSubmitABug.html diff -u llvm/docs/HowToSubmitABug.html:1.12 llvm/docs/HowToSubmitABug.html:1.13 --- llvm/docs/HowToSubmitABug.html:1.12 Fri Feb 13 19:07:17 2004 +++ llvm/docs/HowToSubmitABug.html Fri Mar 12 14:42:16 2004 @@ -96,12 +96,14 @@ gccas, or gccld), run the llvm-gcc command line as you were when the crash occurred, but add a -v option to the command line. The compiler will print out a -bunch of stuff, and should end with telling you that one of cc1, -gccas, or gccld crashed.

        +bunch of stuff, and should end with telling you that one of +cc1/cc1plus, gccas, or +gccld crashed.

          -
        • If cc1 crashed, you found a problem with the front-end. +
        • If cc1 or cc1plus crashed, you found a + problem with the front-end. Jump ahead to the section on front-end bugs.
        • If gccas crashed, you found a bug in one @@ -315,7 +317,7 @@ Chris Lattner
          The LLVM Compiler Infrastructure
          - Last modified: $Date: 2004/02/14 01:07:17 $ + Last modified: $Date: 2004/03/12 20:42:16 $ From gaeke at cs.uiuc.edu Fri Mar 12 15:14:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Mar 12 15:14:01 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Applications/siod/Makefile README-LLVM.txt slibu.c Message-ID: <200403122113.PAA27844@kain.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Applications/siod: Makefile updated: 1.3 -> 1.4 README-LLVM.txt updated: 1.1 -> 1.2 slibu.c updated: 1.3 -> 1.4 --- Log message: Make siod compile on solaris/sparc; update README --- Diffs of the changes: (+7 -22) Index: llvm/test/Programs/MultiSource/Applications/siod/Makefile diff -u llvm/test/Programs/MultiSource/Applications/siod/Makefile:1.3 llvm/test/Programs/MultiSource/Applications/siod/Makefile:1.4 --- llvm/test/Programs/MultiSource/Applications/siod/Makefile:1.3 Sun Feb 29 21:33:34 2004 +++ llvm/test/Programs/MultiSource/Applications/siod/Makefile Fri Mar 12 15:13:20 2004 @@ -2,7 +2,7 @@ LEVEL = ../../../../.. PROG = siod CPPFLAGS = -D__USE_MISC -D__USE_GNU -D__USE_SVID -D__USE_XOPEN_EXTENDED -D__USE_XOPEN -Dunix -LDFLAGS = -lm -ldl -lcrypt +LDFLAGS = -lm -ldl RUN_OPTIONS = -v1 $(BUILD_SRC_DIR)/test.scm Index: llvm/test/Programs/MultiSource/Applications/siod/README-LLVM.txt diff -u llvm/test/Programs/MultiSource/Applications/siod/README-LLVM.txt:1.1 llvm/test/Programs/MultiSource/Applications/siod/README-LLVM.txt:1.2 --- llvm/test/Programs/MultiSource/Applications/siod/README-LLVM.txt:1.1 Fri Oct 17 13:48:45 2003 +++ llvm/test/Programs/MultiSource/Applications/siod/README-LLVM.txt Fri Mar 12 15:13:24 2004 @@ -20,8 +20,11 @@ the thing to work, and gave it a small MultiSource-friendly Makefile. I also #ifdefed out the "Evaluation took ... seconds" message that gets printed out after every top-level REPL expression, in slib.c (search for -"ifdef STATISTICS"). I also renamed lchmod to l_chmod to allow it to -compile natively under Redhat 8... +"ifdef STATISTICS"). + +We also renamed lchmod to l_chmod, ripped out lchown() and lcrypt(), +and the reference to putpwent(). We provided a default definition for +PATH_MAX. WHAT ELSE NEEDS TO BE DONE? Index: llvm/test/Programs/MultiSource/Applications/siod/slibu.c diff -u llvm/test/Programs/MultiSource/Applications/siod/slibu.c:1.3 llvm/test/Programs/MultiSource/Applications/siod/slibu.c:1.4 --- llvm/test/Programs/MultiSource/Applications/siod/slibu.c:1.3 Tue Dec 16 18:09:51 2003 +++ llvm/test/Programs/MultiSource/Applications/siod/slibu.c Fri Mar 12 15:13:25 2004 @@ -55,17 +55,11 @@ #endif #if defined(sun) -#include #include #include #include #endif -#if defined(linux) && defined(PPC) -/* I know, this should be defined(NEED_CRYPT_H) */ -#include -#endif - #if defined(sgi) #include #endif @@ -104,7 +98,7 @@ static void init_slibu_version(void) {setvar(cintern("*slibu-version*"), - cintern("$Id: slibu.c,v 1.3 2003/12/17 00:09:51 gaeke Exp $"), + cintern("$Id: slibu.c,v 1.4 2004/03/12 21:13:25 gaeke Exp $"), NIL);} @@ -140,17 +134,6 @@ {return(flocons(getgid()));} #endif -#ifdef unix - -LISP lcrypt(LISP key,LISP salt) -{char *result; - if ((result = crypt(get_c_string(key),get_c_string(salt)))) - return(strcons(strlen(result),result)); - else - return(NIL);} - -#endif - #if defined(unix) || defined(WIN32) #if defined(WIN32) @@ -2143,7 +2126,6 @@ init_subr_0("getcwd",lgetcwd); #endif #ifdef unix - init_subr_2("crypt",lcrypt); init_subr_1("getpwuid",lgetpwuid); init_subr_1("getpwnam",lgetpwnam); init_subr_0("getpwent",lgetpwent); From criswell at gally.cs.uiuc.edu Fri Mar 12 15:20:01 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 15:20:01 2004 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200403122119.i2CLJIx24920@gally.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.53 -> 1.54 --- Log message: Fixed grammar typo. --- Diffs of the changes: (+2 -2) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.53 llvm/docs/LangRef.html:1.54 --- llvm/docs/LangRef.html:1.53 Thu Mar 11 23:50:16 2004 +++ llvm/docs/LangRef.html Fri Mar 12 15:19:06 2004 @@ -189,7 +189,7 @@
        • Unnamed values are represented as an unsigned numeric value with a '%' prefix. For example, %12, %2, %44.
      -

      LLVM requires the values start with a '%' sign for two reasons: +

      LLVM requires that values start with a '%' sign for two reasons: Compilers don't need to worry about name clashes with reserved words, and the set of reserved words may be expanded in the future without penalty. Additionally, unnamed identifiers allow a compiler to quickly @@ -2148,7 +2148,7 @@ Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/03/12 05:50:16 $ + Last modified: $Date: 2004/03/12 21:19:06 $ From gaeke at cs.uiuc.edu Fri Mar 12 15:20:11 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Mar 12 15:20:11 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Message-ID: <200403122119.PAA14341@seraph.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9TargetMachine.cpp updated: 1.105 -> 1.106 --- Log message: Make -print-machineinstrs show us the code both before and after reg. alloc. --- Diffs of the changes: (+4 -1) Index: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp diff -u llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.105 llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.106 --- llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.105 Thu Mar 4 13:16:23 2004 +++ llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Fri Mar 12 15:19:08 2004 @@ -161,10 +161,13 @@ if (!DisableSched) PM.add(createInstructionSchedulingWithSSAPass(*this)); + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(&std::cerr, "Before reg alloc:\n")); + PM.add(getRegisterAllocator(*this)); if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(&std::cerr)); + PM.add(createMachineFunctionPrinterPass(&std::cerr, "After reg alloc:\n")); PM.add(createPrologEpilogInsertionPass()); From criswell at gally.cs.uiuc.edu Fri Mar 12 15:30:01 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 15:30:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200403122129.i2CLTse25061@gally.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.144 -> 1.145 --- Log message: Fixed grammar typo. --- Diffs of the changes: (+2 -2) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.144 llvm/docs/ReleaseNotes.html:1.145 --- llvm/docs/ReleaseNotes.html:1.144 Wed Mar 10 18:50:54 2004 +++ llvm/docs/ReleaseNotes.html Fri Mar 12 15:29:42 2004 @@ -309,7 +309,7 @@

    • The gccld program does not link objects/archives in the order specified on the command line.
    • The lower-invoke pass does not mark -values live across a setjmp as volatile. This missing feature only effects +values live across a setjmp as volatile. This missing feature only affects targets whose setjmp/longjmp libraries do not save and restore the entire register file.
    @@ -626,7 +626,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/11 00:50:54 $ + Last modified: $Date: 2004/03/12 21:29:42 $ From gaeke at cs.uiuc.edu Fri Mar 12 15:32:03 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Mar 12 15:32:03 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Applications/siod/test.scm Message-ID: <200403122131.PAA28009@kain.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Applications/siod: test.scm updated: 1.2 -> 1.3 --- Log message: Actually print out the Fibonacci number. --- Diffs of the changes: (+14 -7) Index: llvm/test/Programs/MultiSource/Applications/siod/test.scm diff -u llvm/test/Programs/MultiSource/Applications/siod/test.scm:1.2 llvm/test/Programs/MultiSource/Applications/siod/test.scm:1.3 --- llvm/test/Programs/MultiSource/Applications/siod/test.scm:1.2 Sun Feb 29 21:33:34 2004 +++ llvm/test/Programs/MultiSource/Applications/siod/test.scm Fri Mar 12 15:31:02 2004 @@ -63,16 +63,23 @@ (newline)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Fibonacci test + +(define (fib n) + (if (< n 2) + n + (+ (fib (- n 1)) (fib (- n 2))))) + +(define (fib-test) + (display "the 33rd Fibonacci number is ") + (display (fib 33)) + (newline)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Run some simple tests (print-countdown 10) (print-signum -42) (print-signum 0) (print-signum 42) (simple-proplist-test) - -(define (fib n) - (if (< n 2) n - (+ (fib (- n 1)) (fib (- n 2))) -)) - -(fib 33) +(fib-test) From gaeke at cs.uiuc.edu Fri Mar 12 15:38:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Mar 12 15:38:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CodeGeneratorBug.cpp Message-ID: <200403122137.PAA14571@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CodeGeneratorBug.cpp updated: 1.37 -> 1.38 --- Log message: Revise comment and error message for the Bug 38 situation. Also, make it print out the name of the function being used. --- Diffs of the changes: (+5 -4) Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.37 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.38 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.37 Fri Feb 20 00:12:58 2004 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Fri Mar 12 15:37:46 2004 @@ -167,10 +167,11 @@ // actually use the resolved function Inst->replaceUsesOfWith(F, castResolver); } else { - // FIXME: need to take care of cases where a function is used that - // is not an instruction, e.g. global variable initializer... - std::cerr << - "UNSUPPORTED: External function used as global initializer!\n"; + // FIXME: need to take care of cases where a function is used by + // something other than an instruction; e.g., global variable + // initializers and constant expressions. + std::cerr << "UNSUPPORTED: Non-instruction is using an external " + << "function, " << F->getName() << "().\n"; abort(); } } From lattner at cs.uiuc.edu Fri Mar 12 16:39:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 16:39:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/BasicAA/gcsetest.ll Message-ID: <200403122238.QAA20580@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/BasicAA: gcsetest.ll updated: 1.5 -> 1.6 --- Log message: new testcase --- Diffs of the changes: (+10 -0) Index: llvm/test/Regression/Transforms/BasicAA/gcsetest.ll diff -u llvm/test/Regression/Transforms/BasicAA/gcsetest.ll:1.5 llvm/test/Regression/Transforms/BasicAA/gcsetest.ll:1.6 --- llvm/test/Regression/Transforms/BasicAA/gcsetest.ll:1.5 Tue Sep 16 10:26:24 2003 +++ llvm/test/Regression/Transforms/BasicAA/gcsetest.ll Fri Mar 12 16:38:31 2004 @@ -34,3 +34,13 @@ ret int %X } +declare void %external() + +int %test3() { + %X = alloca int + store int 7, int* %X + call void %external() + %V = load int* %X + ret int %V +} + From lattner at cs.uiuc.edu Fri Mar 12 16:40:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 16:40:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200403122239.QAA20590@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: BasicAliasAnalysis.cpp updated: 1.30 -> 1.31 --- Log message: Implement mod/ref analysis for a trivial case where locals don't escape. This comes up when you have a local array on the stack and you never pass the address of elements around. --- Diffs of the changes: (+52 -0) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.30 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.31 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.30 Sun Feb 29 20:44:44 2004 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Fri Mar 12 16:39:00 2004 @@ -47,6 +47,8 @@ AliasResult alias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size); + ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); + /// pointsToConstantMemory - Chase pointers until we find a (constant /// global) or not. bool pointsToConstantMemory(const Value *P); @@ -137,6 +139,56 @@ if (const GlobalVariable *GV = dyn_cast(V)) return GV->isConstant(); return false; +} + +static bool AddressMightEscape(const Value *V) { + for (Value::use_const_iterator UI = V->use_begin(), E = V->use_end(); + UI != E; ++UI) { + const Instruction *I = cast(*UI); + switch (I->getOpcode()) { + case Instruction::Load: break; + case Instruction::Store: + if (I->getOperand(0) == V) + return true; // Escapes if the pointer is stored. + break; + case Instruction::GetElementPtr: + if (AddressMightEscape(I)) return true; + break; + case Instruction::Cast: + if (!isa(I->getType())) + return true; + if (AddressMightEscape(I)) return true; + break; + case Instruction::PHI: + if (AddressMightEscape(I)) return true; + break; + default: + return true; + } + } + return false; +} + +// getModRefInfo - Check to see if the specified callsite can clobber the +// specified memory object. Since we only look at local properties of this +// function, we really can't say much about this query. We do, however, use +// simple "address taken" analysis on local objects. +// +AliasAnalysis::ModRefResult +BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) { + if (!isa(P) && !isa(P)) + if (const AllocationInst *AI = + dyn_cast(getUnderlyingObject(P))) { + // Okay, the pointer is to a stack allocated object. If we can prove that + // the pointer never "escapes", then we know the call cannot clobber it, + // because it simply can't get its address. + if (!AddressMightEscape(AI)) + return NoModRef; + } + + // If P points to a constant memory location, the call definitely could not + // modify the memory location. + return pointsToConstantMemory(P) ? Ref : ModRef; } // alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such From criswell at gally.cs.uiuc.edu Fri Mar 12 16:46:01 2004 From: criswell at gally.cs.uiuc.edu (John Criswell) Date: Fri Mar 12 16:46:01 2004 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/analyze.html extract.html gccas.html gccld.html llc.html llvm-dis.html llvm-prof.html opt.html Message-ID: <200403122245.i2CMjkd25495@gally.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: analyze.html updated: 1.9 -> 1.10 extract.html updated: 1.6 -> 1.7 gccas.html updated: 1.6 -> 1.7 gccld.html updated: 1.9 -> 1.10 llc.html updated: 1.13 -> 1.14 llvm-dis.html updated: 1.6 -> 1.7 llvm-prof.html updated: 1.4 -> 1.5 opt.html updated: 1.9 -> 1.10 --- Log message: Performed some updates on the new options to these command line tools. --- Diffs of the changes: (+73 -20) Index: llvm/docs/CommandGuide/analyze.html diff -u llvm/docs/CommandGuide/analyze.html:1.9 llvm/docs/CommandGuide/analyze.html:1.10 --- llvm/docs/CommandGuide/analyze.html:1.9 Mon Jan 26 15:26:54 2004 +++ llvm/docs/CommandGuide/analyze.html Fri Mar 12 16:45:35 2004 @@ -35,17 +35,6 @@ Print a summary of command line options.

    -

  • -stats -
    - Print statistics. -

    - -

  • -time-passes -
    - Record the amount of time needed for each pass and print it to standard - error. -

    -

  • -q
    Quiet mode. With this option, analysis pass names are not printed. @@ -62,6 +51,27 @@ for running the passes made available by plugin. Use 'analyze -load <plugin> -help' to see the new list of available analysis passes. +

    + +

  • -dsa-track-integers +
    + Track integers as potential pointers. +

    + +

  • -profile-info-file <filename> +
    + Specify the name of the file loaded by the -profile-loader option. +

    + +

  • -stats +
    + Print statistics. +

    + +

  • -time-passes +
    + Record the amount of time needed for each pass and print it to standard + error.

    Index: llvm/docs/CommandGuide/extract.html diff -u llvm/docs/CommandGuide/extract.html:1.6 llvm/docs/CommandGuide/extract.html:1.7 --- llvm/docs/CommandGuide/extract.html:1.6 Wed Feb 18 10:55:29 2004 +++ llvm/docs/CommandGuide/extract.html Fri Mar 12 16:45:35 2004 @@ -61,6 +61,17 @@ Specify the output filename. If filename is "-" (the default), then extract sends its output to standard output.

    + +

  • -stats +
    + Print statistics. +

    + +

  • -time-passes +
    + Record the amount of time needed for each pass and print it to standard + error. +

    Index: llvm/docs/CommandGuide/gccas.html diff -u llvm/docs/CommandGuide/gccas.html:1.6 llvm/docs/CommandGuide/gccas.html:1.7 --- llvm/docs/CommandGuide/gccas.html:1.6 Thu Oct 16 15:05:48 2003 +++ llvm/docs/CommandGuide/gccas.html Fri Mar 12 16:45:35 2004 @@ -44,6 +44,17 @@ Disable the inlining pass. By default, it is enabled.

    +

  • -disable-opt +
    + Disable all assemble-time optimization passes. +

    + +

  • -enable-correct-eh-support +
    + Instruct the -lowerinvoke pass to insert code for correct exception handling + support. This is expensive and is by default omitted for efficiency. +

    +

  • -stats
    Print statistics. Index: llvm/docs/CommandGuide/gccld.html diff -u llvm/docs/CommandGuide/gccld.html:1.9 llvm/docs/CommandGuide/gccld.html:1.10 --- llvm/docs/CommandGuide/gccld.html:1.9 Mon Jan 26 15:26:54 2004 +++ llvm/docs/CommandGuide/gccld.html Fri Mar 12 16:45:35 2004 @@ -114,7 +114,12 @@
  • -disable-opt
    - Disable all link-time optimization passes. + Disable all link-time optimization passes. +

    + +

  • -disable-inlining +
    + Do not run the inliner pass.

  • -L=<directory> Index: llvm/docs/CommandGuide/llc.html diff -u llvm/docs/CommandGuide/llc.html:1.13 llvm/docs/CommandGuide/llc.html:1.14 --- llvm/docs/CommandGuide/llc.html:1.13 Sat Mar 6 16:38:29 2004 +++ llvm/docs/CommandGuide/llc.html Fri Mar 12 16:45:35 2004 @@ -93,7 +93,7 @@
    x86
    IA-32 (Pentium and above)
    -
    sparc
    +
    sparcv9
    SPARC V9
    c
    @@ -104,6 +104,12 @@
  • -o <filename>
    Specify the output filename. +

    + +

  • -enable-correct-eh-support +
    + Instruct the -lowerinvoke pass to insert code for correct exception handling + support. This is expensive and is by default omitted for efficiency.

  • -help Index: llvm/docs/CommandGuide/llvm-dis.html diff -u llvm/docs/CommandGuide/llvm-dis.html:1.6 llvm/docs/CommandGuide/llvm-dis.html:1.7 --- llvm/docs/CommandGuide/llvm-dis.html:1.6 Tue Oct 7 15:17:24 2003 +++ llvm/docs/CommandGuide/llvm-dis.html Fri Mar 12 16:45:35 2004 @@ -53,11 +53,6 @@ readable format. This is the default behavior.

    -

  • -c -
    - Instruct llvm-dis to generate C source code. -

    -

  • -f
    Force overwrite. Normally, llvm-dis will refuse to overwrite Index: llvm/docs/CommandGuide/llvm-prof.html diff -u llvm/docs/CommandGuide/llvm-prof.html:1.4 llvm/docs/CommandGuide/llvm-prof.html:1.5 --- llvm/docs/CommandGuide/llvm-prof.html:1.4 Tue Feb 10 12:04:24 2004 +++ llvm/docs/CommandGuide/llvm-prof.html Fri Mar 12 16:45:35 2004 @@ -30,7 +30,7 @@
  • --annotated-llvm or -A
    In addition to the normal report printed, print out the code for the - program, annotated we execution frequency information. This can be + program, annotated with execution frequency information. This can be particularly useful when trying to visualize how frequently basic blocks are executed. This is most useful with basic block profiling information or better.

    @@ -40,12 +40,17 @@ Using this option enables the --annotated-llvm option, but it prints the entire module, instead of just the most commonly executed functions.

    + +

  • -time-passes
    + + Record the amount of time needed for each pass and print it to standard + error.

    EXIT STATUS

    llvm-prof returns 1 if it cannot load the bytecode file or the profile -information, otherwise it exits with zero. +information. Otherwise, it exits with zero.
    Maintained by the LLVM Team. Index: llvm/docs/CommandGuide/opt.html diff -u llvm/docs/CommandGuide/opt.html:1.9 llvm/docs/CommandGuide/opt.html:1.10 --- llvm/docs/CommandGuide/opt.html:1.9 Mon Jan 26 15:26:54 2004 +++ llvm/docs/CommandGuide/opt.html Fri Mar 12 16:45:35 2004 @@ -53,6 +53,16 @@ Specify the output filename.

    +

  • -dsa-track-integers +
    + Track integers as potential pointers. +

    + +

  • -profile-info-file <filename> +
    + Specify the name of the file loaded by the -profile-loader option. +

    +

  • -stats
    Print statistics. From lattner at cs.uiuc.edu Fri Mar 12 17:14:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 17:14:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200403122313.RAA22535@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: BasicAliasAnalysis.cpp updated: 1.31 -> 1.32 --- Log message: Fix a couple of minor problems. Because PHI nodes can use themselves, this could cause infinite loops. Also, getUnderlyingObject can return null --- Diffs of the changes: (+1 -4) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.31 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.32 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.31 Fri Mar 12 16:39:00 2004 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Fri Mar 12 17:12:55 2004 @@ -159,9 +159,6 @@ return true; if (AddressMightEscape(I)) return true; break; - case Instruction::PHI: - if (AddressMightEscape(I)) return true; - break; default: return true; } @@ -178,7 +175,7 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) { if (!isa(P) && !isa(P)) if (const AllocationInst *AI = - dyn_cast(getUnderlyingObject(P))) { + dyn_cast_or_null(getUnderlyingObject(P))) { // Okay, the pointer is to a stack allocated object. If we can prove that // the pointer never "escapes", then we know the call cannot clobber it, // because it simply can't get its address. From lattner at cs.uiuc.edu Fri Mar 12 17:54:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 17:54:00 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/sub.ll Message-ID: <200403122353.RAA28331@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: sub.ll updated: 1.14 -> 1.15 --- Log message: new testcases --- Diffs of the changes: (+13 -1) Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.14 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.15 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.14 Fri Feb 27 23:26:06 2004 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Fri Mar 12 17:52:51 2004 @@ -1,7 +1,7 @@ ; This test makes sure that these instructions are properly eliminated. ; -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep sub | not grep -v 'sub int %Cok, %Bok' +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v 'sub int %Cok, %Bok' | not grep sub implementation @@ -73,4 +73,16 @@ %C = sub ubyte %A, %B %cD = setne ubyte %C, 0 ; == setne A, B ret bool %cD +} + +int %test12(int %A) { + %B = shr int %A, ubyte 31 + %C = sub int 0, %B ; == ushr A, 31 + ret int %C +} + +uint %test13(uint %A) { + %B = shr uint %A, ubyte 31 + %C = sub uint 0, %B ; == sar A, 31 + ret uint %C } From lattner at cs.uiuc.edu Fri Mar 12 17:54:34 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 17:54:34 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200403122353.RAA28340@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.169 -> 1.170 --- Log message: Implement InstCombine/sub.ll:test12 & test13 --- Diffs of the changes: (+36 -0) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.169 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.170 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.169 Thu Mar 11 23:52:32 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Mar 12 17:53:13 2004 @@ -212,6 +212,18 @@ } } +// getUnsignedIntegralType - Given an signed integral type, return the unsigned +// version of it that has the same size. +static const Type *getUnsignedIntegralType(const Type *Ty) { + switch (Ty->getPrimitiveID()) { + default: assert(0 && "Invalid signed integer type!"); abort(); + case Type::SByteTyID: return Type::UByteTy; + case Type::ShortTyID: return Type::UShortTy; + case Type::IntTyID: return Type::UIntTy; + case Type::LongTyID: return Type::ULongTy; + } +} + // getPromotedType - Return the specified type promoted as it would be to pass // though a va_arg area... static const Type *getPromotedType(const Type *Ty) { @@ -558,6 +570,30 @@ BinaryOperator::getNotArgument(cast(Op1)), ConstantExpr::get(Instruction::Add, C, ConstantInt::get(I.getType(), 1))); + // -((uint)X >> 31) -> ((int)X >> 31) + // -((int)X >> 31) -> ((uint)X >> 31) + if (C->isNullValue()) + if (ShiftInst *SI = dyn_cast(Op1)) + if (SI->getOpcode() == Instruction::Shr) + if (ConstantUInt *CU = dyn_cast(SI->getOperand(1))) { + const Type *NewTy; + if (C->getType()->isSigned()) + NewTy = getUnsignedIntegralType(C->getType()); + else + NewTy = getSignedIntegralType(C->getType()); + // Check to see if we are shifting out everything but the sign bit. + if (CU->getValue() == C->getType()->getPrimitiveSize()*8-1) { + // Ok, the transformation is safe. Insert a cast of the incoming + // value, then the new shift, then the new cast. + Instruction *FirstCast = new CastInst(SI->getOperand(0), NewTy, + SI->getOperand(0)->getName()); + Value *InV = InsertNewInstBefore(FirstCast, I); + Instruction *NewShift = new ShiftInst(Instruction::Shr, FirstCast, + CU, SI->getName()); + InV = InsertNewInstBefore(NewShift, I); + return new CastInst(NewShift, I.getType()); + } + } } if (BinaryOperator *Op1I = dyn_cast(Op1)) From lattner at cs.uiuc.edu Fri Mar 12 18:12:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:12:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/sub.ll Message-ID: <200403130011.SAA30717@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: sub.ll updated: 1.15 -> 1.16 --- Log message: Oh right, casts can interfere. Test this too --- Diffs of the changes: (+8 -0) Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.15 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.16 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.15 Fri Mar 12 17:52:51 2004 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Fri Mar 12 18:11:38 2004 @@ -86,3 +86,11 @@ %C = sub uint 0, %B ; == sar A, 31 ret uint %C } + +int %test14(uint %A) { + %B = shr uint %A, ubyte 31 + %C = cast uint %B to int + %D = sub int 0, %C + ret int %D +} + From lattner at cs.uiuc.edu Fri Mar 12 18:13:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:13:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200403130011.SAA30726@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.170 -> 1.171 --- Log message: Implement sub.ll:test14 --- Diffs of the changes: (+29 -8) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.170 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.171 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.170 Fri Mar 12 17:53:13 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Mar 12 18:11:49 2004 @@ -549,6 +549,21 @@ return Ty == Type::BoolTy ? 1 : Ty->getPrimitiveSize()*8; } +/// RemoveNoopCast - Strip off nonconverting casts from the value. +/// +static Value *RemoveNoopCast(Value *V) { + if (CastInst *CI = dyn_cast(V)) { + const Type *CTy = CI->getType(); + const Type *OpTy = CI->getOperand(0)->getType(); + if (CTy->isInteger() && OpTy->isInteger()) { + if (CTy->getPrimitiveSize() == OpTy->getPrimitiveSize()) + return RemoveNoopCast(CI->getOperand(0)); + } else if (isa(CTy) && isa(OpTy)) + return RemoveNoopCast(CI->getOperand(0)); + } + return V; +} + Instruction *InstCombiner::visitSub(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -572,17 +587,18 @@ ConstantInt::get(I.getType(), 1))); // -((uint)X >> 31) -> ((int)X >> 31) // -((int)X >> 31) -> ((uint)X >> 31) - if (C->isNullValue()) - if (ShiftInst *SI = dyn_cast(Op1)) + if (C->isNullValue()) { + Value *NoopCastedRHS = RemoveNoopCast(Op1); + if (ShiftInst *SI = dyn_cast(NoopCastedRHS)) if (SI->getOpcode() == Instruction::Shr) if (ConstantUInt *CU = dyn_cast(SI->getOperand(1))) { const Type *NewTy; - if (C->getType()->isSigned()) - NewTy = getUnsignedIntegralType(C->getType()); + if (SI->getType()->isSigned()) + NewTy = getUnsignedIntegralType(SI->getType()); else - NewTy = getSignedIntegralType(C->getType()); + NewTy = getSignedIntegralType(SI->getType()); // Check to see if we are shifting out everything but the sign bit. - if (CU->getValue() == C->getType()->getPrimitiveSize()*8-1) { + if (CU->getValue() == SI->getType()->getPrimitiveSize()*8-1) { // Ok, the transformation is safe. Insert a cast of the incoming // value, then the new shift, then the new cast. Instruction *FirstCast = new CastInst(SI->getOperand(0), NewTy, @@ -590,10 +606,15 @@ Value *InV = InsertNewInstBefore(FirstCast, I); Instruction *NewShift = new ShiftInst(Instruction::Shr, FirstCast, CU, SI->getName()); - InV = InsertNewInstBefore(NewShift, I); - return new CastInst(NewShift, I.getType()); + if (NewShift->getType() == I.getType()) + return NewShift; + else { + InV = InsertNewInstBefore(NewShift, I); + return new CastInst(NewShift, I.getType()); + } } } + } } if (BinaryOperator *Op1I = dyn_cast(Op1)) From lattner at cs.uiuc.edu Fri Mar 12 18:24:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:24:00 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.h Message-ID: <200403130023.SAA31615@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.h updated: 1.18 -> 1.19 --- Log message: Rename the intrinsic enum values for llvm.va_* from Intrinsic::va_* to Intrinsic::va*. This avoid conflicting with macros in the stdlib.h file. --- Diffs of the changes: (+3 -3) Index: llvm/include/llvm/Intrinsics.h diff -u llvm/include/llvm/Intrinsics.h:1.18 llvm/include/llvm/Intrinsics.h:1.19 --- llvm/include/llvm/Intrinsics.h:1.18 Fri Feb 13 20:47:12 2004 +++ llvm/include/llvm/Intrinsics.h Fri Mar 12 18:23:14 2004 @@ -27,9 +27,9 @@ not_intrinsic = 0, // Must be zero // Varargs handling intrinsics... - va_start, // Used to implement the va_start macro in C - va_end, // Used to implement the va_end macro in C - va_copy, // Used to implement the va_copy macro in C + vastart, // Used to implement the va_start macro in C + vaend, // Used to implement the va_end macro in C + vacopy, // Used to implement the va_copy macro in C // Code generator intrinsics... returnaddress, // Yields the return address of a dynamic call frame From lattner at cs.uiuc.edu Fri Mar 12 18:24:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:24:10 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200403130023.SAA31868@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.100 -> 1.101 --- Log message: Rename the intrinsic enum values for llvm.va_* from Intrinsic::va_* to Intrinsic::va*. This avoid conflicting with macros in the stdlib.h file. --- Diffs of the changes: (+3 -5) Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.100 llvm/lib/Analysis/DataStructure/Local.cpp:1.101 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.100 Fri Mar 5 14:04:40 2004 +++ llvm/lib/Analysis/DataStructure/Local.cpp Fri Mar 12 18:23:25 2004 @@ -494,16 +494,14 @@ if (Function *F = dyn_cast(Callee)) if (F->isExternal()) switch (F->getIntrinsicID()) { - case Intrinsic::va_start: + case Intrinsic::vastart: getValueDest(*CS.getInstruction()).getNode()->setAllocaNodeMarker(); return; - case Intrinsic::va_copy: + case Intrinsic::vacopy: getValueDest(*CS.getInstruction()). mergeWith(getValueDest(**(CS.arg_begin()))); return; - // FIXME: the #undef is a quick fix for compilation on Sparc -#undef va_end - case Intrinsic::va_end: + case Intrinsic::vaend: return; // noop case Intrinsic::memmove: case Intrinsic::memcpy: { From lattner at cs.uiuc.edu Fri Mar 12 18:24:19 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:24:19 2004 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Message-ID: <200403130023.SAA31876@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: Execution.cpp updated: 1.124 -> 1.125 --- Log message: Rename the intrinsic enum values for llvm.va_* from Intrinsic::va_* to Intrinsic::va*. This avoid conflicting with macros in the stdlib.h file. --- Diffs of the changes: (+3 -3) Index: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.124 llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.125 --- llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.124 Wed Feb 25 17:01:48 2004 +++ llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Fri Mar 12 18:23:29 2004 @@ -774,16 +774,16 @@ switch (F->getIntrinsicID()) { case Intrinsic::not_intrinsic: break; - case Intrinsic::va_start: { // va_start + case Intrinsic::vastart: { // va_start GenericValue ArgIndex; ArgIndex.UIntPairVal.first = ECStack.size() - 1; ArgIndex.UIntPairVal.second = 0; SetValue(CS.getInstruction(), ArgIndex, SF); return; } - case Intrinsic::va_end: // va_end is a noop for the interpreter + case Intrinsic::vaend: // va_end is a noop for the interpreter return; - case Intrinsic::va_copy: // va_copy: dest = src + case Intrinsic::vacopy: // va_copy: dest = src SetValue(CS.getInstruction(), getOperandValue(*CS.arg_begin(), SF), SF); return; default: From lattner at cs.uiuc.edu Fri Mar 12 18:24:28 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:24:28 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp Message-ID: <200403130023.SAA32088@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: Writer.cpp updated: 1.166 -> 1.167 --- Log message: Rename the intrinsic enum values for llvm.va_* from Intrinsic::va_* to Intrinsic::va*. This avoid conflicting with macros in the stdlib.h file. --- Diffs of the changes: (+6 -6) Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.166 llvm/lib/Target/CBackend/Writer.cpp:1.167 --- llvm/lib/Target/CBackend/Writer.cpp:1.166 Thu Mar 11 23:52:14 2004 +++ llvm/lib/Target/CBackend/Writer.cpp Fri Mar 12 18:23:42 2004 @@ -1205,9 +1205,9 @@ if (Function *F = CI->getCalledFunction()) switch (F->getIntrinsicID()) { case Intrinsic::not_intrinsic: - case Intrinsic::va_start: - case Intrinsic::va_copy: - case Intrinsic::va_end: + case Intrinsic::vastart: + case Intrinsic::vacopy: + case Intrinsic::vaend: case Intrinsic::returnaddress: case Intrinsic::frameaddress: case Intrinsic::setjmp: @@ -1234,7 +1234,7 @@ if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) { switch (ID) { default: assert(0 && "Unknown LLVM intrinsic!"); - case Intrinsic::va_start: + case Intrinsic::vastart: Out << "0; "; Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; @@ -1248,12 +1248,12 @@ writeOperand(&I.getParent()->getParent()->aback()); Out << ")"; return; - case Intrinsic::va_end: + case Intrinsic::vaend: Out << "va_end(*(va_list*)&"; writeOperand(I.getOperand(1)); Out << ")"; return; - case Intrinsic::va_copy: + case Intrinsic::vacopy: Out << "0;"; Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", "; Out << "*(va_list*)&"; From lattner at cs.uiuc.edu Fri Mar 12 18:24:37 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:24:37 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9InstrSelection.cpp Message-ID: <200403130023.SAA32095@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9InstrSelection.cpp updated: 1.136 -> 1.137 --- Log message: Rename the intrinsic enum values for llvm.va_* from Intrinsic::va_* to Intrinsic::va*. This avoid conflicting with macros in the stdlib.h file. --- Diffs of the changes: (+3 -3) Index: llvm/lib/Target/SparcV9/SparcV9InstrSelection.cpp diff -u llvm/lib/Target/SparcV9/SparcV9InstrSelection.cpp:1.136 llvm/lib/Target/SparcV9/SparcV9InstrSelection.cpp:1.137 --- llvm/lib/Target/SparcV9/SparcV9InstrSelection.cpp:1.136 Sun Feb 29 13:12:48 2004 +++ llvm/lib/Target/SparcV9/SparcV9InstrSelection.cpp Fri Mar 12 18:23:46 2004 @@ -1398,7 +1398,7 @@ switch (iid) { default: assert(0 && "Unknown intrinsic function call should have been lowered!"); - case Intrinsic::va_start: { + case Intrinsic::vastart: { // Get the address of the first incoming vararg argument on the stack bool ignore; Function* func = cast(callInstr.getParent()->getParent()); @@ -1412,10 +1412,10 @@ return true; } - case Intrinsic::va_end: + case Intrinsic::vaend: return true; // no-op on SparcV9 - case Intrinsic::va_copy: + case Intrinsic::vacopy: // Simple copy of current va_list (arg1) to new va_list (result) mvec.push_back(BuildMI(V9::ORr, 3). addMReg(target.getRegInfo().getZeroRegNum()). From lattner at cs.uiuc.edu Fri Mar 12 18:24:46 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:24:46 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp Message-ID: <200403130023.SAA32104@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/InstrSelection: InstrSelection.cpp updated: 1.69 -> 1.70 --- Log message: Rename the intrinsic enum values for llvm.va_* from Intrinsic::va_* to Intrinsic::va*. This avoid conflicting with macros in the stdlib.h file. --- Diffs of the changes: (+3 -6) Index: llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp diff -u llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp:1.69 llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp:1.70 --- llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp:1.69 Wed Feb 11 20:27:09 2004 +++ llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp Fri Mar 12 18:23:48 2004 @@ -126,13 +126,10 @@ if (CallInst *CI = dyn_cast(I++)) if (Function *F = CI->getCalledFunction()) switch (F->getIntrinsicID()) { -#undef va_start -#undef va_copy -#undef va_end case Intrinsic::not_intrinsic: - case Intrinsic::va_start: - case Intrinsic::va_copy: - case Intrinsic::va_end: + case Intrinsic::vastart: + case Intrinsic::vacopy: + case Intrinsic::vaend: // We directly implement these intrinsics. Note that this knowledge // is incestuously entangled with the code in // SparcInstrSelection.cpp and must be updated when it is updated. From lattner at cs.uiuc.edu Fri Mar 12 18:25:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:25:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Verifier.cpp Message-ID: <200403130024.SAA32286@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.65 -> 1.66 Verifier.cpp updated: 1.85 -> 1.86 --- Log message: Rename the intrinsic enum values for llvm.va_* from Intrinsic::va_* to Intrinsic::va*. This avoid conflicting with macros in the stdlib.h file. --- Diffs of the changes: (+6 -6) Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.65 llvm/lib/VMCore/Function.cpp:1.66 --- llvm/lib/VMCore/Function.cpp:1.65 Fri Feb 13 20:47:16 2004 +++ llvm/lib/VMCore/Function.cpp Fri Mar 12 18:24:00 2004 @@ -234,9 +234,9 @@ if (getName() == "llvm.siglongjmp") return Intrinsic::siglongjmp; break; case 'v': - if (getName() == "llvm.va_copy") return Intrinsic::va_copy; - if (getName() == "llvm.va_end") return Intrinsic::va_end; - if (getName() == "llvm.va_start") return Intrinsic::va_start; + if (getName() == "llvm.va_copy") return Intrinsic::vacopy; + if (getName() == "llvm.va_end") return Intrinsic::vaend; + if (getName() == "llvm.va_start") return Intrinsic::vastart; break; } // The "llvm." namespace is reserved! Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.85 llvm/lib/VMCore/Verifier.cpp:1.86 --- llvm/lib/VMCore/Verifier.cpp:1.85 Thu Mar 11 23:54:31 2004 +++ llvm/lib/VMCore/Verifier.cpp Fri Mar 12 18:24:00 2004 @@ -548,14 +548,14 @@ // FIXME: this should check the return type of each intrinsic as well, also // arguments! switch (ID) { - case Intrinsic::va_start: + case Intrinsic::vastart: Assert1(CI.getParent()->getParent()->getFunctionType()->isVarArg(), "llvm.va_start intrinsic may only occur in function with variable" " args!", &CI); NumArgs = 0; break; - case Intrinsic::va_end: NumArgs = 1; break; - case Intrinsic::va_copy: NumArgs = 1; break; + case Intrinsic::vaend: NumArgs = 1; break; + case Intrinsic::vacopy: NumArgs = 1; break; case Intrinsic::returnaddress: case Intrinsic::frameaddress: From lattner at cs.uiuc.edu Fri Mar 12 18:25:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:25:11 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200403130024.SAA32113@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.192 -> 1.193 --- Log message: Rename the intrinsic enum values for llvm.va_* from Intrinsic::va_* to Intrinsic::va*. This avoid conflicting with macros in the stdlib.h file. --- Diffs of the changes: (+3 -3) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.192 llvm/lib/Target/X86/InstSelectSimple.cpp:1.193 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.192 Sun Mar 7 19:58:35 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Fri Mar 12 18:23:50 2004 @@ -1242,9 +1242,9 @@ if (Function *F = CI->getCalledFunction()) switch (F->getIntrinsicID()) { case Intrinsic::not_intrinsic: - case Intrinsic::va_start: - case Intrinsic::va_copy: - case Intrinsic::va_end: + case Intrinsic::vastart: + case Intrinsic::vacopy: + case Intrinsic::vaend: case Intrinsic::returnaddress: case Intrinsic::frameaddress: case Intrinsic::memcpy: From lattner at cs.uiuc.edu Fri Mar 12 18:26:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 18:26:00 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200403130025.SAA00819@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.193 -> 1.194 --- Log message: It helps if I save the file. :) --- Diffs of the changes: (+3 -3) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.193 llvm/lib/Target/X86/InstSelectSimple.cpp:1.194 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.193 Fri Mar 12 18:23:50 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Fri Mar 12 18:24:52 2004 @@ -1267,18 +1267,18 @@ void ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { unsigned TmpReg1, TmpReg2; switch (ID) { - case Intrinsic::va_start: + case Intrinsic::vastart: // Get the address of the first vararg value... TmpReg1 = getReg(CI); addFrameReference(BuildMI(BB, X86::LEA32r, 5, TmpReg1), VarArgsFrameIndex); return; - case Intrinsic::va_copy: + case Intrinsic::vacopy: TmpReg1 = getReg(CI); TmpReg2 = getReg(CI.getOperand(1)); BuildMI(BB, X86::MOV32rr, 1, TmpReg1).addReg(TmpReg2); return; - case Intrinsic::va_end: return; // Noop on X86 + case Intrinsic::vaend: return; // Noop on X86 case Intrinsic::returnaddress: case Intrinsic::frameaddress: From lattner at cs.uiuc.edu Fri Mar 12 19:15:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Mar 12 19:15:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200403130114.TAA04669@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.171 -> 1.172 --- Log message: Fix a tiny bug that caused an incorrect assertion failure poolallocating boxed-sim. --- Diffs of the changes: (+6 -4) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.171 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.172 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.171 Tue Mar 9 13:37:06 2004 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Fri Mar 12 19:14:23 2004 @@ -1970,10 +1970,12 @@ DSNodeHandle &Entry = NodeMap[N1]; if (Entry.getNode()) { // Termination of recursion! - assert(!StrictChecking || - (Entry.getNode() == N2 && - Entry.getOffset() == (NH2.getOffset()-NH1.getOffset())) && - "Inconsistent mapping detected!"); + if (StrictChecking) { + assert(Entry.getNode() == N2 && "Inconsistent mapping detected!"); + assert((Entry.getOffset() == (NH2.getOffset()-NH1.getOffset()) || + Entry.getNode()->isNodeCompletelyFolded()) && + "Inconsistent mapping detected!"); + } return; } From gaeke at cs.uiuc.edu Sat Mar 13 13:13:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Sat Mar 13 13:13:02 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Message-ID: <200403131912.NAA09658@zion.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: UnpackTraceFunction.cpp updated: 1.44 -> 1.45 --- Log message: Fix some debug output. Start fixing up prolog + epilog. --- Diffs of the changes: (+30 -3) Index: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp diff -u reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.44 reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.45 --- reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.44 Thu Mar 11 03:33:04 2004 +++ reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Sat Mar 13 13:11:58 2004 @@ -36,12 +36,35 @@ TargetMachine *TM; public: SparcV9ReoptInfo (TargetMachine *_TM) : TM (_TM) {} + void rewritePrologEpilog (MachineFunction &MF); void insertCopyMachineInstrs (AllocInfo &Source, AllocInfo &Target, MachineBasicBlock &B, const Type *Ty); void insertBranchMachineInstrs (uint64_t Target, MachineBasicBlock &B); const MachineInstr *containsReturnInstr (MachineBasicBlock &B); }; +void SparcV9ReoptInfo::rewritePrologEpilog (MachineFunction &MF) { + bool foundSave = false, foundRestore = false; + int stackOffset = 0; + for (MachineFunction::iterator fi = MF.begin (), fe = MF.end (); fi != fe; ++fi) { + for (MachineBasicBlock::iterator bi = fi->begin (), be = fi->end (); bi != be; ++bi) { + MachineInstr &mi = *bi; + if (mi.getOpcode () == V9::SAVEi) { + mi.setOpcode (V9::ADDi); + foundSave = true; + for (unsigned i = 0, e = mi.getNumOperands (); i != e; ++i) { + if (mi.getOperand (i).isImmediate ()) { + stackOffset = mi.getOperand (i).getImmedValue (); + } + } + } + } + } + assert (foundSave && "Didn't find SAVE instruction in prolog"); + assert (stackOffset != 0 && "Didn't find frame size in SAVE instruction"); + assert (foundRestore && "Didn't find RESTORE instruction in prolog"); +} + /// Insert the appropriate machine instruction(s) that copies the value in /// Source to the location specified by Target, at the beginning of B. /// @@ -334,7 +357,8 @@ if (MF.getFunction () != TF->TraceFn) return false; - DEBUG(std::cerr << "In UnpackTraceFunction for " << MF.getFunction()->getName() << "()\n"); + DEBUG(std::cerr << "In UnpackTraceFunction for " + << MF.getFunction()->getName() << "()\n"); Function *TraceF = TF->TraceFn, *MatrixF = TF->MatrixFn; LiveVariableSet &Si = TF->LiveInSet, &So = TF->LiveOutSet; @@ -348,7 +372,9 @@ // Insert copies from each live-in variable's reg. in the matrix fn. // to its reg. in the trace. Value *V = *SI; - DEBUG(std::cerr << "UnpackTraceFunction: Looking for alloc state for value: \n" << *V << "\n"); + DEBUG(std::cerr + << "UnpackTraceFunction: Looking for alloc state for value: \n" + << *V << "\n"); AllocInfo Source = getValueAllocStateFromModule (MatrixF, V); DEBUG(std::cerr << "UnpackTraceFunction: Source = " << Source << "\n"); AllocInfo Target = @@ -361,9 +387,10 @@ DEBUG(std::cerr << "UnpackTraceFunction: Inserting copy MachineInstrs:\n"); for (std::vector::iterator i = EntryCopies.begin (), e = EntryCopies.end (); i != e; ++i) { - DEBUG(std::cerr << "UnpackTraceFunction: " << *i); + DEBUG(std::cerr << "UnpackTraceFunction: " << *i << "\n"); SRI.insertCopyMachineInstrs (i->Src, i->Targ, *i->Blk, i->Ty); } + DEBUG(std::cerr << "-------------\n\n"); // Modify EXIT MachineBasicBlocks of MF for (MachineFunction::iterator I = MF.begin (), E = MF.end (); I != E; ++I) { From lattner at cs.uiuc.edu Sat Mar 13 13:37:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 13:37:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CrashDebugger.cpp ExtractFunction.cpp Message-ID: <200403131936.NAA03389@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CrashDebugger.cpp updated: 1.32 -> 1.33 ExtractFunction.cpp updated: 1.23 -> 1.24 --- Log message: Fix the "infinite looping unless you disable adce" bug Also remove an option to disable adce :) --- Diffs of the changes: (+1 -7) Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.32 llvm/tools/bugpoint/CrashDebugger.cpp:1.33 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.32 Wed Feb 18 17:59:11 2004 +++ llvm/tools/bugpoint/CrashDebugger.cpp Sat Mar 13 13:35:54 2004 @@ -330,7 +330,7 @@ // FIXME: This should use the list reducer to converge faster by deleting // larger chunks of instructions at a time! - unsigned Simplification = 4; + unsigned Simplification = 2; do { --Simplification; std::cout << "\n*** Attempting to reduce testcase by deleting instruc" Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.23 llvm/tools/bugpoint/ExtractFunction.cpp:1.24 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.23 Wed Feb 18 15:50:26 2004 +++ llvm/tools/bugpoint/ExtractFunction.cpp Sat Mar 13 13:35:54 2004 @@ -33,9 +33,6 @@ namespace { cl::opt - NoADCE("disable-adce", - cl::desc("Do not use the -adce pass to reduce testcases")); - cl::opt NoDCE ("disable-dce", cl::desc("Do not use the -dce pass to reduce testcases")); cl::opt @@ -78,9 +75,6 @@ // Make sure that the appropriate target data is always used... Passes.add(new TargetData("bugpoint", Result)); - if (Simplification > 2 && !NoADCE) - Passes.add(createAggressiveDCEPass()); // Remove dead code... - //Passes.add(createInstructionCombiningPass()); if (Simplification > 1 && !NoDCE) Passes.add(createDeadCodeEliminationPass()); if (Simplification && !DisableSimplifyCFG) From lattner at cs.uiuc.edu Sat Mar 13 13:37:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 13:37:10 2004 Subject: [llvm-commits] CVS: llvm/docs/CommandGuide/bugpoint.html Message-ID: <200403131936.NAA05776@zion.cs.uiuc.edu> Changes in directory llvm/docs/CommandGuide: bugpoint.html updated: 1.23 -> 1.24 --- Log message: Option no more --- Diffs of the changes: (+1 -1) Index: llvm/docs/CommandGuide/bugpoint.html diff -u llvm/docs/CommandGuide/bugpoint.html:1.23 llvm/docs/CommandGuide/bugpoint.html:1.24 --- llvm/docs/CommandGuide/bugpoint.html:1.23 Wed Feb 18 17:30:21 2004 +++ llvm/docs/CommandGuide/bugpoint.html Sat Mar 13 13:36:30 2004 @@ -184,7 +184,7 @@ Assume a non-zero exit code or core dump from the test program is a failure. Defaults to true.

    -

  • -disable-{adce,dce,simplifycfg}
    +
  • -disable-{dce,simplifycfg}
    Do not run the specified passes to clean up and reduce the size of the test program. By default, bugpoint uses these passes internally when attempting to reduce test programs. If you're trying to find From lattner at cs.uiuc.edu Sat Mar 13 15:39:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 15:39:02 2004 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200403132138.PAA06949@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.94 -> 1.95 --- Log message: Turn on argument promotion in gccas. This can give us substantially better code in cases where the file has lots of static functions or anon namespaces. --- Diffs of the changes: (+1 -0) Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.94 llvm/tools/gccas/gccas.cpp:1.95 --- llvm/tools/gccas/gccas.cpp:1.94 Wed Feb 25 15:35:02 2004 +++ llvm/tools/gccas/gccas.cpp Sat Mar 13 15:38:35 2004 @@ -79,6 +79,7 @@ if (!DisableInline) addPass(PM, createFunctionInliningPass()); // Inline small functions + addPass(PM, createArgumentPromotionPass()); // Scalarize uninlined fn args addPass(PM, createRaisePointerReferencesPass());// Recover type information addPass(PM, createTailDuplicationPass()); // Simplify cfg by copying code From lattner at cs.uiuc.edu Sat Mar 13 16:02:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 16:02:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopSimplify.cpp Message-ID: <200403132201.QAA11167@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopSimplify.cpp updated: 1.34 -> 1.35 --- Log message: This little patch speeds up the loop used to update the dominator set analysis. On the testcase from GCC PR12440, which has a LOT of loops (1392 of which require preheaders to be inserted), this speeds up the loopsimplify pass from 1.931s to 0.1875s. The loop in question goes from 1.65s -> 0.0097s, which isn't bad. All of these times are a debug build. This adds a dependency on DominatorTree analysis that was not there before, but we always had dominatortree available anyway, because LICM requires both loop simplify and DT, so this doesn't add any extra analysis in practice. --- Diffs of the changes: (+18 -17) Index: llvm/lib/Transforms/Scalar/LoopSimplify.cpp diff -u llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.34 llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.35 --- llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.34 Thu Feb 5 17:20:59 2004 +++ llvm/lib/Transforms/Scalar/LoopSimplify.cpp Sat Mar 13 16:01:26 2004 @@ -56,6 +56,7 @@ // We need loop information to identify the loops... AU.addRequired(); AU.addRequired(); + AU.addRequired(); AU.addPreserved(); AU.addPreserved(); @@ -279,6 +280,9 @@ ChangeExitBlock(*ParentLoops, Header, NewBB); DominatorSet &DS = getAnalysis(); // Update dominator info + DominatorTree &DT = getAnalysis(); + DominatorTree::Node *HeaderDTNode = DT.getNode(Header); + { // The blocks that dominate NewBB are the blocks that dominate Header, // minus Header, plus NewBB. @@ -288,10 +292,20 @@ 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); + for (DominatorTree::Node::iterator I = HeaderDTNode->begin(), + E = HeaderDTNode->end(); I != E; ++I) + DS.addDominator((*I)->getBlock(), NewBB); + } + + { // Update the dominator tree information. + // The immediate dominator of the preheader is the immediate dominator of + // the old header. + // + DominatorTree::Node *PHNode = + DT.createNewNode(NewBB, HeaderDTNode->getIDom()); + + // Change the header node so that PNHode is the new immediate dominator + DT.changeImmediateDominator(HeaderDTNode, PHNode); } // Update immediate dominator information if we have it... @@ -303,19 +317,6 @@ ID->setImmediateDominator(Header, NewBB); } - // Update DominatorTree information if it is active. - if (DominatorTree *DT = getAnalysisToUpdate()) { - // The immediate dominator of the preheader is the immediate dominator of - // the old header. - // - DominatorTree::Node *HeaderNode = DT->getNode(Header); - DominatorTree::Node *PHNode = DT->createNewNode(NewBB, - HeaderNode->getIDom()); - - // Change the header node so that PNHode is the new immediate dominator - DT->changeImmediateDominator(HeaderNode, PHNode); - } - // Update dominance frontier information... if (DominanceFrontier *DF = getAnalysisToUpdate()) { // The DF(NewBB) is just (DF(Header)-Header), because NewBB dominates From lattner at cs.uiuc.edu Sat Mar 13 17:16:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 17:16:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/InlineSimple.cpp Message-ID: <200403132315.RAA15620@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: InlineSimple.cpp updated: 1.59 -> 1.60 --- Log message: This change makes two big adjustments. * Be a lot more accurate about what the effects will be when inlining a call to a function when an argument is an alloca. * Dramatically reduce the penalty for inlining a call in a large function. This heuristic made it almost impossible to inline a function into a large function, no matter how small the callee is. --- Diffs of the changes: (+49 -11) Index: llvm/lib/Transforms/IPO/InlineSimple.cpp diff -u llvm/lib/Transforms/IPO/InlineSimple.cpp:1.59 llvm/lib/Transforms/IPO/InlineSimple.cpp:1.60 --- llvm/lib/Transforms/IPO/InlineSimple.cpp:1.59 Fri Nov 21 15:57:29 2003 +++ llvm/lib/Transforms/IPO/InlineSimple.cpp Sat Mar 13 17:15:45 2004 @@ -14,11 +14,20 @@ #include "Inliner.h" #include "llvm/Instructions.h" #include "llvm/Function.h" +#include "llvm/Type.h" #include "llvm/Support/CallSite.h" #include "llvm/Transforms/IPO.h" using namespace llvm; namespace { + struct ArgInfo { + unsigned ConstantWeight; + unsigned AllocaWeight; + + ArgInfo(unsigned CWeight, unsigned AWeight) + : ConstantWeight(CWeight), AllocaWeight(AWeight) {} + }; + // FunctionInfo - For each function, calculate the size of it in blocks and // instructions. struct FunctionInfo { @@ -26,11 +35,11 @@ // used to estimate the code size cost of inlining it. unsigned NumInsts, NumBlocks; - // ConstantArgumentWeights - Each formal argument of the function is - // inspected to see if it is used in any contexts where making it a constant + // ArgumentWeights - Each formal argument of the function is inspected to + // see if it is used in any contexts where making it a constant or alloca // would reduce the code size. If so, we add some value to the argument // entry here. - std::vector ConstantArgumentWeights; + std::vector ArgumentWeights; FunctionInfo() : NumInsts(0), NumBlocks(0) {} }; @@ -88,6 +97,33 @@ return Reduction; } +// CountCodeReductionForAlloca - Figure out an approximation of how much smaller +// the function will be if it is inlined into a context where an argument +// becomes an alloca. +// +static unsigned CountCodeReductionForAlloca(Value *V) { + if (!isa(V->getType())) return 0; // Not a pointer + unsigned Reduction = 0; + for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){ + Instruction *I = cast(*UI); + if (isa(I) || isa(I)) + Reduction += 10; + else if (GetElementPtrInst *GEP = dyn_cast(I)) { + // If the GEP has variable indices, we won't be able to do much with it. + for (Instruction::op_iterator I = GEP->op_begin()+1, E = GEP->op_end(); + I != E; ++I) + if (!isa(*I)) return 0; + Reduction += CountCodeReductionForAlloca(GEP)+15; + } else { + // If there is some other strange instruction, we're not going to be able + // to do much if we inline this. + return 0; + } + } + + return Reduction; +} + // getInlineCost - The heuristic used to determine if we should inline the // function call or not. // @@ -131,11 +167,12 @@ // Check out all of the arguments to the function, figuring out how much // code can be eliminated if one of the arguments is a constant. - std::vector &ArgWeights = CalleeFI.ConstantArgumentWeights; + std::vector &ArgWeights = CalleeFI.ArgumentWeights; for (Function::aiterator I = Callee->abegin(), E = Callee->aend(); I != E; ++I) - ArgWeights.push_back(CountCodeReductionForConstant(I)); + ArgWeights.push_back(ArgInfo(CountCodeReductionForConstant(I), + CountCodeReductionForAlloca(I))); } @@ -161,15 +198,16 @@ // significant future optimization possibilities (like scalar promotion, and // scalarization), so encourage the inlining of the function. // - else if (isa(I)) - InlineCost -= 60; + else if (AllocaInst *AI = dyn_cast(I)) { + if (ArgNo < CalleeFI.ArgumentWeights.size()) + InlineCost -= CalleeFI.ArgumentWeights[ArgNo].AllocaWeight; // If this is a constant being passed into the function, use the argument // weights calculated for the callee to determine how much will be folded // away with this information. - else if (isa(I) || isa(I)) { - if (ArgNo < CalleeFI.ConstantArgumentWeights.size()) - InlineCost -= CalleeFI.ConstantArgumentWeights[ArgNo]; + } else if (isa(I) || isa(I)) { + if (ArgNo < CalleeFI.ArgumentWeights.size()) + InlineCost -= CalleeFI.ArgumentWeights[ArgNo].ConstantWeight; } } @@ -178,7 +216,7 @@ // Don't inline into something too big, which would make it bigger. Here, we // count each basic block as a single unit. - InlineCost += Caller->size()*2; + InlineCost += Caller->size()/20; // Look at the size of the callee. Each basic block counts as 20 units, and From lattner at cs.uiuc.edu Sat Mar 13 17:54:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 17:54:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2004-03-13-InstCombineInfLoop.ll Message-ID: <200403132353.RAA17242@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2004-03-13-InstCombineInfLoop.ll added (r1.1) --- Log message: New testcase, distilled from povray I think. --- Diffs of the changes: (+13 -0) Index: llvm/test/Regression/Transforms/InstCombine/2004-03-13-InstCombineInfLoop.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/2004-03-13-InstCombineInfLoop.ll:1.1 *** /dev/null Sat Mar 13 17:53:14 2004 --- llvm/test/Regression/Transforms/InstCombine/2004-03-13-InstCombineInfLoop.ll Sat Mar 13 17:53:04 2004 *************** *** 0 **** --- 1,13 ---- + ; This testcase caused the combiner to go into an infinite loop, moving the + ; cast back and forth, changing the seteq to operate on int vs uint and back. + + ; RUN: llvm-as < %s | opt -instcombine -disable-output + + bool %test(uint %A, int %B) { + %C = sub uint 0, %A + %Cc = cast uint %C to int + %D = sub int 0, %B + %E = seteq int %Cc, %D + ret bool %E + } + From lattner at cs.uiuc.edu Sat Mar 13 17:55:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 17:55:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200403132354.RAA17282@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.171 -> 1.172 --- Log message: Add some debugging output Fix InstCombine/2004-03-13-InstCombineInfLoop.ll which caused an infinite loop compiling (I think) povray. --- Diffs of the changes: (+8 -1) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.171 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.172 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.171 Fri Mar 12 18:11:49 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat Mar 13 17:54:27 2004 @@ -33,6 +33,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "instcombine" #include "llvm/Transforms/Scalar.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" @@ -46,6 +47,7 @@ #include "llvm/Support/InstIterator.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/CallSite.h" +#include "Support/Debug.h" #include "Support/Statistic.h" #include using namespace llvm; @@ -1551,7 +1553,7 @@ if (CastInst *CI = dyn_cast(Op0)) { Value *CastOp0 = CI->getOperand(0); if (CastOp0->getType()->isLosslesslyConvertibleTo(CI->getType()) && - !isa(Op1) && + (isa(Op1) || isa(Op1)) && (I.getOpcode() == Instruction::SetEQ || I.getOpcode() == Instruction::SetNE)) { // We keep moving the cast from the left operand over to the right @@ -2543,6 +2545,9 @@ ++NumCombined; // Should we replace the old instruction with a new one? if (Result != I) { + DEBUG(std::cerr << "IC: Old = " << *I + << " New = " << *Result); + // Instructions can end up on the worklist more than once. Make sure // we do not process an instruction that has been deleted. removeFromWorkList(I); @@ -2561,6 +2566,8 @@ // Erase the old instruction. InstParent->getInstList().erase(I); } else { + DEBUG(std::cerr << "IC: MOD = " << *I); + BasicBlock::iterator II = I; // If the instruction was modified, it's possible that it is now dead. From lattner at cs.uiuc.edu Sat Mar 13 20:04:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:04:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200403140203.UAA18123@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.145 -> 1.146 --- Log message: Document stuff that is known to be broken --- Diffs of the changes: (+27 -5) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.145 llvm/docs/ReleaseNotes.html:1.146 --- llvm/docs/ReleaseNotes.html:1.145 Fri Mar 12 15:29:42 2004 +++ llvm/docs/ReleaseNotes.html Sat Mar 13 20:03:02 2004 @@ -18,6 +18,7 @@
  • Installation Instructions
  • Known Problems
      +
    • Experimental features included with this release
    • Known problems with the LLVM Core
    • Known problems with the C Front-end
    • Known problems with the C++ Front-end @@ -276,11 +277,32 @@ - - + + + +
      + +

      +The following components of this LLVM release are either untested, known to be +broken or unreliable, or are in early development. These components should not +be relied on, and bugs should not be filed against them, but they may be useful +to some people. In particular, if you would like to work on one of these +components, please contact us on the llvmdev list. +

      + +
        +
      • The following passes are incomplete or buggy: -pgmdep, -memdep, + -ipmodref, -sortstructs, -swapstructs, -cee
      • +
      • The -pre pass is incomplete (there are cases it doesn't handle that + it should) and not thoroughly tested.
      • +
      • The llvm-ar tool is incomplete and probably buggy.
      • +
      • The llvm-db tool is in a very early stage of development.
      • +
      + +
      @@ -626,7 +648,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/03/12 21:29:42 $ + Last modified: $Date: 2004/03/14 02:03:02 $ From lattner at cs.uiuc.edu Sat Mar 13 20:14:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:14:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Local.h Message-ID: <200403140213.UAA21861@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Local.h updated: 1.14 -> 1.15 --- Log message: Move DemoteRegToStack prototype out of DemoteRegToStack.h to this file. --- Diffs of the changes: (+9 -0) Index: llvm/include/llvm/Transforms/Utils/Local.h diff -u llvm/include/llvm/Transforms/Utils/Local.h:1.14 llvm/include/llvm/Transforms/Utils/Local.h:1.15 --- llvm/include/llvm/Transforms/Utils/Local.h:1.14 Mon Jan 12 12:25:56 2004 +++ llvm/include/llvm/Transforms/Utils/Local.h Sat Mar 13 20:13:07 2004 @@ -21,6 +21,7 @@ class Pass; class PHINode; +class AllocaInst; //===----------------------------------------------------------------------===// // Local constant propagation... @@ -86,6 +87,14 @@ /// WARNING: The entry node of a method may not be simplified. /// bool SimplifyCFG(BasicBlock *BB); + +/// DemoteRegToStack - This function takes a virtual register computed by an +/// Instruction& X and replaces it with a slot in the stack frame, allocated via +/// alloca. This allows the CFG to be changed around without fear of +/// invalidating the SSA information for the value. It returns the pointer to +/// the alloca inserted to create a stack slot for X. +/// +AllocaInst *DemoteRegToStack(Instruction &X); } // End llvm namespace From lattner at cs.uiuc.edu Sat Mar 13 20:14:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:14:11 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/DemoteRegToStack.cpp Message-ID: <200403140213.UAA22391@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: DemoteRegToStack.cpp updated: 1.8 -> 1.9 --- Log message: DemoteRegToStack got moved from DemoteRegToStack.h to Local.h --- Diffs of the changes: (+1 -1) Index: llvm/lib/Transforms/Utils/DemoteRegToStack.cpp diff -u llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.8 llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.9 --- llvm/lib/Transforms/Utils/DemoteRegToStack.cpp:1.8 Fri Jan 9 00:12:19 2004 +++ llvm/lib/Transforms/Utils/DemoteRegToStack.cpp Sat Mar 13 20:13:34 2004 @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Utils/DemoteRegToStack.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Function.h" #include "llvm/iMemory.h" #include "llvm/iPHINode.h" From lattner at cs.uiuc.edu Sat Mar 13 20:14:21 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:14:21 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/LowerSetJmp.cpp Parallelize.cpp Message-ID: <200403140213.UAA22401@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: LowerSetJmp.cpp updated: 1.17 -> 1.18 Parallelize.cpp updated: 1.13 -> 1.14 --- Log message: DemoteRegToStack got moved from DemoteRegToStack.h to Local.h --- Diffs of the changes: (+5 -5) Index: llvm/lib/Transforms/IPO/LowerSetJmp.cpp diff -u llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.17 llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.18 --- llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.17 Sun Feb 8 15:43:47 2004 +++ llvm/lib/Transforms/IPO/LowerSetJmp.cpp Sat Mar 13 20:13:38 2004 @@ -42,7 +42,7 @@ #include "llvm/Pass.h" #include "llvm/Support/CFG.h" #include "llvm/Support/InstVisitor.h" -#include "llvm/Transforms/Utils/DemoteRegToStack.h" +#include "llvm/Transforms/Utils/Local.h" #include "Support/DepthFirstIterator.h" #include "Support/Statistic.h" #include "Support/StringExtras.h" Index: llvm/lib/Transforms/IPO/Parallelize.cpp diff -u llvm/lib/Transforms/IPO/Parallelize.cpp:1.13 llvm/lib/Transforms/IPO/Parallelize.cpp:1.14 --- llvm/lib/Transforms/IPO/Parallelize.cpp:1.13 Sun Feb 29 17:09:10 2004 +++ llvm/lib/Transforms/IPO/Parallelize.cpp Sat Mar 13 20:13:38 2004 @@ -38,14 +38,14 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Utils/DemoteRegToStack.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" #include "llvm/Analysis/PgmDependenceGraph.h" #include "llvm/Analysis/DataStructure.h" #include "llvm/Analysis/DSGraph.h" -#include "llvm/Module.h" -#include "llvm/Instructions.h" -#include "llvm/DerivedTypes.h" #include "llvm/Support/InstVisitor.h" +#include "llvm/Transforms/Utils/Local.h" #include "Support/Statistic.h" #include "Support/STLExtras.h" #include "Support/hash_set" From lattner at cs.uiuc.edu Sat Mar 13 20:15:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:15:02 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/DemoteRegToStack.h Message-ID: <200403140214.UAA22413@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: DemoteRegToStack.h (r1.4) removed --- Log message: Remove dead file --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Sat Mar 13 20:33:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:33:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/LoopExtractor.cpp Message-ID: <200403140232.UAA24710@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: LoopExtractor.cpp (r1.3) removed --- Log message: Move to the IPO library. Utils shouldn't contain passes. --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Sat Mar 13 20:33:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:33:11 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/LoopExtractor.cpp Message-ID: <200403140232.UAA24717@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: LoopExtractor.cpp added (r1.1) --- Log message: Move to the IPO library. Utils shouldn't contain passes. --- Diffs of the changes: (+68 -0) Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp diff -c /dev/null llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.1 *** /dev/null Sat Mar 13 20:32:37 2004 --- llvm/lib/Transforms/IPO/LoopExtractor.cpp Sat Mar 13 20:32:27 2004 *************** *** 0 **** --- 1,68 ---- + //===- LoopExtractor.cpp - Extract each loop into a new function ----------===// + // + // A pass wrapper around the ExtractLoop() scalar transformation to extract each + // top-level loop into its own new function. If the loop is the ONLY loop in a + // given function, it is not touched. This is a pass most useful for debugging + // via bugpoint. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Module.h" + #include "llvm/Pass.h" + #include "llvm/Analysis/LoopInfo.h" + #include "llvm/Transforms/Scalar.h" + #include "llvm/Transforms/Utils/FunctionUtils.h" + #include + using namespace llvm; + + namespace { + + // FIXME: PassManager should allow Module passes to require FunctionPasses + struct LoopExtractor : public FunctionPass { + + public: + LoopExtractor() {} + virtual bool run(Module &M); + virtual bool runOnFunction(Function &F); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + + }; + + RegisterOpt + X("loop-extract", "Extract loops into new functions"); + + bool LoopExtractor::run(Module &M) { + bool Changed = false; + for (Module::iterator i = M.begin(), e = M.end(); i != e; ++i) + Changed |= runOnFunction(*i); + return Changed; + } + + bool LoopExtractor::runOnFunction(Function &F) { + std::cerr << F.getName() << "\n"; + + LoopInfo &LI = getAnalysis(); + + // We don't want to keep extracting the only loop of a function into a new one + if (LI.begin() == LI.end() || LI.begin() + 1 == LI.end()) + return false; + + bool Changed = false; + + // Try to move each loop out of the code into separate function + for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; ++i) + Changed |= (ExtractLoop(*i) != 0); + + return Changed; + } + + } // End anonymous namespace + + /// createLoopExtractorPass + /// + FunctionPass* llvm::createLoopExtractorPass() { + return new LoopExtractor(); + } From lattner at cs.uiuc.edu Sat Mar 13 20:35:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:35:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/LoopExtractor.cpp Message-ID: <200403140234.UAA24737@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: LoopExtractor.cpp updated: 1.1 -> 1.2 --- Log message: Indent anon namespace properly, add copyright block --- Diffs of the changes: (+19 -18) Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp diff -u llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.1 llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.2 --- llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.1 Sat Mar 13 20:32:27 2004 +++ llvm/lib/Transforms/IPO/LoopExtractor.cpp Sat Mar 13 20:34:07 2004 @@ -1,4 +1,11 @@ //===- LoopExtractor.cpp - Extract each loop into a new function ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // A pass wrapper around the ExtractLoop() scalar transformation to extract each // top-level loop into its own new function. If the loop is the ONLY loop in a @@ -16,23 +23,19 @@ using namespace llvm; namespace { + // FIXME: PassManager should allow Module passes to require FunctionPasses + struct LoopExtractor : public FunctionPass { + virtual bool run(Module &M); + virtual bool runOnFunction(Function &F); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + }; -// FIXME: PassManager should allow Module passes to require FunctionPasses -struct LoopExtractor : public FunctionPass { - -public: - LoopExtractor() {} - virtual bool run(Module &M); - virtual bool runOnFunction(Function &F); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - } - -}; - -RegisterOpt -X("loop-extract", "Extract loops into new functions"); + RegisterOpt + X("loop-extract", "Extract loops into new functions"); +} // End anonymous namespace bool LoopExtractor::run(Module &M) { bool Changed = false; @@ -58,8 +61,6 @@ return Changed; } - -} // End anonymous namespace /// createLoopExtractorPass /// From lattner at cs.uiuc.edu Sat Mar 13 20:37:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:37:02 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/IPO.h Scalar.h Message-ID: <200403140236.UAA26845@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.28 -> 1.29 Scalar.h updated: 1.34 -> 1.35 --- Log message: Move loop extractor to the IPO header --- Diffs of the changes: (+8 -8) Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.28 llvm/include/llvm/Transforms/IPO.h:1.29 --- llvm/include/llvm/Transforms/IPO.h:1.28 Sun Mar 7 15:30:08 2004 +++ llvm/include/llvm/Transforms/IPO.h Sat Mar 13 20:36:34 2004 @@ -134,6 +134,14 @@ Pass *createSwapElementsPass(); Pass *createSortElementsPass(); + +//===----------------------------------------------------------------------===// +// +// LoopExtractor - This pass moves every natural loop into its own function. +// Mostly useful in debugging via bugpoint. +// +Pass *createLoopExtractorPass(); + } // End llvm namespace #endif Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.34 llvm/include/llvm/Transforms/Scalar.h:1.35 --- llvm/include/llvm/Transforms/Scalar.h:1.34 Fri Feb 27 21:33:17 2004 +++ llvm/include/llvm/Transforms/Scalar.h Sat Mar 13 20:36:34 2004 @@ -139,14 +139,6 @@ //===----------------------------------------------------------------------===// // -// LoopExtractor - This pass moves every natural loop into its own function. -// Mostly useful in debugging via bugpoint. -// -FunctionPass *createLoopExtractorPass(); - - -//===----------------------------------------------------------------------===// -// // PiNodeInsertion - This pass inserts single entry Phi nodes into basic blocks // that are preceeded by a conditional branch, where the branch gives // information about the operands of the condition. For example, this C code: From lattner at cs.uiuc.edu Sat Mar 13 20:38:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 20:38:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/LoopExtractor.cpp Message-ID: <200403140237.UAA26856@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: LoopExtractor.cpp updated: 1.2 -> 1.3 --- Log message: Move prototype to IPO.h instead of Scalar.h Make sure that the file interface header (IPO.h) is included first remove dead #incldue --- Diffs of the changes: (+2 -3) Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp diff -u llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.2 llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.3 --- llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.2 Sat Mar 13 20:34:07 2004 +++ llvm/lib/Transforms/IPO/LoopExtractor.cpp Sat Mar 13 20:37:16 2004 @@ -14,12 +14,11 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/IPO.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/FunctionUtils.h" -#include using namespace llvm; namespace { @@ -64,6 +63,6 @@ /// createLoopExtractorPass /// -FunctionPass* llvm::createLoopExtractorPass() { +Pass* llvm::createLoopExtractorPass() { return new LoopExtractor(); } From lattner at cs.uiuc.edu Sat Mar 13 21:05:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 21:05:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CodeExtractor/2004-03-13-LoopExtractorCrash.ll Message-ID: <200403140304.VAA32581@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CodeExtractor: 2004-03-13-LoopExtractorCrash.ll added (r1.1) --- Log message: New testcase that crashes the loop extractor --- Diffs of the changes: (+75 -0) Index: llvm/test/Regression/Transforms/CodeExtractor/2004-03-13-LoopExtractorCrash.ll diff -c /dev/null llvm/test/Regression/Transforms/CodeExtractor/2004-03-13-LoopExtractorCrash.ll:1.1 *** /dev/null Sat Mar 13 21:04:09 2004 --- llvm/test/Regression/Transforms/CodeExtractor/2004-03-13-LoopExtractorCrash.ll Sat Mar 13 21:03:59 2004 *************** *** 0 **** --- 1,75 ---- + ; RUN: llvm-as < %s | opt -loop-extract -disable-output + + void %solve() { + entry: + br label %loopentry.0 + + loopentry.0: ; preds = %entry, %endif.0 + br bool false, label %no_exit.0, label %loopexit.0 + + no_exit.0: ; preds = %loopentry.0 + br bool false, label %then.0, label %endif.0 + + then.0: ; preds = %no_exit.0 + br bool false, label %shortcirc_done, label %shortcirc_next + + shortcirc_next: ; preds = %then.0 + br label %shortcirc_done + + shortcirc_done: ; preds = %then.0, %shortcirc_next + br bool false, label %then.1, label %endif.1 + + then.1: ; preds = %shortcirc_done + br bool false, label %cond_true, label %cond_false + + cond_true: ; preds = %then.1 + br label %cond_continue + + cond_false: ; preds = %then.1 + br label %cond_continue + + cond_continue: ; preds = %cond_true, %cond_false + br label %return + + after_ret.0: ; No predecessors! + br label %endif.1 + + endif.1: ; preds = %shortcirc_done, %after_ret.0 + br label %endif.0 + + endif.0: ; preds = %no_exit.0, %endif.1 + br label %loopentry.0 + + loopexit.0: ; preds = %loopentry.0 + br bool false, label %then.2, label %endif.2 + + then.2: ; preds = %loopexit.0 + br bool false, label %then.3, label %endif.3 + + then.3: ; preds = %then.2 + br label %return + + after_ret.1: ; No predecessors! + br label %endif.3 + + endif.3: ; preds = %then.2, %after_ret.1 + br label %endif.2 + + endif.2: ; preds = %loopexit.0, %endif.3 + br label %loopentry.1 + + loopentry.1: ; preds = %endif.2, %no_exit.1 + br bool false, label %no_exit.1, label %loopexit.1 + + no_exit.1: ; preds = %loopentry.1 + br label %loopentry.1 + + loopexit.1: ; preds = %loopentry.1 + br label %return + + after_ret.2: ; No predecessors! + br label %return + + return: ; preds = %cond_continue, %then.3, %loopexit.1, %after_ret.2 + ret void + } From lattner at cs.uiuc.edu Sat Mar 13 21:17:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 21:17:02 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200403140316.VAA02596@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.86 -> 1.87 --- Log message: verifyFunction has been broken for a long time now. Fix it. --- Diffs of the changes: (+8 -12) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.86 llvm/lib/VMCore/Verifier.cpp:1.87 --- llvm/lib/VMCore/Verifier.cpp:1.86 Fri Mar 12 18:24:00 2004 +++ llvm/lib/VMCore/Verifier.cpp Sat Mar 13 21:16:15 2004 @@ -44,6 +44,7 @@ #include "llvm/Constants.h" #include "llvm/Pass.h" #include "llvm/Module.h" +#include "llvm/ModuleProvider.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" @@ -619,19 +620,14 @@ // verifyFunction - Create bool llvm::verifyFunction(const Function &f) { - Function &F = (Function&)f; + Function &F = const_cast(f); assert(!F.isExternal() && "Cannot verify external functions"); - - DominatorSet DS; - DS.doInitialization(*F.getParent()); - DS.runOnFunction(F); - - Verifier V(DS); - V.runOnFunction(F); - - DS.doFinalization(*F.getParent()); - - return V.Broken; + + FunctionPassManager FPM(new ExistingModuleProvider(F.getParent())); + Verifier *V = new Verifier(); + FPM.add(V); + FPM.run(F); + return V->Broken; } /// verifyModule - Check a module for errors, printing messages on stderr. From lattner at cs.uiuc.edu Sat Mar 13 21:18:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 21:18:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200403140317.VAA02614@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.3 -> 1.4 --- Log message: Verify functions as they are produced if -debug is specified. Reduce curly braceage --- Diffs of the changes: (+5 -6) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.3 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.4 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.3 Mon Mar 1 18:20:57 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Sat Mar 13 21:17:22 2004 @@ -20,6 +20,7 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/Verifier.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/FunctionUtils.h" #include "Support/Debug.h" @@ -324,13 +325,10 @@ for (unsigned i = 0, e = inputs.size(); i != e; ++i) { std::vector Users(inputs[i]->use_begin(), inputs[i]->use_end()); for (std::vector::iterator use = Users.begin(), useE = Users.end(); - use != useE; ++use) { - if (Instruction* inst = dyn_cast(*use)) { - if (contains(code, inst->getParent())) { + use != useE; ++use) + if (Instruction* inst = dyn_cast(*use)) + if (contains(code, inst->getParent())) inst->replaceUsesOfWith(inputs[i], getFunctionArg(newFunction, i)); - } - } - } } // Rewrite branches to basic blocks outside of the loop to new dummy blocks @@ -563,6 +561,7 @@ moveCodeToFunction(code, newFunction); + DEBUG(if (verifyFunction(*newFunction)) abort()); return newFunction; } From lattner at cs.uiuc.edu Sat Mar 13 21:25:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 21:25:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200403140324.VAA03013@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.87 -> 1.88 --- Log message: Catch some more cases of broken code. The loop extractor seems to be creating situations where there is a branch that goes to a block in another function. --- Diffs of the changes: (+8 -3) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.87 llvm/lib/VMCore/Verifier.cpp:1.88 --- llvm/lib/VMCore/Verifier.cpp:1.87 Sat Mar 13 21:16:15 2004 +++ llvm/lib/VMCore/Verifier.cpp Sat Mar 13 21:23:54 2004 @@ -508,11 +508,16 @@ for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { // Check to make sure that the "address of" an intrinsic function is never // taken. - if (Function *F = dyn_cast(I.getOperand(i))) + if (Function *F = dyn_cast(I.getOperand(i))) { Assert1(!F->isIntrinsic() || (i == 0 && isa(I)), "Cannot take the address of an intrinsic!", &I); - - else if (Instruction *Op = dyn_cast(I.getOperand(i))) { + } else if (BasicBlock *OpBB = dyn_cast(I.getOperand(i))) { + Assert1(OpBB->getParent() == BB->getParent(), + "Referring to a basic block in another function!", &I); + } else if (Argument *OpArg = dyn_cast(I.getOperand(i))) { + Assert1(OpArg->getParent() == BB->getParent(), + "Referring to an argument in another function!", &I); + } else if (Instruction *Op = dyn_cast(I.getOperand(i))) { BasicBlock *OpBlock = Op->getParent(); // Check that a definition dominates all of its uses. From lattner at cs.uiuc.edu Sat Mar 13 22:00:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 22:00:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopSimplify.cpp Message-ID: <200403140359.VAA05223@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopSimplify.cpp updated: 1.35 -> 1.36 --- Log message: If a block is dead, dominators will not be calculated for it. Because of this loop information won't see it, and we could have unreachable blocks pointing to the non-header node of blocks in a natural loop. This isn't tidy, so have the loopsimplify pass clean it up. --- Diffs of the changes: (+33 -2) Index: llvm/lib/Transforms/Scalar/LoopSimplify.cpp diff -u llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.35 llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.36 --- llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.35 Sat Mar 13 16:01:26 2004 +++ llvm/lib/Transforms/Scalar/LoopSimplify.cpp Sat Mar 13 21:59:22 2004 @@ -33,10 +33,11 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" -#include "llvm/Function.h" +#include "llvm/Constant.h" #include "llvm/iTerminators.h" #include "llvm/iPHINode.h" -#include "llvm/Constant.h" +#include "llvm/Function.h" +#include "llvm/Type.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" @@ -104,6 +105,36 @@ /// bool LoopSimplify::ProcessLoop(Loop *L) { bool Changed = false; + + // Check to see that no blocks (other than the header) in the loop have + // predecessors that are not in the loop. This is not valid for natural + // loops, but can occur if the blocks are unreachable. Since they are + // unreachable we can just shamelessly destroy their terminators to make them + // not branch into the loop! + assert(L->getBlocks()[0] == L->getHeader() && + "Header isn't first block in loop?"); + for (unsigned i = 1, e = L->getBlocks().size(); i != e; ++i) { + BasicBlock *LoopBB = L->getBlocks()[i]; + Retry: + for (pred_iterator PI = pred_begin(LoopBB), E = pred_end(LoopBB); + PI != E; ++PI) + if (!L->contains(*PI)) { + // This predecessor is not in the loop. Kill its terminator! + BasicBlock *DeadBlock = *PI; + for (succ_iterator SI = succ_begin(DeadBlock), E = succ_end(DeadBlock); + SI != E; ++SI) + (*SI)->removePredecessor(DeadBlock); // Remove PHI node entries + + // Delete the dead terminator. + DeadBlock->getInstList().pop_back(); + + Value *RetVal = 0; + if (LoopBB->getParent()->getReturnType() != Type::VoidTy) + RetVal = Constant::getNullValue(LoopBB->getParent()->getReturnType()); + new ReturnInst(RetVal, DeadBlock); + goto Retry; // We just invalidated the pred_iterator. Retry. + } + } // Does the loop already have a preheader? If so, don't modify the loop... if (L->getLoopPreheader() == 0) { From lattner at cs.uiuc.edu Sat Mar 13 22:02:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 22:02:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/LoopExtractor.cpp Message-ID: <200403140401.WAA05288@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: LoopExtractor.cpp updated: 1.3 -> 1.4 --- Log message: FunctionPass's should not define their own 'run' method. Require 'simplified' loops, not just raw natural loops. This fixes CodeExtractor/2004-03-13-LoopExtractorCrash.ll --- Diffs of the changes: (+2 -8) Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp diff -u llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.3 llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.4 --- llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.3 Sat Mar 13 20:37:16 2004 +++ llvm/lib/Transforms/IPO/LoopExtractor.cpp Sat Mar 13 22:01:06 2004 @@ -18,30 +18,24 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/FunctionUtils.h" using namespace llvm; namespace { // FIXME: PassManager should allow Module passes to require FunctionPasses struct LoopExtractor : public FunctionPass { - virtual bool run(Module &M); virtual bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequiredID(LoopSimplifyID); } }; RegisterOpt X("loop-extract", "Extract loops into new functions"); } // End anonymous namespace - -bool LoopExtractor::run(Module &M) { - bool Changed = false; - for (Module::iterator i = M.begin(), e = M.end(); i != e; ++i) - Changed |= runOnFunction(*i); - return Changed; -} bool LoopExtractor::runOnFunction(Function &F) { std::cerr << F.getName() << "\n"; From lattner at cs.uiuc.edu Sat Mar 13 22:02:12 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 22:02:12 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200403140401.WAA05302@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.4 -> 1.5 --- Log message: Minor random cleanups --- Diffs of the changes: (+7 -9) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.4 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.5 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.4 Sat Mar 13 21:17:22 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Sat Mar 13 22:01:47 2004 @@ -353,17 +353,18 @@ void CodeExtractor::moveCodeToFunction(const std::vector &code, Function *newFunction) { + Function *oldFunc = code[0]->getParent(); + Function::BasicBlockListType &oldBlocks = oldFunc->getBasicBlockList(); + Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList(); + for (std::vector::const_iterator i = code.begin(), e =code.end(); i != e; ++i) { BasicBlock *BB = *i; - Function *oldFunc = BB->getParent(); - Function::BasicBlockListType &oldBlocks = oldFunc->getBasicBlockList(); // Delete the basic block from the old function, and the list of blocks oldBlocks.remove(BB); // Insert this basic block into the new function - Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList(); newBlocks.push_back(BB); } } @@ -569,22 +570,19 @@ /// function /// Function* llvm::ExtractCodeRegion(const std::vector &code) { - CodeExtractor CE; - return CE.ExtractCodeRegion(code); + return CodeExtractor().ExtractCodeRegion(code); } /// ExtractBasicBlock - slurp a natural loop into a brand new function /// Function* llvm::ExtractLoop(Loop *L) { - CodeExtractor CE; - return CE.ExtractCodeRegion(L->getBlocks()); + return CodeExtractor().ExtractCodeRegion(L->getBlocks()); } /// ExtractBasicBlock - slurp a basic block into a brand new function /// Function* llvm::ExtractBasicBlock(BasicBlock *BB) { - CodeExtractor CE; std::vector Blocks; Blocks.push_back(BB); - return CE.ExtractCodeRegion(Blocks); + return CodeExtractor().ExtractCodeRegion(Blocks); } From lattner at cs.uiuc.edu Sat Mar 13 22:15:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 22:15:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LowerSwitch/2004-03-13-SwitchIsDefaultCrash.ll Message-ID: <200403140414.WAA10210@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LowerSwitch: 2004-03-13-SwitchIsDefaultCrash.ll added (r1.1) --- Log message: New testcase that crashes the -lowerswitch pass --- Diffs of the changes: (+21 -0) Index: llvm/test/Regression/Transforms/LowerSwitch/2004-03-13-SwitchIsDefaultCrash.ll diff -c /dev/null llvm/test/Regression/Transforms/LowerSwitch/2004-03-13-SwitchIsDefaultCrash.ll:1.1 *** /dev/null Sat Mar 13 22:14:08 2004 --- llvm/test/Regression/Transforms/LowerSwitch/2004-03-13-SwitchIsDefaultCrash.ll Sat Mar 13 22:13:57 2004 *************** *** 0 **** --- 1,21 ---- + ; RUN: llvm-as < %s | opt -lowerswitch -disable-output + + void %solve() { + entry: + %targetBlock = call ushort %solve_code( ) ; [#uses=1] + br label %codeReplTail + + then.1: ; preds = %codeReplTail + ret void + + loopexit.0: ; preds = %codeReplTail + ret void + + codeReplTail: ; preds = %entry, %codeReplTail + switch ushort %targetBlock, label %codeReplTail [ + ushort 0, label %loopexit.0 + ushort 1, label %then.1 + ] + } + + declare ushort %solve_code() From lattner at cs.uiuc.edu Sat Mar 13 22:15:12 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 22:15:12 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerSwitch.cpp Message-ID: <200403140414.WAA10340@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerSwitch.cpp updated: 1.11 -> 1.12 --- Log message: Do not create empty basic blocks when the lowerswitch pass expects blocks to be non-empty! This fixes LowerSwitch/2004-03-13-SwitchIsDefaultCrash.ll --- Diffs of the changes: (+2 -5) Index: llvm/lib/Transforms/Scalar/LowerSwitch.cpp diff -u llvm/lib/Transforms/Scalar/LowerSwitch.cpp:1.11 llvm/lib/Transforms/Scalar/LowerSwitch.cpp:1.12 --- llvm/lib/Transforms/Scalar/LowerSwitch.cpp:1.11 Wed Feb 25 09:15:04 2004 +++ llvm/lib/Transforms/Scalar/LowerSwitch.cpp Sat Mar 13 22:14:31 2004 @@ -181,13 +181,10 @@ Value *Val = SI->getOperand(0); // The value we are switching on... BasicBlock* Default = SI->getDefaultDest(); - // Unlink the switch instruction from it's block. - CurBlock->getInstList().remove(SI); - // If there is only the default destination, don't bother with the code below. if (SI->getNumOperands() == 2) { new BranchInst(SI->getDefaultDest(), CurBlock); - delete SI; + CurBlock->getInstList().erase(SI); return; } @@ -222,5 +219,5 @@ new BranchInst(SwitchBlock, OrigBlock); // We are now done with the switch instruction, delete it. - delete SI; + CurBlock->getInstList().erase(SI); } From lattner at cs.uiuc.edu Sat Mar 13 22:19:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Mar 13 22:19:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/LoopExtractor.cpp Message-ID: <200403140418.WAA11429@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: LoopExtractor.cpp updated: 1.4 -> 1.5 --- Log message: Passes don't print stuff! --- Diffs of the changes: (+0 -2) Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp diff -u llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.4 llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.5 --- llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.4 Sat Mar 13 22:01:06 2004 +++ llvm/lib/Transforms/IPO/LoopExtractor.cpp Sat Mar 13 22:17:53 2004 @@ -38,8 +38,6 @@ } // End anonymous namespace bool LoopExtractor::runOnFunction(Function &F) { - std::cerr << F.getName() << "\n"; - LoopInfo &LI = getAnalysis(); // We don't want to keep extracting the only loop of a function into a new one From alkis at cs.uiuc.edu Sun Mar 14 01:21:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Mar 14 01:21:01 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLocal.cpp LiveIntervals.cpp Message-ID: <200403140720.BAA12305@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLocal.cpp updated: 1.60 -> 1.61 LiveIntervals.cpp updated: 1.65 -> 1.66 --- Log message: Change MRegisterInfo::foldMemoryOperand to return the folded instruction to make the API more flexible. --- Diffs of the changes: (+12 -11) Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.60 llvm/lib/CodeGen/RegAllocLocal.cpp:1.61 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.60 Thu Feb 26 16:00:20 2004 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Sun Mar 14 01:19:51 2004 @@ -487,13 +487,12 @@ assignVirtToPhysReg(VirtReg, PhysReg); } else { // No registers available. // If we can fold this spill into this instruction, do so now. - MachineBasicBlock::iterator MII = MI; - if (RegInfo->foldMemoryOperand(MII, OpNum, FrameIndex)) { + if (MachineInstr* FMI = RegInfo->foldMemoryOperand(MI, OpNum, FrameIndex)){ ++NumFolded; // Since we changed the address of MI, make sure to update live variables // to know that the new instruction has the properties of the old one. - LV->instructionChanged(MI, MII); - return MII; + LV->instructionChanged(MI, FMI); + return MBB.insert(MBB.erase(MI), FMI); } // It looks like we can't fold this virtual register load into this Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.65 llvm/lib/CodeGen/LiveIntervals.cpp:1.66 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.65 Mon Mar 1 14:05:10 2004 +++ llvm/lib/CodeGen/LiveIntervals.cpp Sun Mar 14 01:19:51 2004 @@ -209,13 +209,15 @@ for (unsigned i = 0; i < mi->getNumOperands(); ++i) { MachineOperand& mop = mi->getOperand(i); if (mop.isRegister() && mop.getReg() == li.reg) { - MachineInstr* old = mi; - if (mri_->foldMemoryOperand(mi, i, slot)) { - lv_->instructionChanged(old, mi); - vrm.virtFolded(li.reg, old, mi); - mi2iMap_.erase(old); - i2miMap_[index/InstrSlots::NUM] = mi; - mi2iMap_[mi] = index; + if (MachineInstr* fmi = + mri_->foldMemoryOperand(mi, i, slot)) { + lv_->instructionChanged(mi, fmi); + vrm.virtFolded(li.reg, mi, fmi); + mi2iMap_.erase(mi); + i2miMap_[index/InstrSlots::NUM] = fmi; + mi2iMap_[fmi] = index; + MachineBasicBlock& mbb = *mi->getParent(); + mi = mbb.insert(mbb.erase(mi), fmi); ++numFolded; goto for_operand; } From alkis at cs.uiuc.edu Sun Mar 14 01:21:12 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Mar 14 01:21:12 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.h X86RegisterInfo.cpp Message-ID: <200403140720.BAA12298@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.h updated: 1.23 -> 1.24 X86RegisterInfo.cpp updated: 1.76 -> 1.77 --- Log message: Change MRegisterInfo::foldMemoryOperand to return the folded instruction to make the API more flexible. --- Diffs of the changes: (+166 -171) Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.23 llvm/lib/Target/X86/X86RegisterInfo.h:1.24 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.23 Mon Feb 16 23:54:57 2004 +++ llvm/lib/Target/X86/X86RegisterInfo.h Sun Mar 14 01:19:51 2004 @@ -48,8 +48,9 @@ /// folding and return true, otherwise it should return false. If it folds /// the instruction, it is likely that the MachineInstruction the iterator /// references has been changed. - virtual bool foldMemoryOperand(MachineBasicBlock::iterator &MI,unsigned OpNum, - int FrameIndex) const; + virtual MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, + unsigned OpNum, + int FrameIndex) const; void eliminateCallFramePseudoInstr(MachineFunction &MF, Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.76 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.77 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.76 Sat Mar 6 21:19:11 2004 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Sun Mar 14 01:19:51 2004 @@ -1,10 +1,10 @@ //===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===// -// +// // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file contains the X86 implementation of the MRegisterInfo class. This @@ -132,181 +132,175 @@ } -bool X86RegisterInfo::foldMemoryOperand(MachineBasicBlock::iterator &MI, - unsigned i, int FrameIndex) const { - if (NoFusing) return false; +MachineInstr* X86RegisterInfo::foldMemoryOperand( + MachineBasicBlock::iterator MI, + unsigned i, + int FrameIndex) const { + if (NoFusing) return NULL; /// FIXME: This should obviously be autogenerated by tablegen when patterns /// are available! MachineBasicBlock& MBB = *MI->getParent(); - MachineInstr* NI = 0; if (i == 0) { switch(MI->getOpcode()) { - case X86::XCHG8rr: NI = MakeMRInst(X86::XCHG8mr ,FrameIndex, MI); break; - case X86::XCHG16rr:NI = MakeMRInst(X86::XCHG16mr,FrameIndex, MI); break; - case X86::XCHG32rr:NI = MakeMRInst(X86::XCHG32mr,FrameIndex, MI); break; - case X86::MOV8rr: NI = MakeMRInst(X86::MOV8mr , FrameIndex, MI); break; - case X86::MOV16rr: NI = MakeMRInst(X86::MOV16mr, FrameIndex, MI); break; - case X86::MOV32rr: NI = MakeMRInst(X86::MOV32mr, FrameIndex, MI); break; - case X86::MOV8ri: NI = MakeMIInst(X86::MOV8mi , FrameIndex, MI); break; - case X86::MOV16ri: NI = MakeMIInst(X86::MOV16mi, FrameIndex, MI); break; - case X86::MOV32ri: NI = MakeMIInst(X86::MOV32mi, FrameIndex, MI); break; - case X86::MUL8r: NI = MakeMInst( X86::MUL8m , FrameIndex, MI); break; - case X86::MUL16r: NI = MakeMInst( X86::MUL16m, FrameIndex, MI); break; - case X86::MUL32r: NI = MakeMInst( X86::MUL32m, FrameIndex, MI); break; - case X86::DIV8r: NI = MakeMInst( X86::DIV8m , FrameIndex, MI); break; - case X86::DIV16r: NI = MakeMInst( X86::DIV16m, FrameIndex, MI); break; - case X86::DIV32r: NI = MakeMInst( X86::DIV32m, FrameIndex, MI); break; - case X86::IDIV8r: NI = MakeMInst( X86::IDIV8m , FrameIndex, MI); break; - case X86::IDIV16r: NI = MakeMInst( X86::IDIV16m, FrameIndex, MI); break; - case X86::IDIV32r: NI = MakeMInst( X86::IDIV32m, FrameIndex, MI); break; - case X86::NEG8r: NI = MakeMInst( X86::NEG8m , FrameIndex, MI); break; - case X86::NEG16r: NI = MakeMInst( X86::NEG16m, FrameIndex, MI); break; - case X86::NEG32r: NI = MakeMInst( X86::NEG32m, FrameIndex, MI); break; - case X86::NOT8r: NI = MakeMInst( X86::NOT8m , FrameIndex, MI); break; - case X86::NOT16r: NI = MakeMInst( X86::NOT16m, FrameIndex, MI); break; - case X86::NOT32r: NI = MakeMInst( X86::NOT32m, FrameIndex, MI); break; - case X86::INC8r: NI = MakeMInst( X86::INC8m , FrameIndex, MI); break; - case X86::INC16r: NI = MakeMInst( X86::INC16m, FrameIndex, MI); break; - case X86::INC32r: NI = MakeMInst( X86::INC32m, FrameIndex, MI); break; - case X86::DEC8r: NI = MakeMInst( X86::DEC8m , FrameIndex, MI); break; - case X86::DEC16r: NI = MakeMInst( X86::DEC16m, FrameIndex, MI); break; - case X86::DEC32r: NI = MakeMInst( X86::DEC32m, FrameIndex, MI); break; - case X86::ADD8rr: NI = MakeMRInst(X86::ADD8mr , FrameIndex, MI); break; - case X86::ADD16rr: NI = MakeMRInst(X86::ADD16mr, FrameIndex, MI); break; - case X86::ADD32rr: NI = MakeMRInst(X86::ADD32mr, FrameIndex, MI); break; - case X86::ADC32rr: NI = MakeMRInst(X86::ADC32mr, FrameIndex, MI); break; - case X86::ADD8ri: NI = MakeMIInst(X86::ADD8mi , FrameIndex, MI); break; - case X86::ADD16ri: NI = MakeMIInst(X86::ADD16mi, FrameIndex, MI); break; - case X86::ADD32ri: NI = MakeMIInst(X86::ADD32mi, FrameIndex, MI); break; - case X86::SUB8rr: NI = MakeMRInst(X86::SUB8mr , FrameIndex, MI); break; - case X86::SUB16rr: NI = MakeMRInst(X86::SUB16mr, FrameIndex, MI); break; - case X86::SUB32rr: NI = MakeMRInst(X86::SUB32mr, FrameIndex, MI); break; - case X86::SBB32rr: NI = MakeMRInst(X86::SBB32mr, FrameIndex, MI); break; - case X86::SUB8ri: NI = MakeMIInst(X86::SUB8mi , FrameIndex, MI); break; - case X86::SUB16ri: NI = MakeMIInst(X86::SUB16mi, FrameIndex, MI); break; - case X86::SUB32ri: NI = MakeMIInst(X86::SUB32mi, FrameIndex, MI); break; - case X86::AND8rr: NI = MakeMRInst(X86::AND8mr , FrameIndex, MI); break; - case X86::AND16rr: NI = MakeMRInst(X86::AND16mr, FrameIndex, MI); break; - case X86::AND32rr: NI = MakeMRInst(X86::AND32mr, FrameIndex, MI); break; - case X86::AND8ri: NI = MakeMIInst(X86::AND8mi , FrameIndex, MI); break; - case X86::AND16ri: NI = MakeMIInst(X86::AND16mi, FrameIndex, MI); break; - case X86::AND32ri: NI = MakeMIInst(X86::AND32mi, FrameIndex, MI); break; - case X86::OR8rr: NI = MakeMRInst(X86::OR8mr , FrameIndex, MI); break; - case X86::OR16rr: NI = MakeMRInst(X86::OR16mr, FrameIndex, MI); break; - case X86::OR32rr: NI = MakeMRInst(X86::OR32mr, FrameIndex, MI); break; - case X86::OR8ri: NI = MakeMIInst(X86::OR8mi , FrameIndex, MI); break; - case X86::OR16ri: NI = MakeMIInst(X86::OR16mi, FrameIndex, MI); break; - case X86::OR32ri: NI = MakeMIInst(X86::OR32mi, FrameIndex, MI); break; - case X86::XOR8rr: NI = MakeMRInst(X86::XOR8mr , FrameIndex, MI); break; - case X86::XOR16rr: NI = MakeMRInst(X86::XOR16mr, FrameIndex, MI); break; - case X86::XOR32rr: NI = MakeMRInst(X86::XOR32mr, FrameIndex, MI); break; - case X86::XOR8ri: NI = MakeMIInst(X86::XOR8mi , FrameIndex, MI); break; - case X86::XOR16ri: NI = MakeMIInst(X86::XOR16mi, FrameIndex, MI); break; - case X86::XOR32ri: NI = MakeMIInst(X86::XOR32mi, FrameIndex, MI); break; - case X86::SHL8rCL: NI = MakeMInst( X86::SHL8mCL ,FrameIndex, MI); break; - case X86::SHL16rCL:NI = MakeMInst( X86::SHL16mCL,FrameIndex, MI); break; - case X86::SHL32rCL:NI = MakeMInst( X86::SHL32mCL,FrameIndex, MI); break; - case X86::SHL8ri: NI = MakeMIInst(X86::SHL8mi , FrameIndex, MI); break; - case X86::SHL16ri: NI = MakeMIInst(X86::SHL16mi, FrameIndex, MI); break; - case X86::SHL32ri: NI = MakeMIInst(X86::SHL32mi, FrameIndex, MI); break; - case X86::SHR8rCL: NI = MakeMInst( X86::SHR8mCL ,FrameIndex, MI); break; - case X86::SHR16rCL:NI = MakeMInst( X86::SHR16mCL,FrameIndex, MI); break; - case X86::SHR32rCL:NI = MakeMInst( X86::SHR32mCL,FrameIndex, MI); break; - case X86::SHR8ri: NI = MakeMIInst(X86::SHR8mi , FrameIndex, MI); break; - case X86::SHR16ri: NI = MakeMIInst(X86::SHR16mi, FrameIndex, MI); break; - case X86::SHR32ri: NI = MakeMIInst(X86::SHR32mi, FrameIndex, MI); break; - case X86::SAR8rCL: NI = MakeMInst( X86::SAR8mCL ,FrameIndex, MI); break; - case X86::SAR16rCL:NI = MakeMInst( X86::SAR16mCL,FrameIndex, MI); break; - case X86::SAR32rCL:NI = MakeMInst( X86::SAR32mCL,FrameIndex, MI); break; - case X86::SAR8ri: NI = MakeMIInst(X86::SAR8mi , FrameIndex, MI); break; - case X86::SAR16ri: NI = MakeMIInst(X86::SAR16mi, FrameIndex, MI); break; - case X86::SAR32ri: NI = MakeMIInst(X86::SAR32mi, FrameIndex, MI); break; - case X86::SHLD32rrCL:NI = MakeMRInst( X86::SHLD32mrCL,FrameIndex, MI);break; - case X86::SHLD32rri8:NI = MakeMRIInst(X86::SHLD32mri8,FrameIndex, MI);break; - case X86::SHRD32rrCL:NI = MakeMRInst( X86::SHRD32mrCL,FrameIndex, MI);break; - case X86::SHRD32rri8:NI = MakeMRIInst(X86::SHRD32mri8,FrameIndex, MI);break; - case X86::SETBr: NI = MakeMInst( X86::SETBm, FrameIndex, MI); break; - case X86::SETAEr: NI = MakeMInst( X86::SETAEm, FrameIndex, MI); break; - case X86::SETEr: NI = MakeMInst( X86::SETEm, FrameIndex, MI); break; - case X86::SETNEr: NI = MakeMInst( X86::SETNEm, FrameIndex, MI); break; - case X86::SETBEr: NI = MakeMInst( X86::SETBEm, FrameIndex, MI); break; - case X86::SETAr: NI = MakeMInst( X86::SETAm, FrameIndex, MI); break; - case X86::SETSr: NI = MakeMInst( X86::SETSm, FrameIndex, MI); break; - case X86::SETNSr: NI = MakeMInst( X86::SETNSm, FrameIndex, MI); break; - case X86::SETLr: NI = MakeMInst( X86::SETLm, FrameIndex, MI); break; - case X86::SETGEr: NI = MakeMInst( X86::SETGEm, FrameIndex, MI); break; - case X86::SETLEr: NI = MakeMInst( X86::SETLEm, FrameIndex, MI); break; - case X86::SETGr: NI = MakeMInst( X86::SETGm, FrameIndex, MI); break; - case X86::TEST8rr: NI = MakeMRInst(X86::TEST8mr ,FrameIndex, MI); break; - case X86::TEST16rr:NI = MakeMRInst(X86::TEST16mr,FrameIndex, MI); break; - case X86::TEST32rr:NI = MakeMRInst(X86::TEST32mr,FrameIndex, MI); break; - case X86::TEST8ri: NI = MakeMIInst(X86::TEST8mi ,FrameIndex, MI); break; - case X86::TEST16ri:NI = MakeMIInst(X86::TEST16mi,FrameIndex, MI); break; - case X86::TEST32ri:NI = MakeMIInst(X86::TEST32mi,FrameIndex, MI); break; - case X86::CMP8rr: NI = MakeMRInst(X86::CMP8mr , FrameIndex, MI); break; - case X86::CMP16rr: NI = MakeMRInst(X86::CMP16mr, FrameIndex, MI); break; - case X86::CMP32rr: NI = MakeMRInst(X86::CMP32mr, FrameIndex, MI); break; - case X86::CMP8ri: NI = MakeMIInst(X86::CMP8mi , FrameIndex, MI); break; - case X86::CMP16ri: NI = MakeMIInst(X86::CMP16mi, FrameIndex, MI); break; - case X86::CMP32ri: NI = MakeMIInst(X86::CMP32mi, FrameIndex, MI); break; - default: break; // Cannot fold + case X86::XCHG8rr: return MakeMRInst(X86::XCHG8mr ,FrameIndex, MI); + case X86::XCHG16rr: return MakeMRInst(X86::XCHG16mr,FrameIndex, MI); + case X86::XCHG32rr: return MakeMRInst(X86::XCHG32mr,FrameIndex, MI); + case X86::MOV8rr: return MakeMRInst(X86::MOV8mr , FrameIndex, MI); + case X86::MOV16rr: return MakeMRInst(X86::MOV16mr, FrameIndex, MI); + case X86::MOV32rr: return MakeMRInst(X86::MOV32mr, FrameIndex, MI); + case X86::MOV8ri: return MakeMIInst(X86::MOV8mi , FrameIndex, MI); + case X86::MOV16ri: return MakeMIInst(X86::MOV16mi, FrameIndex, MI); + case X86::MOV32ri: return MakeMIInst(X86::MOV32mi, FrameIndex, MI); + case X86::MUL8r: return MakeMInst( X86::MUL8m , FrameIndex, MI); + case X86::MUL16r: return MakeMInst( X86::MUL16m, FrameIndex, MI); + case X86::MUL32r: return MakeMInst( X86::MUL32m, FrameIndex, MI); + case X86::DIV8r: return MakeMInst( X86::DIV8m , FrameIndex, MI); + case X86::DIV16r: return MakeMInst( X86::DIV16m, FrameIndex, MI); + case X86::DIV32r: return MakeMInst( X86::DIV32m, FrameIndex, MI); + case X86::IDIV8r: return MakeMInst( X86::IDIV8m , FrameIndex, MI); + case X86::IDIV16r: return MakeMInst( X86::IDIV16m, FrameIndex, MI); + case X86::IDIV32r: return MakeMInst( X86::IDIV32m, FrameIndex, MI); + case X86::NEG8r: return MakeMInst( X86::NEG8m , FrameIndex, MI); + case X86::NEG16r: return MakeMInst( X86::NEG16m, FrameIndex, MI); + case X86::NEG32r: return MakeMInst( X86::NEG32m, FrameIndex, MI); + case X86::NOT8r: return MakeMInst( X86::NOT8m , FrameIndex, MI); + case X86::NOT16r: return MakeMInst( X86::NOT16m, FrameIndex, MI); + case X86::NOT32r: return MakeMInst( X86::NOT32m, FrameIndex, MI); + case X86::INC8r: return MakeMInst( X86::INC8m , FrameIndex, MI); + case X86::INC16r: return MakeMInst( X86::INC16m, FrameIndex, MI); + case X86::INC32r: return MakeMInst( X86::INC32m, FrameIndex, MI); + case X86::DEC8r: return MakeMInst( X86::DEC8m , FrameIndex, MI); + case X86::DEC16r: return MakeMInst( X86::DEC16m, FrameIndex, MI); + case X86::DEC32r: return MakeMInst( X86::DEC32m, FrameIndex, MI); + case X86::ADD8rr: return MakeMRInst(X86::ADD8mr , FrameIndex, MI); + case X86::ADD16rr: return MakeMRInst(X86::ADD16mr, FrameIndex, MI); + case X86::ADD32rr: return MakeMRInst(X86::ADD32mr, FrameIndex, MI); + case X86::ADC32rr: return MakeMRInst(X86::ADC32mr, FrameIndex, MI); + case X86::ADD8ri: return MakeMIInst(X86::ADD8mi , FrameIndex, MI); + case X86::ADD16ri: return MakeMIInst(X86::ADD16mi, FrameIndex, MI); + case X86::ADD32ri: return MakeMIInst(X86::ADD32mi, FrameIndex, MI); + case X86::SUB8rr: return MakeMRInst(X86::SUB8mr , FrameIndex, MI); + case X86::SUB16rr: return MakeMRInst(X86::SUB16mr, FrameIndex, MI); + case X86::SUB32rr: return MakeMRInst(X86::SUB32mr, FrameIndex, MI); + case X86::SBB32rr: return MakeMRInst(X86::SBB32mr, FrameIndex, MI); + case X86::SUB8ri: return MakeMIInst(X86::SUB8mi , FrameIndex, MI); + case X86::SUB16ri: return MakeMIInst(X86::SUB16mi, FrameIndex, MI); + case X86::SUB32ri: return MakeMIInst(X86::SUB32mi, FrameIndex, MI); + case X86::AND8rr: return MakeMRInst(X86::AND8mr , FrameIndex, MI); + case X86::AND16rr: return MakeMRInst(X86::AND16mr, FrameIndex, MI); + case X86::AND32rr: return MakeMRInst(X86::AND32mr, FrameIndex, MI); + case X86::AND8ri: return MakeMIInst(X86::AND8mi , FrameIndex, MI); + case X86::AND16ri: return MakeMIInst(X86::AND16mi, FrameIndex, MI); + case X86::AND32ri: return MakeMIInst(X86::AND32mi, FrameIndex, MI); + case X86::OR8rr: return MakeMRInst(X86::OR8mr , FrameIndex, MI); + case X86::OR16rr: return MakeMRInst(X86::OR16mr, FrameIndex, MI); + case X86::OR32rr: return MakeMRInst(X86::OR32mr, FrameIndex, MI); + case X86::OR8ri: return MakeMIInst(X86::OR8mi , FrameIndex, MI); + case X86::OR16ri: return MakeMIInst(X86::OR16mi, FrameIndex, MI); + case X86::OR32ri: return MakeMIInst(X86::OR32mi, FrameIndex, MI); + case X86::XOR8rr: return MakeMRInst(X86::XOR8mr , FrameIndex, MI); + case X86::XOR16rr: return MakeMRInst(X86::XOR16mr, FrameIndex, MI); + case X86::XOR32rr: return MakeMRInst(X86::XOR32mr, FrameIndex, MI); + case X86::XOR8ri: return MakeMIInst(X86::XOR8mi , FrameIndex, MI); + case X86::XOR16ri: return MakeMIInst(X86::XOR16mi, FrameIndex, MI); + case X86::XOR32ri: return MakeMIInst(X86::XOR32mi, FrameIndex, MI); + case X86::SHL8rCL: return MakeMInst( X86::SHL8mCL ,FrameIndex, MI); + case X86::SHL16rCL: return MakeMInst( X86::SHL16mCL,FrameIndex, MI); + case X86::SHL32rCL: return MakeMInst( X86::SHL32mCL,FrameIndex, MI); + case X86::SHL8ri: return MakeMIInst(X86::SHL8mi , FrameIndex, MI); + case X86::SHL16ri: return MakeMIInst(X86::SHL16mi, FrameIndex, MI); + case X86::SHL32ri: return MakeMIInst(X86::SHL32mi, FrameIndex, MI); + case X86::SHR8rCL: return MakeMInst( X86::SHR8mCL ,FrameIndex, MI); + case X86::SHR16rCL: return MakeMInst( X86::SHR16mCL,FrameIndex, MI); + case X86::SHR32rCL: return MakeMInst( X86::SHR32mCL,FrameIndex, MI); + case X86::SHR8ri: return MakeMIInst(X86::SHR8mi , FrameIndex, MI); + case X86::SHR16ri: return MakeMIInst(X86::SHR16mi, FrameIndex, MI); + case X86::SHR32ri: return MakeMIInst(X86::SHR32mi, FrameIndex, MI); + case X86::SAR8rCL: return MakeMInst( X86::SAR8mCL ,FrameIndex, MI); + case X86::SAR16rCL: return MakeMInst( X86::SAR16mCL,FrameIndex, MI); + case X86::SAR32rCL: return MakeMInst( X86::SAR32mCL,FrameIndex, MI); + case X86::SAR8ri: return MakeMIInst(X86::SAR8mi , FrameIndex, MI); + case X86::SAR16ri: return MakeMIInst(X86::SAR16mi, FrameIndex, MI); + case X86::SAR32ri: return MakeMIInst(X86::SAR32mi, FrameIndex, MI); + case X86::SHLD32rrCL:return MakeMRInst( X86::SHLD32mrCL,FrameIndex, MI); + case X86::SHLD32rri8:return MakeMRIInst(X86::SHLD32mri8,FrameIndex, MI); + case X86::SHRD32rrCL:return MakeMRInst( X86::SHRD32mrCL,FrameIndex, MI); + case X86::SHRD32rri8:return MakeMRIInst(X86::SHRD32mri8,FrameIndex, MI); + case X86::SETBr: return MakeMInst( X86::SETBm, FrameIndex, MI); + case X86::SETAEr: return MakeMInst( X86::SETAEm, FrameIndex, MI); + case X86::SETEr: return MakeMInst( X86::SETEm, FrameIndex, MI); + case X86::SETNEr: return MakeMInst( X86::SETNEm, FrameIndex, MI); + case X86::SETBEr: return MakeMInst( X86::SETBEm, FrameIndex, MI); + case X86::SETAr: return MakeMInst( X86::SETAm, FrameIndex, MI); + case X86::SETSr: return MakeMInst( X86::SETSm, FrameIndex, MI); + case X86::SETNSr: return MakeMInst( X86::SETNSm, FrameIndex, MI); + case X86::SETLr: return MakeMInst( X86::SETLm, FrameIndex, MI); + case X86::SETGEr: return MakeMInst( X86::SETGEm, FrameIndex, MI); + case X86::SETLEr: return MakeMInst( X86::SETLEm, FrameIndex, MI); + case X86::SETGr: return MakeMInst( X86::SETGm, FrameIndex, MI); + case X86::TEST8rr: return MakeMRInst(X86::TEST8mr ,FrameIndex, MI); + case X86::TEST16rr: return MakeMRInst(X86::TEST16mr,FrameIndex, MI); + case X86::TEST32rr: return MakeMRInst(X86::TEST32mr,FrameIndex, MI); + case X86::TEST8ri: return MakeMIInst(X86::TEST8mi ,FrameIndex, MI); + case X86::TEST16ri: return MakeMIInst(X86::TEST16mi,FrameIndex, MI); + case X86::TEST32ri: return MakeMIInst(X86::TEST32mi,FrameIndex, MI); + case X86::CMP8rr: return MakeMRInst(X86::CMP8mr , FrameIndex, MI); + case X86::CMP16rr: return MakeMRInst(X86::CMP16mr, FrameIndex, MI); + case X86::CMP32rr: return MakeMRInst(X86::CMP32mr, FrameIndex, MI); + case X86::CMP8ri: return MakeMIInst(X86::CMP8mi , FrameIndex, MI); + case X86::CMP16ri: return MakeMIInst(X86::CMP16mi, FrameIndex, MI); + case X86::CMP32ri: return MakeMIInst(X86::CMP32mi, FrameIndex, MI); } } else if (i == 1) { switch(MI->getOpcode()) { - case X86::XCHG8rr: NI = MakeRMInst(X86::XCHG8rm ,FrameIndex, MI); break; - case X86::XCHG16rr:NI = MakeRMInst(X86::XCHG16rm,FrameIndex, MI); break; - case X86::XCHG32rr:NI = MakeRMInst(X86::XCHG32rm,FrameIndex, MI); break; - case X86::MOV8rr: NI = MakeRMInst(X86::MOV8rm , FrameIndex, MI); break; - case X86::MOV16rr: NI = MakeRMInst(X86::MOV16rm, FrameIndex, MI); break; - case X86::MOV32rr: NI = MakeRMInst(X86::MOV32rm, FrameIndex, MI); break; - case X86::CMOVE16rr: NI = MakeRMInst(X86::CMOVE16rm , FrameIndex, MI); break; - case X86::CMOVNE32rr: NI = MakeRMInst(X86::CMOVNE32rm, FrameIndex, MI); break; - case X86::CMOVS32rr: NI = MakeRMInst(X86::CMOVS32rm , FrameIndex, MI); break; - case X86::ADD8rr: NI = MakeRMInst(X86::ADD8rm , FrameIndex, MI); break; - case X86::ADD16rr: NI = MakeRMInst(X86::ADD16rm, FrameIndex, MI); break; - case X86::ADD32rr: NI = MakeRMInst(X86::ADD32rm, FrameIndex, MI); break; - case X86::ADC32rr: NI = MakeRMInst(X86::ADC32rm, FrameIndex, MI); break; - case X86::SUB8rr: NI = MakeRMInst(X86::SUB8rm , FrameIndex, MI); break; - case X86::SUB16rr: NI = MakeRMInst(X86::SUB16rm, FrameIndex, MI); break; - case X86::SUB32rr: NI = MakeRMInst(X86::SUB32rm, FrameIndex, MI); break; - case X86::SBB32rr: NI = MakeRMInst(X86::SBB32rm, FrameIndex, MI); break; - case X86::AND8rr: NI = MakeRMInst(X86::AND8rm , FrameIndex, MI); break; - case X86::AND16rr: NI = MakeRMInst(X86::AND16rm, FrameIndex, MI); break; - case X86::AND32rr: NI = MakeRMInst(X86::AND32rm, FrameIndex, MI); break; - case X86::OR8rr: NI = MakeRMInst(X86::OR8rm , FrameIndex, MI); break; - case X86::OR16rr: NI = MakeRMInst(X86::OR16rm, FrameIndex, MI); break; - case X86::OR32rr: NI = MakeRMInst(X86::OR32rm, FrameIndex, MI); break; - case X86::XOR8rr: NI = MakeRMInst(X86::XOR8rm , FrameIndex, MI); break; - case X86::XOR16rr: NI = MakeRMInst(X86::XOR16rm, FrameIndex, MI); break; - case X86::XOR32rr: NI = MakeRMInst(X86::XOR32rm, FrameIndex, MI); break; - case X86::TEST8rr: NI = MakeRMInst(X86::TEST8rm ,FrameIndex, MI); break; - case X86::TEST16rr:NI = MakeRMInst(X86::TEST16rm,FrameIndex, MI); break; - case X86::TEST32rr:NI = MakeRMInst(X86::TEST32rm,FrameIndex, MI); break; - case X86::IMUL16rr:NI = MakeRMInst(X86::IMUL16rm,FrameIndex, MI); break; - case X86::IMUL32rr:NI = MakeRMInst(X86::IMUL32rm,FrameIndex, MI); break; - case X86::IMUL16rri: NI = MakeRMIInst(X86::IMUL16rmi, FrameIndex, MI);break; - case X86::IMUL32rri: NI = MakeRMIInst(X86::IMUL32rmi, FrameIndex, MI);break; - case X86::CMP8rr: NI = MakeRMInst(X86::CMP8rm , FrameIndex, MI); break; - case X86::CMP16rr: NI = MakeRMInst(X86::CMP16rm, FrameIndex, MI); break; - case X86::CMP32rr: NI = MakeRMInst(X86::CMP32rm, FrameIndex, MI); break; - case X86::MOVSX16rr8: NI = MakeRMInst(X86::MOVSX16rm8 , FrameIndex, MI); break; - case X86::MOVSX32rr8: NI = MakeRMInst(X86::MOVSX32rm8, FrameIndex, MI); break; - case X86::MOVSX32rr16:NI = MakeRMInst(X86::MOVSX32rm16, FrameIndex, MI); break; - case X86::MOVZX16rr8: NI = MakeRMInst(X86::MOVZX16rm8 , FrameIndex, MI); break; - case X86::MOVZX32rr8: NI = MakeRMInst(X86::MOVZX32rm8, FrameIndex, MI); break; - case X86::MOVZX32rr16:NI = MakeRMInst(X86::MOVZX32rm16, FrameIndex, MI); break; - default: break; + case X86::XCHG8rr: return MakeRMInst(X86::XCHG8rm ,FrameIndex, MI); + case X86::XCHG16rr: return MakeRMInst(X86::XCHG16rm,FrameIndex, MI); + case X86::XCHG32rr: return MakeRMInst(X86::XCHG32rm,FrameIndex, MI); + case X86::MOV8rr: return MakeRMInst(X86::MOV8rm , FrameIndex, MI); + case X86::MOV16rr: return MakeRMInst(X86::MOV16rm, FrameIndex, MI); + case X86::MOV32rr: return MakeRMInst(X86::MOV32rm, FrameIndex, MI); + case X86::CMOVE16rr: return MakeRMInst(X86::CMOVE16rm , FrameIndex, MI); + case X86::CMOVNE32rr:return MakeRMInst(X86::CMOVNE32rm, FrameIndex, MI); + case X86::CMOVS32rr: return MakeRMInst(X86::CMOVS32rm , FrameIndex, MI); + case X86::ADD8rr: return MakeRMInst(X86::ADD8rm , FrameIndex, MI); + case X86::ADD16rr: return MakeRMInst(X86::ADD16rm, FrameIndex, MI); + case X86::ADD32rr: return MakeRMInst(X86::ADD32rm, FrameIndex, MI); + case X86::ADC32rr: return MakeRMInst(X86::ADC32rm, FrameIndex, MI); + case X86::SUB8rr: return MakeRMInst(X86::SUB8rm , FrameIndex, MI); + case X86::SUB16rr: return MakeRMInst(X86::SUB16rm, FrameIndex, MI); + case X86::SUB32rr: return MakeRMInst(X86::SUB32rm, FrameIndex, MI); + case X86::SBB32rr: return MakeRMInst(X86::SBB32rm, FrameIndex, MI); + case X86::AND8rr: return MakeRMInst(X86::AND8rm , FrameIndex, MI); + case X86::AND16rr: return MakeRMInst(X86::AND16rm, FrameIndex, MI); + case X86::AND32rr: return MakeRMInst(X86::AND32rm, FrameIndex, MI); + case X86::OR8rr: return MakeRMInst(X86::OR8rm , FrameIndex, MI); + case X86::OR16rr: return MakeRMInst(X86::OR16rm, FrameIndex, MI); + case X86::OR32rr: return MakeRMInst(X86::OR32rm, FrameIndex, MI); + case X86::XOR8rr: return MakeRMInst(X86::XOR8rm , FrameIndex, MI); + case X86::XOR16rr: return MakeRMInst(X86::XOR16rm, FrameIndex, MI); + case X86::XOR32rr: return MakeRMInst(X86::XOR32rm, FrameIndex, MI); + case X86::TEST8rr: return MakeRMInst(X86::TEST8rm ,FrameIndex, MI); + case X86::TEST16rr: return MakeRMInst(X86::TEST16rm,FrameIndex, MI); + case X86::TEST32rr: return MakeRMInst(X86::TEST32rm,FrameIndex, MI); + case X86::IMUL16rr: return MakeRMInst(X86::IMUL16rm,FrameIndex, MI); + case X86::IMUL32rr: return MakeRMInst(X86::IMUL32rm,FrameIndex, MI); + case X86::IMUL16rri: return MakeRMIInst(X86::IMUL16rmi, FrameIndex, MI); + case X86::IMUL32rri: return MakeRMIInst(X86::IMUL32rmi, FrameIndex, MI); + case X86::CMP8rr: return MakeRMInst(X86::CMP8rm , FrameIndex, MI); + case X86::CMP16rr: return MakeRMInst(X86::CMP16rm, FrameIndex, MI); + case X86::CMP32rr: return MakeRMInst(X86::CMP32rm, FrameIndex, MI); + case X86::MOVSX16rr8:return MakeRMInst(X86::MOVSX16rm8 , FrameIndex, MI); + case X86::MOVSX32rr8:return MakeRMInst(X86::MOVSX32rm8, FrameIndex, MI); + case X86::MOVSX32rr16:return MakeRMInst(X86::MOVSX32rm16, FrameIndex, MI); + case X86::MOVZX16rr8:return MakeRMInst(X86::MOVZX16rm8 , FrameIndex, MI); + case X86::MOVZX32rr8: return MakeRMInst(X86::MOVZX32rm8, FrameIndex, MI); + case X86::MOVZX32rr16:return MakeRMInst(X86::MOVZX32rm16, FrameIndex, MI); } } - if (NI) { - MI = MBB.insert(MBB.erase(MI), NI); - return true; - } else { - if (PrintFailedFusing) - std::cerr << "We failed to fuse: " << *MI; - return false; - } + if (PrintFailedFusing) + std::cerr << "We failed to fuse: " << *MI; + return NULL; } //===----------------------------------------------------------------------===// @@ -431,7 +425,7 @@ // eliminates the need for add/sub ESP brackets around call sites. // NumBytes += MFI->getMaxCallFrameSize(); - + // Round the size to a multiple of the alignment (don't forget the 4 byte // offset though). unsigned Align = MF.getTarget().getFrameInfo().getStackAlignment(); @@ -462,7 +456,7 @@ // Get the offset of the stack slot for the EBP register... which is // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. int EBPOffset = MFI->getObjectOffset(MFI->getObjectIndexEnd()-1)+4; - + // mov ESP, EBP MI = BuildMI(X86::MOV32rr, 1,X86::ESP).addReg(X86::EBP); MBB.insert(MBBI, MI); @@ -498,7 +492,7 @@ case Type::IntTyID: case Type::UIntTyID: case Type::PointerTyID: return &R32Instance; - + case Type::FloatTyID: case Type::DoubleTyID: return &RFPInstance; } From alkis at cs.uiuc.edu Sun Mar 14 01:21:22 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Mar 14 01:21:22 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200403140720.BAA12312@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.39 -> 1.40 --- Log message: Change MRegisterInfo::foldMemoryOperand to return the folded instruction to make the API more flexible. --- Diffs of the changes: (+10 -9) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.39 llvm/include/llvm/Target/MRegisterInfo.h:1.40 --- llvm/include/llvm/Target/MRegisterInfo.h:1.39 Thu Feb 26 16:00:20 2004 +++ llvm/include/llvm/Target/MRegisterInfo.h Sun Mar 14 01:19:51 2004 @@ -253,15 +253,16 @@ const TargetRegisterClass *RC) const = 0; - /// foldMemoryOperand - If this target supports it, fold a load or store of - /// the specified stack slot into the specified machine instruction for the - /// specified operand. If this is possible, the target should perform the - /// folding and return true, otherwise it should return false. If it folds - /// the instruction, it is likely that the MachineInstruction the iterator - /// references has been changed. - virtual bool foldMemoryOperand(MachineBasicBlock::iterator &MI, - unsigned OpNum, int FrameIndex) const { - return false; + /// foldMemoryOperand - Attempt to fold a load or store of the + /// specified stack slot into the specified machine instruction for + /// the specified operand. If this is possible, a new instruction + /// is returned with the specified operand folded, otherwise NULL is + /// returned. The client is responsible for removing the old + /// instruction and adding the new one in the instruction stream + virtual MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, + unsigned OpNum, + int FrameIndex) const { + return NULL; } /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the From lattner at cs.uiuc.edu Sun Mar 14 13:28:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 13:28:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.cpp BugDriver.h CodeGeneratorBug.cpp ExtractFunction.cpp Miscompilation.cpp Message-ID: <200403141927.NAA06578@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.cpp updated: 1.29 -> 1.30 BugDriver.h updated: 1.30 -> 1.31 CodeGeneratorBug.cpp updated: 1.38 -> 1.39 ExtractFunction.cpp updated: 1.24 -> 1.25 Miscompilation.cpp updated: 1.28 -> 1.29 --- Log message: Refactor all of the "splitting a module into two pieces" code to avoid code duplication. Also, don't use ReduceMiscompilingFunctions::TestFuncs to print out the final message. --- Diffs of the changes: (+92 -129) Index: llvm/tools/bugpoint/BugDriver.cpp diff -u llvm/tools/bugpoint/BugDriver.cpp:1.29 llvm/tools/bugpoint/BugDriver.cpp:1.30 --- llvm/tools/bugpoint/BugDriver.cpp:1.29 Thu Feb 19 23:56:48 2004 +++ llvm/tools/bugpoint/BugDriver.cpp Sun Mar 14 13:27:19 2004 @@ -60,15 +60,6 @@ return Result; } -// DeleteFunctionBody - "Remove" the function by deleting all of its basic -// blocks, making it external. -// -void llvm::DeleteFunctionBody(Function *F) { - // delete the body of the function... - F->deleteBody(); - assert(F->isExternal() && "This didn't make the function external!"); -} - BugDriver::BugDriver(const char *toolname) : ToolName(toolname), ReferenceOutputFile(OutputFile), Program(0), Interpreter(0), cbe(0), gcc(0) {} Index: llvm/tools/bugpoint/BugDriver.h diff -u llvm/tools/bugpoint/BugDriver.h:1.30 llvm/tools/bugpoint/BugDriver.h:1.31 --- llvm/tools/bugpoint/BugDriver.h:1.30 Wed Feb 18 17:25:22 2004 +++ llvm/tools/bugpoint/BugDriver.h Sun Mar 14 13:27:19 2004 @@ -231,6 +231,11 @@ // void DeleteFunctionBody(Function *F); +/// SplitFunctionsOutOfModule - Given a module and a list of functions in the +/// module, split the functions OUT of the specified module, and place them in +/// the new module. +Module *SplitFunctionsOutOfModule(Module *M, const std::vector &F); + } // End llvm namespace #endif Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.38 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.39 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.38 Fri Mar 12 15:37:46 2004 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Sun Mar 14 13:27:19 2004 @@ -63,40 +63,15 @@ std::cout << "\t"; // Clone the module for the two halves of the program we want. - Module *SafeModule = CloneModule(BD.Program); + Module *SafeModule = CloneModule(BD.getProgram()); - // Make sure functions & globals are all external so that linkage - // between the two modules will work. - for (Module::iterator I = SafeModule->begin(), E = SafeModule->end();I!=E;++I) - I->setLinkage(GlobalValue::ExternalLinkage); - for (Module::giterator I=SafeModule->gbegin(),E = SafeModule->gend();I!=E;++I) - I->setLinkage(GlobalValue::ExternalLinkage); - - Module *TestModule = CloneModule(SafeModule); - - // Make sure global initializers exist only in the safe module (CBE->.so) - for (Module::giterator I=TestModule->gbegin(),E = TestModule->gend();I!=E;++I) - I->setInitializer(0); // Delete the initializer to make it external - - // Remove the Test functions from the Safe module - for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { - Function *TNOF = SafeModule->getFunction(Funcs[i]->getName(), - Funcs[i]->getFunctionType()); - DEBUG(std::cerr << "Removing function " << Funcs[i]->getName() << "\n"); - assert(TNOF && "Function doesn't exist in module!"); - DeleteFunctionBody(TNOF); // Function is now external in this module! - } - - // Remove the Safe functions from the Test module - for (Module::iterator I=TestModule->begin(),E=TestModule->end(); I!=E; ++I) { - bool funcFound = false; - for (std::vector::const_iterator F=Funcs.begin(),Fe=Funcs.end(); - F != Fe; ++F) - if (I->getName() == (*F)->getName()) funcFound = true; - - if (!funcFound && !(BD.isExecutingJIT() && I->getName() == "main")) - DeleteFunctionBody(I); + // The JIT must extract the 'main' function. + std::vector RealFuncs(Funcs); + if (BD.isExecutingJIT()) { + if (Function *F = BD.Program->getMainFunction()) + RealFuncs.push_back(F); } + Module *TestModule = SplitFunctionsOutOfModule(SafeModule, RealFuncs); // This is only applicable if we are debugging the JIT: // Find all external functions in the Safe modules that are actually used Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.24 llvm/tools/bugpoint/ExtractFunction.cpp:1.25 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.24 Sat Mar 13 13:35:54 2004 +++ llvm/tools/bugpoint/ExtractFunction.cpp Sun Mar 14 13:27:19 2004 @@ -24,6 +24,7 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Target/TargetData.h" #include "Support/CommandLine.h" +#include "Support/Debug.h" #include "Support/FileUtilities.h" using namespace llvm; @@ -128,4 +129,53 @@ removeFile(Filename); } return M; +} + + +// DeleteFunctionBody - "Remove" the function by deleting all of its basic +// blocks, making it external. +// +void llvm::DeleteFunctionBody(Function *F) { + // delete the body of the function... + F->deleteBody(); + assert(F->isExternal() && "This didn't make the function external!"); +} + +/// SplitFunctionsOutOfModule - Given a module and a list of functions in the +/// module, split the functions OUT of the specified module, and place them in +/// the new module. +Module *llvm::SplitFunctionsOutOfModule(Module *M, + const std::vector &F) { + // Make sure functions & globals are all external so that linkage + // between the two modules will work. + for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) + I->setLinkage(GlobalValue::ExternalLinkage); + for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + I->setLinkage(GlobalValue::ExternalLinkage); + + Module *New = CloneModule(M); + + // Make sure global initializers exist only in the safe module (CBE->.so) + for (Module::giterator I = New->gbegin(), E = New->gend(); I != E; ++I) + I->setInitializer(0); // Delete the initializer to make it external + + // Remove the Test functions from the Safe module + for (unsigned i = 0, e = F.size(); i != e; ++i) { + Function *TNOF = M->getFunction(F[i]->getName(), F[i]->getFunctionType()); + DEBUG(std::cerr << "Removing function " << F[i]->getName() << "\n"); + assert(TNOF && "Function doesn't exist in module!"); + DeleteFunctionBody(TNOF); // Function is now external in this module! + } + + // Remove the Safe functions from the Test module + for (Module::iterator I = New->begin(), E = New->end(); I != E; ++I) { + bool funcFound = false; + for (std::vector::const_iterator FI = F.begin(), Fe = F.end(); + FI != Fe; ++FI) + if (I->getName() == (*FI)->getName()) funcFound = true; + + if (!funcFound) + DeleteFunctionBody(I); + } + return New; } Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.28 llvm/tools/bugpoint/Miscompilation.cpp:1.29 --- llvm/tools/bugpoint/Miscompilation.cpp:1.28 Wed Feb 18 15:29:46 2004 +++ llvm/tools/bugpoint/Miscompilation.cpp Sun Mar 14 13:27:19 2004 @@ -132,93 +132,37 @@ virtual TestResult doTest(std::vector &Prefix, std::vector &Suffix) { - if (!Suffix.empty() && TestFuncs(Suffix, false)) + if (!Suffix.empty() && TestFuncs(Suffix)) return KeepSuffix; - if (!Prefix.empty() && TestFuncs(Prefix, false)) + if (!Prefix.empty() && TestFuncs(Prefix)) return KeepPrefix; return NoFailure; } - bool TestFuncs(const std::vector &Prefix, bool EmitBytecode); + bool TestFuncs(const std::vector &Prefix); }; } -bool ReduceMiscompilingFunctions::TestFuncs(const std::vector &Funcs, - bool EmitBytecode) { +bool ReduceMiscompilingFunctions::TestFuncs(const std::vector&Funcs){ // Test to see if the function is misoptimized if we ONLY run it on the // functions listed in Funcs. - if (!EmitBytecode) { - std::cout << "Checking to see if the program is misoptimized when " - << (Funcs.size()==1 ? "this function is" : "these functions are") - << " run through the pass" - << (BD.PassesToRun.size() == 1 ? "" : "es") << ": "; - BD.PrintFunctionList(Funcs); - std::cout << "\n"; - } else { - std::cout <<"Outputting reduced bytecode files which expose the problem:\n"; - } + std::cout << "Checking to see if the program is misoptimized when " + << (Funcs.size()==1 ? "this function is" : "these functions are") + << " run through the pass" + << (BD.PassesToRun.size() == 1 ? "" : "es") << ": "; + BD.PrintFunctionList(Funcs); + std::cout << "\n"; - // First step: clone the module for the two halves of the program we want. + // Split the module into the two halves of the program we want. Module *ToOptimize = CloneModule(BD.getProgram()); + Module *ToNotOptimize = SplitFunctionsOutOfModule(ToOptimize, Funcs); - // Second step: Make sure functions & globals are all external so that linkage - // between the two modules will work. - for (Module::iterator I = ToOptimize->begin(), E = ToOptimize->end();I!=E;++I) - I->setLinkage(GlobalValue::ExternalLinkage); - for (Module::giterator I = ToOptimize->gbegin(), E = ToOptimize->gend(); - I != E; ++I) - I->setLinkage(GlobalValue::ExternalLinkage); - - // Third step: make a clone of the externalized program for the non-optimized - // part. - Module *ToNotOptimize = CloneModule(ToOptimize); - - // Fourth step: Remove the test functions from the ToNotOptimize module, and - // all of the global variables. - for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { - Function *TNOF = ToNotOptimize->getFunction(Funcs[i]->getName(), - Funcs[i]->getFunctionType()); - assert(TNOF && "Function doesn't exist in module!"); - DeleteFunctionBody(TNOF); // Function is now external in this module! - } - for (Module::giterator I = ToNotOptimize->gbegin(), E = ToNotOptimize->gend(); - I != E; ++I) - I->setInitializer(0); // Delete the initializer to make it external - - if (EmitBytecode) { - std::cout << " Non-optimized portion: "; - std::swap(BD.Program, ToNotOptimize); - BD.EmitProgressBytecode("tonotoptimize", true); - std::swap(BD.Program, ToNotOptimize); - } - - // Fifth step: Remove all functions from the ToOptimize module EXCEPT for the - // ones specified in Funcs. We know which ones these are because they are - // non-external in ToOptimize, but external in ToNotOptimize. - // - for (Module::iterator I = ToOptimize->begin(), E = ToOptimize->end();I!=E;++I) - if (!I->isExternal()) { - Function *TNOF = ToNotOptimize->getFunction(I->getName(), - I->getFunctionType()); - assert(TNOF && "Function doesn't exist in ToNotOptimize module??"); - if (!TNOF->isExternal()) - DeleteFunctionBody(I); - } - - if (EmitBytecode) { - std::cout << " Portion that is input to optimizer: "; - std::swap(BD.Program, ToOptimize); - BD.EmitProgressBytecode("tooptimize"); - std::swap(BD.Program, ToOptimize); - } - - // Sixth step: Run the optimization passes on ToOptimize, producing a - // transformed version of the functions being tested. + // Run the optimization passes on ToOptimize, producing a transformed version + // of the functions being tested. Module *OldProgram = BD.Program; BD.Program = ToOptimize; - if (!EmitBytecode) - std::cout << " Optimizing functions being tested: "; + std::cout << " Optimizing functions being tested: "; std::string BytecodeResult; if (BD.runPasses(BD.PassesToRun, BytecodeResult, false/*delete*/, true/*quiet*/)) { @@ -228,17 +172,11 @@ exit(BD.debugOptimizerCrash()); } - if (!EmitBytecode) - std::cout << "done.\n"; + std::cout << "done.\n"; delete BD.getProgram(); // Delete the old "ToOptimize" module BD.Program = BD.ParseInputFile(BytecodeResult); - if (EmitBytecode) { - std::cout << " 'tooptimize' after being optimized: "; - BD.EmitProgressBytecode("optimized", true); - } - if (BD.Program == 0) { std::cerr << BD.getToolName() << ": Error reading bytecode file '" << BytecodeResult << "'!\n"; @@ -256,14 +194,6 @@ } delete ToNotOptimize; // We are done with this module... - if (EmitBytecode) { - std::cout << " Program as tested: "; - BD.EmitProgressBytecode("linked", true); - delete BD.Program; - BD.Program = OldProgram; - return false; // We don't need to actually execute the program here. - } - std::cout << " Checking to see if the merged program executes correctly: "; // Eighth step: Execute the program. If it does not match the expected @@ -277,7 +207,6 @@ return Broken; } - /// debugMiscompilation - This method is used when the passes selected are not /// crashing, but the generated output is semantically different from the /// input. @@ -314,7 +243,20 @@ std::cout << "\n"; // Output a bunch of bytecode files for the user... - ReduceMiscompilingFunctions(*this).TestFuncs(MiscompiledFunctions, true); + std::cout << "Outputting reduced bytecode files which expose the problem:\n"; + Module *ToOptimize = CloneModule(getProgram()); + Module *ToNotOptimize = SplitFunctionsOutOfModule(ToOptimize, + MiscompiledFunctions); + + std::cout << " Non-optimized portion: "; + std::swap(Program, ToNotOptimize); + EmitProgressBytecode("tonotoptimize", true); + setNewProgram(ToNotOptimize); // Delete hacked module. + + std::cout << " Portion that is input to optimizer: "; + std::swap(Program, ToOptimize); + EmitProgressBytecode("tooptimize"); + setNewProgram(ToOptimize); // Delete hacked module. return false; } From lattner at cs.uiuc.edu Sun Mar 14 13:32:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 13:32:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExtractFunction.cpp Message-ID: <200403141931.NAA06604@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExtractFunction.cpp updated: 1.25 -> 1.26 --- Log message: add a fixme --- Diffs of the changes: (+5 -0) Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.25 llvm/tools/bugpoint/ExtractFunction.cpp:1.26 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.25 Sun Mar 14 13:27:19 2004 +++ llvm/tools/bugpoint/ExtractFunction.cpp Sun Mar 14 13:31:00 2004 @@ -144,6 +144,11 @@ /// SplitFunctionsOutOfModule - Given a module and a list of functions in the /// module, split the functions OUT of the specified module, and place them in /// the new module. +/// +/// FIXME: this could be made DRAMATICALLY more efficient for large programs if +/// we just MOVED functions from one module to the other, instead of cloning the +/// whole module, then proceeding to delete an entire module's worth of stuff. +/// Module *llvm::SplitFunctionsOutOfModule(Module *M, const std::vector &F) { // Make sure functions & globals are all external so that linkage From lattner at cs.uiuc.edu Sun Mar 14 14:01:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 14:01:00 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/IPO.h Message-ID: <200403142000.OAA13587@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.29 -> 1.30 --- Log message: Rename createLoopExtractorPass to createSingleLoopExtractorPass Doxygenify --- Diffs of the changes: (+64 -63) Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.29 llvm/include/llvm/Transforms/IPO.h:1.30 --- llvm/include/llvm/Transforms/IPO.h:1.29 Sat Mar 13 20:36:34 2004 +++ llvm/include/llvm/Transforms/IPO.h Sun Mar 14 14:00:37 2004 @@ -21,126 +21,127 @@ class Function; //===----------------------------------------------------------------------===// -// createLowerSetJmpPass - This function lowers the setjmp/longjmp intrinsics to -// invoke/unwind instructions. This should really be part of the C/C++ -// front-end, but it's so much easier to write transformations in LLVM proper. -// +/// createLowerSetJmpPass - This function lowers the setjmp/longjmp intrinsics +/// to invoke/unwind instructions. This should really be part of the C/C++ +/// front-end, but it's so much easier to write transformations in LLVM proper. +/// Pass* createLowerSetJmpPass(); //===----------------------------------------------------------------------===// -// createConstantMergePass - This function returns a new 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. -// +/// createConstantMergePass - This function returns a new 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. +/// Pass *createConstantMergePass(); //===----------------------------------------------------------------------===// -// createGlobalConstifierPass - This function returns a new pass that marks -// internal globals "constant" if they are provably never written to. -// +/// createGlobalConstifierPass - This function returns a new pass that marks +/// internal globals "constant" if they are provably never written to. +/// Pass *createGlobalConstifierPass(); //===----------------------------------------------------------------------===// -// createRaiseAllocationsPass - Return a new pass that transforms malloc and -// free function calls into malloc and free instructions. -// +/// createRaiseAllocationsPass - Return a new pass that transforms malloc and +/// free function calls into malloc and free instructions. +/// Pass *createRaiseAllocationsPass(); //===----------------------------------------------------------------------===// -// createDeadTypeEliminationPass - Return a new pass that eliminates symbol -// table entries for types that are never used. -// +/// createDeadTypeEliminationPass - Return a new pass that eliminates symbol +/// table entries for types that are never used. +/// Pass *createDeadTypeEliminationPass(); //===----------------------------------------------------------------------===// -// createGlobalDCEPass - This transform is designed to eliminate unreachable -// internal globals (functions or global variables) -// +/// createGlobalDCEPass - This transform is designed to eliminate unreachable +/// internal globals (functions or global variables) +/// Pass *createGlobalDCEPass(); //===----------------------------------------------------------------------===// -// createFunctionExtractionPass - This pass deletes as much of the module as -// possible, except for the function specified. -// +/// createFunctionExtractionPass - This pass deletes as much of the module as +/// possible, except for the function specified. +/// Pass *createFunctionExtractionPass(Function *F); //===----------------------------------------------------------------------===// -// FunctionResolvingPass - Go over the functions that are in the module and -// look for functions that have the same name. More often than not, there will -// be things like: -// void "foo"(...) -// void "foo"(int, int) -// because of the way things are declared in C. If this is the case, patch -// things up. -// -// This is an interprocedural pass. -// +/// FunctionResolvingPass - Go over the functions that are in the module and +/// look for functions that have the same name. More often than not, there will +/// be things like: +/// void "foo"(...) +/// void "foo"(int, int) +/// because of the way things are declared in C. If this is the case, patch +/// things up. +/// +/// This is an interprocedural pass. +/// Pass *createFunctionResolvingPass(); //===----------------------------------------------------------------------===// -// createFunctionInliningPass - Return a new pass object that uses a heuristic -// to inline direct function calls to small functions. -// +/// createFunctionInliningPass - Return a new pass object that uses a heuristic +/// to inline direct function calls to small functions. +/// Pass *createFunctionInliningPass(); //===----------------------------------------------------------------------===// -// createPruneEHPass - Return a new pass object which transforms invoke -// instructions into calls, if the callee can _not_ unwind the stack. -// +/// createPruneEHPass - Return a new pass object which transforms invoke +/// instructions into calls, if the callee can _not_ unwind the stack. +/// Pass *createPruneEHPass(); //===----------------------------------------------------------------------===// -// createInternalizePass - This pass loops over all of the functions in the -// input module, looking for a main function. If a main function is found, all -// other functions are marked as internal. -// +/// createInternalizePass - This pass loops over all of the functions in the +/// input module, looking for a main function. If a main function is found, all +/// other functions are marked as internal. +/// Pass *createInternalizePass(); //===----------------------------------------------------------------------===// -// createDeadArgEliminationPass - This pass removes arguments from functions -// which are not used by the body of the function. -// +/// createDeadArgEliminationPass - This pass removes arguments from functions +/// which are not used by the body of the function. +/// Pass *createDeadArgEliminationPass(); -// DeadArgHacking pass - Same as DAE, but delete arguments of external functions -// as well. This is definitely not safe, and should only be used by bugpoint. +/// DeadArgHacking pass - Same as DAE, but delete arguments of external +/// functions as well. This is definitely not safe, and should only be used by +/// bugpoint. Pass *createDeadArgHackingPass(); //===----------------------------------------------------------------------===// -// createArgumentPromotionPass - This pass promotes "by reference" arguments to -// be passed by value. -// +/// createArgumentPromotionPass - This pass promotes "by reference" arguments to +/// be passed by value. +/// Pass *createArgumentPromotionPass(); //===----------------------------------------------------------------------===// -// createIPConstantPropagationPass - This pass propagates constants from call -// sites into the bodies of functions. -// +/// createIPConstantPropagationPass - This pass propagates constants from call +/// sites into the bodies of functions. +/// Pass *createIPConstantPropagationPass(); //===----------------------------------------------------------------------===// -// These passes are wrappers that can do a few simple structure mutation -// transformations. -// +/// These passes are wrappers that can do a few simple structure mutation +/// transformations. +/// Pass *createSwapElementsPass(); Pass *createSortElementsPass(); //===----------------------------------------------------------------------===// // -// LoopExtractor - This pass moves every natural loop into its own function. -// Mostly useful in debugging via bugpoint. -// -Pass *createLoopExtractorPass(); +/// createSingleLoopExtractorPass - This pass extracts one natural loop from the +/// program into a function if it can. This is used by bugpoint. +/// +Pass *createSingleLoopExtractorPass(); } // End llvm namespace From lattner at cs.uiuc.edu Sun Mar 14 14:02:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 14:02:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/LoopExtractor.cpp Message-ID: <200403142001.OAA13608@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: LoopExtractor.cpp updated: 1.5 -> 1.6 --- Log message: Split into two passes. Now there is the general loop extractor, usable on the command line, and the single loop extractor, usable by bugpoint --- Diffs of the changes: (+24 -6) Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp diff -u llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.5 llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.6 --- llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.5 Sat Mar 13 22:17:53 2004 +++ llvm/lib/Transforms/IPO/LoopExtractor.cpp Sun Mar 14 14:01:36 2004 @@ -23,8 +23,14 @@ using namespace llvm; namespace { - // FIXME: PassManager should allow Module passes to require FunctionPasses + // FIXME: This is not a function pass, but the PassManager doesn't allow + // Module passes to require FunctionPasses, so we can't get loop info if we're + // not a function pass. struct LoopExtractor : public FunctionPass { + unsigned NumLoops; + + LoopExtractor(unsigned numLoops = ~0) : NumLoops(numLoops) {} + virtual bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -35,6 +41,14 @@ RegisterOpt X("loop-extract", "Extract loops into new functions"); + + /// SingleLoopExtractor - For bugpoint. + struct SingleLoopExtractor : public LoopExtractor { + SingleLoopExtractor() : LoopExtractor(1) {} + }; + + RegisterOpt + Y("loop-extract-single", "Extract at most one loop into a new function"); } // End anonymous namespace bool LoopExtractor::runOnFunction(Function &F) { @@ -47,14 +61,18 @@ bool Changed = false; // Try to move each loop out of the code into separate function - for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; ++i) + for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; ++i) { + if (NumLoops == 0) return Changed; + --NumLoops; Changed |= (ExtractLoop(*i) != 0); + } return Changed; } -/// createLoopExtractorPass -/// -Pass* llvm::createLoopExtractorPass() { - return new LoopExtractor(); +// createSingleLoopExtractorPass - This pass extracts one natural loop from the +// program into a function if it can. This is used by bugpoint. +// +Pass *llvm::createSingleLoopExtractorPass() { + return new SingleLoopExtractor(); } From lattner at cs.uiuc.edu Sun Mar 14 14:03:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 14:03:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExtractFunction.cpp BugDriver.h Message-ID: <200403142002.OAA13621@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExtractFunction.cpp updated: 1.26 -> 1.27 BugDriver.h updated: 1.31 -> 1.32 --- Log message: Add a method to extract a loop --- Diffs of the changes: (+42 -1) Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.26 llvm/tools/bugpoint/ExtractFunction.cpp:1.27 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.26 Sun Mar 14 13:31:00 2004 +++ llvm/tools/bugpoint/ExtractFunction.cpp Sun Mar 14 14:02:07 2004 @@ -117,7 +117,7 @@ std::swap(Program, M); if (Failed) { - std::cerr << "Final cleanups failed. Sorry. :(\n"; + std::cerr << "Final cleanups failed. Sorry. :( Please report a bug!\n"; } else { delete M; M = ParseInputFile(Filename); @@ -129,6 +129,42 @@ removeFile(Filename); } return M; +} + + +/// ExtractLoop - Given a module, extract up to one loop from it into a new +/// function. This returns null if there are no extractable loops in the +/// program or if the loop extractor crashes. +Module *BugDriver::ExtractLoop(Module *M) { + std::vector LoopExtractPasses; + LoopExtractPasses.push_back(getPI(createSingleLoopExtractorPass())); + + std::swap(Program, M); + std::string Filename; + bool Failed = runPasses(LoopExtractPasses, Filename); + std::swap(Program, M); + + if (Failed) { + std::cerr << "Loop extraction failed. Sorry. :( Please report a bug!\n"; + return 0; + } else { + Module *NewM = ParseInputFile(Filename); + if (NewM == 0) { + std::cerr << getToolName() << ": Error reading bytecode file '" + << Filename << "'!\n"; + exit(1); + } + removeFile(Filename); + + // Check to see if we created any new functions. If not, no loops were + // extracted and we should return null. + if (M->size() != NewM->size()) { + delete NewM; + return 0; + } + + return NewM; + } } Index: llvm/tools/bugpoint/BugDriver.h diff -u llvm/tools/bugpoint/BugDriver.h:1.31 llvm/tools/bugpoint/BugDriver.h:1.32 --- llvm/tools/bugpoint/BugDriver.h:1.31 Sun Mar 14 13:27:19 2004 +++ llvm/tools/bugpoint/BugDriver.h Sun Mar 14 14:02:07 2004 @@ -178,6 +178,11 @@ /// Module *performFinalCleanups(Module *M, bool MayModifySemantics = false); + /// ExtractLoop - Given a module, extract up to one loop from it into a new + /// function. This returns null if there are no extractable loops in the + /// program or if the loop extractor crashes. + Module *ExtractLoop(Module *M); + private: /// ParseInputFile - Given a bytecode or assembly input filename, parse and /// return it, or return null if not possible. From alkis at cs.uiuc.edu Sun Mar 14 14:15:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Mar 14 14:15:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.h X86RegisterInfo.cpp Message-ID: <200403142014.OAA14762@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.h updated: 1.24 -> 1.25 X86RegisterInfo.cpp updated: 1.77 -> 1.78 --- Log message: Another API change to MRegisterInfo::foldMemoryOperand. Instead of a MachineBasicBlock::iterator take a MachineInstr*. --- Diffs of the changes: (+4 -5) Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.24 llvm/lib/Target/X86/X86RegisterInfo.h:1.25 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.24 Sun Mar 14 01:19:51 2004 +++ llvm/lib/Target/X86/X86RegisterInfo.h Sun Mar 14 14:14:27 2004 @@ -48,7 +48,7 @@ /// folding and return true, otherwise it should return false. If it folds /// the instruction, it is likely that the MachineInstruction the iterator /// references has been changed. - virtual MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FrameIndex) const; Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.77 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.78 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.77 Sun Mar 14 01:19:51 2004 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Sun Mar 14 14:14:27 2004 @@ -132,10 +132,9 @@ } -MachineInstr* X86RegisterInfo::foldMemoryOperand( - MachineBasicBlock::iterator MI, - unsigned i, - int FrameIndex) const { +MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr* MI, + unsigned i, + int FrameIndex) const { if (NoFusing) return NULL; /// FIXME: This should obviously be autogenerated by tablegen when patterns From alkis at cs.uiuc.edu Sun Mar 14 14:15:13 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Mar 14 14:15:13 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200403142014.OAA14769@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.40 -> 1.41 --- Log message: Another API change to MRegisterInfo::foldMemoryOperand. Instead of a MachineBasicBlock::iterator take a MachineInstr*. --- Diffs of the changes: (+1 -1) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.40 llvm/include/llvm/Target/MRegisterInfo.h:1.41 --- llvm/include/llvm/Target/MRegisterInfo.h:1.40 Sun Mar 14 01:19:51 2004 +++ llvm/include/llvm/Target/MRegisterInfo.h Sun Mar 14 14:14:27 2004 @@ -259,7 +259,7 @@ /// is returned with the specified operand folded, otherwise NULL is /// returned. The client is responsible for removing the old /// instruction and adding the new one in the instruction stream - virtual MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FrameIndex) const { return NULL; From lattner at cs.uiuc.edu Sun Mar 14 14:51:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 14:51:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.cpp BugDriver.h CodeGeneratorBug.cpp CrashDebugger.cpp ExtractFunction.cpp Miscompilation.cpp Message-ID: <200403142050.OAA25402@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.cpp updated: 1.30 -> 1.31 BugDriver.h updated: 1.32 -> 1.33 CodeGeneratorBug.cpp updated: 1.39 -> 1.40 CrashDebugger.cpp updated: 1.33 -> 1.34 ExtractFunction.cpp updated: 1.27 -> 1.28 Miscompilation.cpp updated: 1.29 -> 1.30 --- Log message: Refactor and clean up a bunch more code. No major functionality changes. * Make several methods of bugdriver global functions (ParseInputFile, PrintFunctionList) * Make PrintFunctionList truncate the output after 10 entries, like the crash debugger did. This allows code sharing. * Add a couple of methods to BugDriver that allows us to eliminate some friends * Improve comments in ExtractFunction.cpp * Make classes that used to be friends up bugdriver now live in anon namespaces * Rip a bunch of functionality in the miscompilation tester into a new TestMergedProgram function for future code sharing. * Fix a bug in the miscompilation tester induced in my last checkin --- Diffs of the changes: (+98 -89) Index: llvm/tools/bugpoint/BugDriver.cpp diff -u llvm/tools/bugpoint/BugDriver.cpp:1.30 llvm/tools/bugpoint/BugDriver.cpp:1.31 --- llvm/tools/bugpoint/BugDriver.cpp:1.30 Sun Mar 14 13:27:19 2004 +++ llvm/tools/bugpoint/BugDriver.cpp Sun Mar 14 14:50:42 2004 @@ -68,16 +68,16 @@ /// ParseInputFile - Given a bytecode or assembly input filename, parse and /// return it, or return null if not possible. /// -Module *BugDriver::ParseInputFile(const std::string &InputFilename) const { +Module *llvm::ParseInputFile(const std::string &InputFilename) { Module *Result = 0; try { Result = ParseBytecodeFile(InputFilename); if (!Result && !(Result = ParseAssemblyFile(InputFilename))){ - std::cerr << ToolName << ": could not read input file '" + std::cerr << "bugpoint: could not read input file '" << InputFilename << "'!\n"; } } catch (const ParseException &E) { - std::cerr << ToolName << ": " << E.getMessage() << "\n"; + std::cerr << "bugpoint: " << E.getMessage() << "\n"; Result = 0; } return Result; @@ -199,11 +199,12 @@ } } -void BugDriver::PrintFunctionList(const std::vector &Funcs) { - for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { - if (i) std::cout << ", "; - std::cout << Funcs[i]->getName(); - } +void llvm::PrintFunctionList(const std::vector &Funcs) { + unsigned NumPrint = Funcs.size(); + if (NumPrint > 10) NumPrint = 10; + for (unsigned i = 0; i != NumPrint; ++i) + std::cout << " " << Funcs[i]->getName(); + if (NumPrint < Funcs.size()) + std::cout << "... <" << Funcs.size() << " total>"; std::cout << std::flush; } - Index: llvm/tools/bugpoint/BugDriver.h diff -u llvm/tools/bugpoint/BugDriver.h:1.32 llvm/tools/bugpoint/BugDriver.h:1.33 --- llvm/tools/bugpoint/BugDriver.h:1.32 Sun Mar 14 14:02:07 2004 +++ llvm/tools/bugpoint/BugDriver.h Sun Mar 14 14:50:42 2004 @@ -28,8 +28,6 @@ class Instruction; class DebugCrashes; -class ReduceMiscompilingPasses; -class ReduceMiscompilingFunctions; class CBE; class GCC; @@ -47,8 +45,6 @@ // FIXME: sort out public/private distinctions... friend class ReducePassList; - friend class ReduceMiscompilingPasses; - friend class ReduceMiscompilingFunctions; friend class ReduceMisCodegenFunctions; public: @@ -65,6 +61,9 @@ void setPassesToRun(const std::vector &PTR) { PassesToRun = PTR; } + const std::vector &getPassesToRun() const { + return PassesToRun; + } /// run - The top level method that is invoked after all of the instance /// variables are set up from command line arguments. @@ -120,7 +119,15 @@ return Result; } - const Module *getProgram() const { return Program; } + Module *getProgram() const { return Program; } + + /// swapProgramIn - Set the current module to the specified module, returning + /// the old one. + Module *swapProgramIn(Module *M) { + Module *OldProgram = Program; + Program = M; + return OldProgram; + } /// setNewProgram - If we reduce or update the program somehow, call this /// method to update bugdriver with it. This deletes the old module and sets @@ -183,17 +190,6 @@ /// program or if the loop extractor crashes. Module *ExtractLoop(Module *M); -private: - /// ParseInputFile - Given a bytecode or assembly input filename, parse and - /// return it, or return null if not possible. - /// - Module *ParseInputFile(const std::string &InputFilename) const; - - /// writeProgramToFile - This writes the current "Program" to the named - /// bytecode file. If an error occurs, true is returned. - /// - bool writeProgramToFile(const std::string &Filename, Module *M = 0) const; - /// runPasses - Run the specified passes on Program, outputting a bytecode /// file and writting the filename into OutputFile if successful. If the /// optimizations fail for some reason (optimizer crashes), return true, @@ -205,6 +201,11 @@ bool runPasses(const std::vector &PassesToRun, std::string &OutputFilename, bool DeleteOutput = false, bool Quiet = false) const; +private: + /// writeProgramToFile - This writes the current "Program" to the named + /// bytecode file. If an error occurs, true is returned. + /// + bool writeProgramToFile(const std::string &Filename, Module *M = 0) const; /// runPasses - Just like the method above, but this just returns true or /// false indicating whether or not the optimizer crashed on the specified @@ -216,20 +217,26 @@ return runPasses(PassesToRun, Filename, DeleteOutput); } - /// PrintFunctionList - prints out list of problematic functions - /// - static void PrintFunctionList(const std::vector &Funcs); - /// initializeExecutionEnvironment - This method is used to set up the /// environment for executing LLVM programs. /// bool initializeExecutionEnvironment(); }; +/// ParseInputFile - Given a bytecode or assembly input filename, parse and +/// return it, or return null if not possible. +/// +Module *ParseInputFile(const std::string &InputFilename); + + /// getPassesString - Turn a list of passes into a string which indicates the /// command line options that must be passed to add the passes. /// std::string getPassesString(const std::vector &Passes); + +/// PrintFunctionList - prints out list of problematic functions +/// +void PrintFunctionList(const std::vector &Funcs); // DeleteFunctionBody - "Remove" the function by deleting all of it's basic // blocks, making it external. Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.39 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.40 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.39 Sun Mar 14 13:27:19 2004 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Sun Mar 14 14:50:42 2004 @@ -59,7 +59,7 @@ bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, bool KeepFiles) { std::cout << "Testing functions: "; - BD.PrintFunctionList(Funcs); + PrintFunctionList(Funcs); std::cout << "\t"; // Clone the module for the two halves of the program we want. Index: llvm/tools/bugpoint/CrashDebugger.cpp diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.33 llvm/tools/bugpoint/CrashDebugger.cpp:1.34 --- llvm/tools/bugpoint/CrashDebugger.cpp:1.33 Sat Mar 13 13:35:54 2004 +++ llvm/tools/bugpoint/CrashDebugger.cpp Sun Mar 14 14:50:42 2004 @@ -59,7 +59,7 @@ OrigProgram = BD.Program; - BD.Program = BD.ParseInputFile(PrefixOutput); + BD.Program = ParseInputFile(PrefixOutput); if (BD.Program == 0) { std::cerr << BD.getToolName() << ": Error reading bytecode file '" << PrefixOutput << "'!\n"; @@ -85,7 +85,7 @@ } namespace llvm { - class ReduceCrashingFunctions : public ListReducer { + class ReduceCrashingFunctions : public ListReducer { BugDriver &BD; bool (*TestFn)(BugDriver &, Module *); public: @@ -93,8 +93,8 @@ bool (*testFn)(BugDriver &, Module *)) : BD(bd), TestFn(testFn) {} - virtual TestResult doTest(std::vector &Prefix, - std::vector &Kept) { + virtual TestResult doTest(std::vector &Prefix, + std::vector &Kept) { if (!Kept.empty() && TestFuncs(Kept)) return KeepSuffix; if (!Prefix.empty() && TestFuncs(Prefix)) @@ -102,11 +102,11 @@ return NoFailure; } - bool TestFuncs(std::vector &Prefix); + bool TestFuncs(std::vector &Prefix); }; } -bool ReduceCrashingFunctions::TestFuncs(std::vector &Funcs) { +bool ReduceCrashingFunctions::TestFuncs(std::vector &Funcs) { // Clone the program to try hacking it apart... Module *M = CloneModule(BD.getProgram()); @@ -119,13 +119,8 @@ Functions.insert(CMF); } - std::cout << "Checking for crash with only these functions:"; - unsigned NumPrint = Funcs.size(); - if (NumPrint > 10) NumPrint = 10; - for (unsigned i = 0; i != NumPrint; ++i) - std::cout << " " << Funcs[i]->getName(); - if (NumPrint < Funcs.size()) - std::cout << "... <" << Funcs.size() << " total>"; + std::cout << "Checking for crash with only these functions: "; + PrintFunctionList(Funcs); std::cout << ": "; // Loop over and delete any functions which we aren't supposed to be playing @@ -295,8 +290,8 @@ } // Now try to reduce the number of functions in the module to something small. - std::vector Functions; - for (Module::const_iterator I = BD.getProgram()->begin(), + std::vector Functions; + for (Module::iterator I = BD.getProgram()->begin(), E = BD.getProgram()->end(); I != E; ++I) if (!I->isExternal()) Functions.push_back(I); Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.27 llvm/tools/bugpoint/ExtractFunction.cpp:1.28 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.27 Sun Mar 14 14:02:07 2004 +++ llvm/tools/bugpoint/ExtractFunction.cpp Sun Mar 14 14:50:42 2004 @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file implements a method that extracts a function from program, cleans -// it up, and returns it as a new module. +// This file implements several methods that are used to extract functions, +// loops, or portions of a module from the rest of the module. // //===----------------------------------------------------------------------===// @@ -76,6 +76,8 @@ // Make sure that the appropriate target data is always used... Passes.add(new TargetData("bugpoint", Result)); + /// FIXME: If this used runPasses() like the methods below, we could get rid + /// of the -disable-* options! if (Simplification > 1 && !NoDCE) Passes.add(createDeadCodeEliminationPass()); if (Simplification && !DisableSimplifyCFG) Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.29 llvm/tools/bugpoint/Miscompilation.cpp:1.30 --- llvm/tools/bugpoint/Miscompilation.cpp:1.29 Sun Mar 14 13:27:19 2004 +++ llvm/tools/bugpoint/Miscompilation.cpp Sun Mar 14 14:50:42 2004 @@ -20,8 +20,7 @@ #include "Support/FileUtilities.h" using namespace llvm; -namespace llvm { - +namespace { class ReduceMiscompilingPasses : public ListReducer { BugDriver &BD; public: @@ -88,7 +87,7 @@ // Ok, so now we know that the prefix passes work, try running the suffix // passes on the result of the prefix passes. // - Module *PrefixOutput = BD.ParseInputFile(BytecodeResult); + Module *PrefixOutput = ParseInputFile(BytecodeResult); if (PrefixOutput == 0) { std::cerr << BD.getToolName() << ": Error reading bytecode file '" << BytecodeResult << "'!\n"; @@ -100,8 +99,7 @@ << "' passes compile correctly after the '" << getPassesString(Prefix) << "' passes: "; - Module *OriginalInput = BD.Program; - BD.Program = PrefixOutput; + Module *OriginalInput = BD.swapProgramIn(PrefixOutput); if (BD.runPasses(Suffix, BytecodeResult, false/*delete*/, true/*quiet*/)) { std::cerr << " Error running this sequence of passes" << " on the input program!\n"; @@ -119,12 +117,11 @@ // Otherwise, we must not be running the bad pass anymore. std::cout << "yup.\n"; // No miscompilation! - BD.Program = OriginalInput; // Restore original program - delete PrefixOutput; // Free experiment + delete BD.swapProgramIn(OriginalInput); // Restore orig program & free test return NoFailure; } -namespace llvm { +namespace { class ReduceMiscompilingFunctions : public ListReducer { BugDriver &BD; public: @@ -143,28 +140,52 @@ }; } +/// TestMergedProgram - Given two modules, link them together and run the +/// program, checking to see if the program matches the diff. If the diff +/// matches, return false, otherwise return true. In either case, we delete +/// both input modules before we return. +static bool TestMergedProgram(BugDriver &BD, Module *M1, Module *M2) { + // Link the two portions of the program back to together. + std::string ErrorMsg; + if (LinkModules(M1, M2, &ErrorMsg)) { + std::cerr << BD.getToolName() << ": Error linking modules together:" + << ErrorMsg << "\n"; + exit(1); + } + delete M2; // We are done with this module... + + Module *OldProgram = BD.swapProgramIn(M1); + + // Execute the program. If it does not match the expected output, we must + // return true. + bool Broken = BD.diffProgram(); + + // Delete the linked module & restore the original + delete BD.swapProgramIn(OldProgram); + return Broken; +} + bool ReduceMiscompilingFunctions::TestFuncs(const std::vector&Funcs){ // Test to see if the function is misoptimized if we ONLY run it on the // functions listed in Funcs. std::cout << "Checking to see if the program is misoptimized when " << (Funcs.size()==1 ? "this function is" : "these functions are") << " run through the pass" - << (BD.PassesToRun.size() == 1 ? "" : "es") << ": "; - BD.PrintFunctionList(Funcs); + << (BD.getPassesToRun().size() == 1 ? "" : "es") << ": "; + PrintFunctionList(Funcs); std::cout << "\n"; // Split the module into the two halves of the program we want. - Module *ToOptimize = CloneModule(BD.getProgram()); - Module *ToNotOptimize = SplitFunctionsOutOfModule(ToOptimize, Funcs); + Module *ToNotOptimize = CloneModule(BD.getProgram()); + Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, Funcs); // Run the optimization passes on ToOptimize, producing a transformed version // of the functions being tested. - Module *OldProgram = BD.Program; - BD.Program = ToOptimize; + Module *OldProgram = BD.swapProgramIn(ToOptimize); std::cout << " Optimizing functions being tested: "; std::string BytecodeResult; - if (BD.runPasses(BD.PassesToRun, BytecodeResult, false/*delete*/, + if (BD.runPasses(BD.getPassesToRun(), BytecodeResult, false/*delete*/, true/*quiet*/)) { std::cerr << " Error running this sequence of passes" << " on the input program!\n"; @@ -174,35 +195,18 @@ std::cout << "done.\n"; - delete BD.getProgram(); // Delete the old "ToOptimize" module - BD.Program = BD.ParseInputFile(BytecodeResult); - - if (BD.Program == 0) { + // Delete the old "ToOptimize" module + delete BD.swapProgramIn(OldProgram); + Module *Optimized = ParseInputFile(BytecodeResult); + if (Optimized == 0) { std::cerr << BD.getToolName() << ": Error reading bytecode file '" << BytecodeResult << "'!\n"; exit(1); } removeFile(BytecodeResult); // No longer need the file on disk - // Seventh step: Link the optimized part of the program back to the - // unoptimized part of the program. - // - if (LinkModules(BD.Program, ToNotOptimize, &BytecodeResult)) { - std::cerr << BD.getToolName() << ": Error linking modules together:" - << BytecodeResult << "\n"; - exit(1); - } - delete ToNotOptimize; // We are done with this module... - std::cout << " Checking to see if the merged program executes correctly: "; - - // Eighth step: Execute the program. If it does not match the expected - // output, then 'Funcs' are being misoptimized! - bool Broken = BD.diffProgram(); - - delete BD.Program; // Delete the hacked up program - BD.Program = OldProgram; // Restore the original - + bool Broken = TestMergedProgram(BD, Optimized, ToNotOptimize); std::cout << (Broken ? " nope.\n" : " yup.\n"); return Broken; } @@ -220,8 +224,8 @@ } std::cout << "\n*** Found miscompiling pass" - << (PassesToRun.size() == 1 ? "" : "es") << ": " - << getPassesString(PassesToRun) << "\n"; + << (getPassesToRun().size() == 1 ? "" : "es") << ": " + << getPassesString(getPassesToRun()) << "\n"; EmitProgressBytecode("passinput"); // Okay, now that we have reduced the list of passes which are causing the @@ -244,9 +248,9 @@ // Output a bunch of bytecode files for the user... std::cout << "Outputting reduced bytecode files which expose the problem:\n"; - Module *ToOptimize = CloneModule(getProgram()); - Module *ToNotOptimize = SplitFunctionsOutOfModule(ToOptimize, - MiscompiledFunctions); + Module *ToNotOptimize = CloneModule(getProgram()); + Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, + MiscompiledFunctions); std::cout << " Non-optimized portion: "; std::swap(Program, ToNotOptimize); From lattner at cs.uiuc.edu Sun Mar 14 15:18:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 15:18:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.h OptimizerDriver.cpp Message-ID: <200403142117.PAA27356@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.h updated: 1.33 -> 1.34 OptimizerDriver.cpp updated: 1.18 -> 1.19 --- Log message: Add new method --- Diffs of the changes: (+28 -0) Index: llvm/tools/bugpoint/BugDriver.h diff -u llvm/tools/bugpoint/BugDriver.h:1.33 llvm/tools/bugpoint/BugDriver.h:1.34 --- llvm/tools/bugpoint/BugDriver.h:1.33 Sun Mar 14 14:50:42 2004 +++ llvm/tools/bugpoint/BugDriver.h Sun Mar 14 15:17:03 2004 @@ -190,6 +190,11 @@ /// program or if the loop extractor crashes. Module *ExtractLoop(Module *M); + /// runPassesOn - Carefully run the specified set of pass on the specified + /// module, returning the transformed module on success, or a null pointer on + /// failure. + Module *runPassesOn(Module *M, const std::vector &Passes); + /// runPasses - Run the specified passes on Program, outputting a bytecode /// file and writting the filename into OutputFile if successful. If the /// optimizations fail for some reason (optimizer crashes), return true, Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.18 llvm/tools/bugpoint/OptimizerDriver.cpp:1.19 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.18 Wed Feb 18 17:24:56 2004 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Sun Mar 14 15:17:03 2004 @@ -161,3 +161,26 @@ return !ExitedOK; } + +/// runPassesOn - Carefully run the specified set of pass on the specified +/// module, returning the transformed module on success, or a null pointer on +/// failure. +Module *BugDriver::runPassesOn(Module *M, + const std::vector &Passes) { + Module *OldProgram = swapProgramIn(M); + std::string BytecodeResult; + if (runPasses(Passes, BytecodeResult, false/*delete*/, true/*quiet*/)) + return 0; + + // Restore the current program. + swapProgramIn(OldProgram); + + Module *Ret = ParseInputFile(BytecodeResult); + if (Ret == 0) { + std::cerr << getToolName() << ": Error reading bytecode file '" + << BytecodeResult << "'!\n"; + exit(1); + } + removeFile(BytecodeResult); // No longer need the file on disk + return Ret; +} From lattner at cs.uiuc.edu Sun Mar 14 15:18:12 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 15:18:12 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExtractFunction.cpp Message-ID: <200403142117.PAA27369@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExtractFunction.cpp updated: 1.28 -> 1.29 --- Log message: Refactor to use a new method --- Diffs of the changes: (+14 -38) Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.28 llvm/tools/bugpoint/ExtractFunction.cpp:1.29 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.28 Sun Mar 14 14:50:42 2004 +++ llvm/tools/bugpoint/ExtractFunction.cpp Sun Mar 14 15:17:22 2004 @@ -112,25 +112,13 @@ CleanupPasses.push_back(getPI(createDeadArgHackingPass())); else CleanupPasses.push_back(getPI(createDeadArgEliminationPass())); - - std::swap(Program, M); - std::string Filename; - bool Failed = runPasses(CleanupPasses, Filename); - std::swap(Program, M); - if (Failed) { + Module *New = runPassesOn(M, CleanupPasses); + if (New == 0) { std::cerr << "Final cleanups failed. Sorry. :( Please report a bug!\n"; - } else { - delete M; - M = ParseInputFile(Filename); - if (M == 0) { - std::cerr << getToolName() << ": Error reading bytecode file '" - << Filename << "'!\n"; - exit(1); - } - removeFile(Filename); } - return M; + delete M; + return New; } @@ -141,32 +129,20 @@ std::vector LoopExtractPasses; LoopExtractPasses.push_back(getPI(createSingleLoopExtractorPass())); - std::swap(Program, M); - std::string Filename; - bool Failed = runPasses(LoopExtractPasses, Filename); - std::swap(Program, M); - - if (Failed) { + Module *NewM = runPassesOn(M, LoopExtractPasses); + if (NewM == 0) { std::cerr << "Loop extraction failed. Sorry. :( Please report a bug!\n"; return 0; - } else { - Module *NewM = ParseInputFile(Filename); - if (NewM == 0) { - std::cerr << getToolName() << ": Error reading bytecode file '" - << Filename << "'!\n"; - exit(1); - } - removeFile(Filename); - - // Check to see if we created any new functions. If not, no loops were - // extracted and we should return null. - if (M->size() != NewM->size()) { - delete NewM; - return 0; - } + } - return NewM; + // Check to see if we created any new functions. If not, no loops were + // extracted and we should return null. + if (M->size() != NewM->size()) { + delete NewM; + return 0; } + + return NewM; } From lattner at cs.uiuc.edu Sun Mar 14 15:23:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 15:23:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/OptimizerDriver.cpp BugDriver.h Message-ID: <200403142122.PAA28546@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: OptimizerDriver.cpp updated: 1.19 -> 1.20 BugDriver.h updated: 1.34 -> 1.35 --- Log message: Add a new "AutoDebugCrashes" option --- Diffs of the changes: (+17 -4) Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.19 llvm/tools/bugpoint/OptimizerDriver.cpp:1.20 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.19 Sun Mar 14 15:17:03 2004 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Sun Mar 14 15:21:57 2004 @@ -16,6 +16,7 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" +#include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bytecode/WriteBytecodePass.h" @@ -166,11 +167,20 @@ /// module, returning the transformed module on success, or a null pointer on /// failure. Module *BugDriver::runPassesOn(Module *M, - const std::vector &Passes) { + const std::vector &Passes, + bool AutoDebugCrashes) { Module *OldProgram = swapProgramIn(M); std::string BytecodeResult; - if (runPasses(Passes, BytecodeResult, false/*delete*/, true/*quiet*/)) + if (runPasses(Passes, BytecodeResult, false/*delete*/, true/*quiet*/)) { + if (AutoDebugCrashes) { + std::cerr << " Error running this sequence of passes" + << " on the input program!\n"; + delete OldProgram; + EmitProgressBytecode("pass-error", false); + exit(debugOptimizerCrash()); + } return 0; + } // Restore the current program. swapProgramIn(OldProgram); Index: llvm/tools/bugpoint/BugDriver.h diff -u llvm/tools/bugpoint/BugDriver.h:1.34 llvm/tools/bugpoint/BugDriver.h:1.35 --- llvm/tools/bugpoint/BugDriver.h:1.34 Sun Mar 14 15:17:03 2004 +++ llvm/tools/bugpoint/BugDriver.h Sun Mar 14 15:21:57 2004 @@ -192,8 +192,11 @@ /// runPassesOn - Carefully run the specified set of pass on the specified /// module, returning the transformed module on success, or a null pointer on - /// failure. - Module *runPassesOn(Module *M, const std::vector &Passes); + /// failure. If AutoDebugCrashes is set to true, then bugpoint will + /// automatically attempt to track down a crashing pass if one exists, and + /// this method will never return null. + Module *runPassesOn(Module *M, const std::vector &Passes, + bool AutoDebugCrashes = false); /// runPasses - Run the specified passes on Program, outputting a bytecode /// file and writting the filename into OutputFile if successful. If the From lattner at cs.uiuc.edu Sun Mar 14 15:38:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 15:38:01 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/OptimizerDriver.cpp Message-ID: <200403142137.PAA30116@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: OptimizerDriver.cpp updated: 1.20 -> 1.21 --- Log message: Fix a minor bug in runPassesOn --- Diffs of the changes: (+1 -0) Index: llvm/tools/bugpoint/OptimizerDriver.cpp diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.20 llvm/tools/bugpoint/OptimizerDriver.cpp:1.21 --- llvm/tools/bugpoint/OptimizerDriver.cpp:1.20 Sun Mar 14 15:21:57 2004 +++ llvm/tools/bugpoint/OptimizerDriver.cpp Sun Mar 14 15:37:41 2004 @@ -179,6 +179,7 @@ EmitProgressBytecode("pass-error", false); exit(debugOptimizerCrash()); } + swapProgramIn(OldProgram); return 0; } From lattner at cs.uiuc.edu Sun Mar 14 16:09:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 16:09:02 2004 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ExtractFunction.cpp Miscompilation.cpp Message-ID: <200403142208.QAA31085@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: ExtractFunction.cpp updated: 1.29 -> 1.30 Miscompilation.cpp updated: 1.30 -> 1.31 --- Log message: After reducing a miscompiled program down to the functions which are being miscompiled, try to use the loop extractor to reduce the program down to a loop nest that is being miscompiled. In practice, the loop extractor appears to have too many bugs for this to be useful, but hopefully they will be fixed soon... --- Diffs of the changes: (+110 -28) Index: llvm/tools/bugpoint/ExtractFunction.cpp diff -u llvm/tools/bugpoint/ExtractFunction.cpp:1.29 llvm/tools/bugpoint/ExtractFunction.cpp:1.30 --- llvm/tools/bugpoint/ExtractFunction.cpp:1.29 Sun Mar 14 15:17:22 2004 +++ llvm/tools/bugpoint/ExtractFunction.cpp Sun Mar 14 16:08:00 2004 @@ -131,7 +131,11 @@ Module *NewM = runPassesOn(M, LoopExtractPasses); if (NewM == 0) { - std::cerr << "Loop extraction failed. Sorry. :( Please report a bug!\n"; + Module *Old = swapProgramIn(M); + std::cout << "*** Loop extraction failed: "; + EmitProgressBytecode("loopextraction", true); + std::cout << "*** Sorry. :( Please report a bug!\n"; + swapProgramIn(Old); return 0; } Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.30 llvm/tools/bugpoint/Miscompilation.cpp:1.31 --- llvm/tools/bugpoint/Miscompilation.cpp:1.30 Sun Mar 14 14:50:42 2004 +++ llvm/tools/bugpoint/Miscompilation.cpp Sun Mar 14 16:08:00 2004 @@ -142,17 +142,20 @@ /// TestMergedProgram - Given two modules, link them together and run the /// program, checking to see if the program matches the diff. If the diff -/// matches, return false, otherwise return true. In either case, we delete -/// both input modules before we return. -static bool TestMergedProgram(BugDriver &BD, Module *M1, Module *M2) { +/// matches, return false, otherwise return true. If the DeleteInputs argument +/// is set to true then this function deletes both input modules before it +/// returns. +static bool TestMergedProgram(BugDriver &BD, Module *M1, Module *M2, + bool DeleteInputs) { // Link the two portions of the program back to together. std::string ErrorMsg; + if (!DeleteInputs) M1 = CloneModule(M1); if (LinkModules(M1, M2, &ErrorMsg)) { std::cerr << BD.getToolName() << ": Error linking modules together:" << ErrorMsg << "\n"; exit(1); } - delete M2; // We are done with this module... + if (DeleteInputs) delete M2; // We are done with this module... Module *OldProgram = BD.swapProgramIn(M1); @@ -161,7 +164,8 @@ bool Broken = BD.diffProgram(); // Delete the linked module & restore the original - delete BD.swapProgramIn(OldProgram); + BD.swapProgramIn(OldProgram); + if (DeleteInputs) delete M1; return Broken; } @@ -171,7 +175,7 @@ std::cout << "Checking to see if the program is misoptimized when " << (Funcs.size()==1 ? "this function is" : "these functions are") << " run through the pass" - << (BD.getPassesToRun().size() == 1 ? "" : "es") << ": "; + << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":"; PrintFunctionList(Funcs); std::cout << "\n"; @@ -181,36 +185,94 @@ // Run the optimization passes on ToOptimize, producing a transformed version // of the functions being tested. - Module *OldProgram = BD.swapProgramIn(ToOptimize); - std::cout << " Optimizing functions being tested: "; - std::string BytecodeResult; - if (BD.runPasses(BD.getPassesToRun(), BytecodeResult, false/*delete*/, - true/*quiet*/)) { - std::cerr << " Error running this sequence of passes" - << " on the input program!\n"; - BD.EmitProgressBytecode("pass-error", false); - exit(BD.debugOptimizerCrash()); - } - + Module *Optimized = BD.runPassesOn(ToOptimize, BD.getPassesToRun(), + /*AutoDebugCrashes*/true); std::cout << "done.\n"; + delete ToOptimize; - // Delete the old "ToOptimize" module - delete BD.swapProgramIn(OldProgram); - Module *Optimized = ParseInputFile(BytecodeResult); - if (Optimized == 0) { - std::cerr << BD.getToolName() << ": Error reading bytecode file '" - << BytecodeResult << "'!\n"; - exit(1); - } - removeFile(BytecodeResult); // No longer need the file on disk std::cout << " Checking to see if the merged program executes correctly: "; - bool Broken = TestMergedProgram(BD, Optimized, ToNotOptimize); + bool Broken = TestMergedProgram(BD, Optimized, ToNotOptimize, true); std::cout << (Broken ? " nope.\n" : " yup.\n"); return Broken; } +/// ExtractLoops - Given a reduced list of functions that still exposed the bug, +/// check to see if we can extract the loops in the region without obscuring the +/// bug. If so, it reduces the amount of code identified. +static bool ExtractLoops(BugDriver &BD, + std::vector &MiscompiledFunctions) { + bool MadeChange = false; + while (1) { + Module *ToNotOptimize = CloneModule(BD.getProgram()); + Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, + MiscompiledFunctions); + Module *ToOptimizeLoopExtracted = BD.ExtractLoop(ToOptimize); + if (!ToOptimizeLoopExtracted) { + // If the loop extractor crashed or if there were no extractible loops, + // then this chapter of our odyssey is over with. + delete ToNotOptimize; + delete ToOptimize; + return MadeChange; + } + + std::cerr << "Extracted a loop from the breaking portion of the program.\n"; + delete ToOptimize; + + // Bugpoint is intentionally not very trusting of LLVM transformations. In + // particular, we're not going to assume that the loop extractor works, so + // we're going to test the newly loop extracted program to make sure nothing + // has broken. If something broke, then we'll inform the user and stop + // extraction. + if (TestMergedProgram(BD, ToOptimizeLoopExtracted, ToNotOptimize, false)) { + // Merged program doesn't work anymore! + std::cerr << " *** ERROR: Loop extraction broke the program. :(" + << " Please report a bug!\n"; + std::cerr << " Continuing on with un-loop-extracted version.\n"; + delete ToNotOptimize; + delete ToOptimizeLoopExtracted; + return MadeChange; + } + + // Okay, the loop extractor didn't break the program. Run the series of + // optimizations on the loop extracted portion and see if THEY still break + // the program. If so, it was safe to extract these loops! + std::cout << " Running optimizations on loop extracted portion: "; + Module *Optimized = BD.runPassesOn(ToOptimizeLoopExtracted, + BD.getPassesToRun(), + /*AutoDebugCrashes*/true); + std::cout << "done.\n"; + + std::cout << " Checking to see if the merged program executes correctly: "; + bool Broken = TestMergedProgram(BD, Optimized, ToNotOptimize, true); + delete Optimized; + if (!Broken) { + std::cout << "yup: loop extraction masked the problem. Undoing.\n"; + // If the program is not still broken, then loop extraction did something + // that masked the error. Stop loop extraction now. + delete ToNotOptimize; + delete ToOptimizeLoopExtracted; + return MadeChange; + } + std::cout << "nope: loop extraction successful!\n"; + + // Okay, great! Now we know that we extracted a loop and that loop + // extraction both didn't break the program, and didn't mask the problem. + // Replace the current program with the loop extracted version, and try to + // extract another loop. + std::string ErrorMsg; + if (LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, &ErrorMsg)) { + std::cerr << BD.getToolName() << ": Error linking modules together:" + << ErrorMsg << "\n"; + exit(1); + } + delete ToOptimizeLoopExtracted; + BD.setNewProgram(ToNotOptimize); + MadeChange = true; + } +} + /// debugMiscompilation - This method is used when the passes selected are not /// crashing, but the generated output is semantically different from the /// input. @@ -245,6 +307,22 @@ << " being miscompiled: "; PrintFunctionList(MiscompiledFunctions); std::cout << "\n"; + + // See if we can rip any loops out of the miscompiled functions and still + // trigger the problem. + if (ExtractLoops(*this, MiscompiledFunctions)) { + // Okay, we extracted some loops and the problem still appears. See if we + // can eliminate some of the created functions from being candidates. + + // Do the reduction... + ReduceMiscompilingFunctions(*this).reduceList(MiscompiledFunctions); + + std::cout << "\n*** The following function" + << (MiscompiledFunctions.size() == 1 ? " is" : "s are") + << " being miscompiled: "; + PrintFunctionList(MiscompiledFunctions); + std::cout << "\n"; + } // Output a bunch of bytecode files for the user... std::cout << "Outputting reduced bytecode files which expose the problem:\n"; From lattner at cs.uiuc.edu Sun Mar 14 16:18:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 16:18:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CodeExtractor/2004-03-14-NoSwitchSupport.ll Message-ID: <200403142217.QAA31308@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CodeExtractor: 2004-03-14-NoSwitchSupport.ll added (r1.1) --- Log message: New testcase that crashes the loop extractor --- Diffs of the changes: (+27 -0) Index: llvm/test/Regression/Transforms/CodeExtractor/2004-03-14-NoSwitchSupport.ll diff -c /dev/null llvm/test/Regression/Transforms/CodeExtractor/2004-03-14-NoSwitchSupport.ll:1.1 *** /dev/null Sun Mar 14 16:17:02 2004 --- llvm/test/Regression/Transforms/CodeExtractor/2004-03-14-NoSwitchSupport.ll Sun Mar 14 16:16:52 2004 *************** *** 0 **** --- 1,27 ---- + ; RUN: llvm-as < %s | opt -loop-extract-single -disable-output + + void %ab() { + entry: + br label %codeReplTail + + then.1: ; preds = %codeReplTail + br label %loopentry.1 + + loopentry.1: ; preds = %loopentry.1.preheader, %no_exit.1 + br bool false, label %no_exit.1, label %loopexit.0.loopexit1 + + no_exit.1: ; preds = %loopentry.1 + br label %loopentry.1 + + loopexit.0.loopexit: ; preds = %codeReplTail + ret void + + loopexit.0.loopexit1: ; preds = %loopentry.1 + ret void + + codeReplTail: ; preds = %codeRepl, %codeReplTail + switch ushort 0, label %codeReplTail [ + ushort 0, label %loopexit.0.loopexit + ushort 1, label %then.1 + ] + } From lattner at cs.uiuc.edu Sun Mar 14 16:38:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 16:38:06 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200403142235.QAA00319@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.5 -> 1.6 --- Log message: Simplify the code a bit by making the collection of basic blocks to extract a member of the class. While we're at it, turn the collection into a set instead of a vector to improve efficiency and make queries simpler. --- Diffs of the changes: (+39 -57) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.5 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.6 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.5 Sat Mar 13 22:01:47 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Sun Mar 14 16:34:55 2004 @@ -26,16 +26,11 @@ #include "Support/Debug.h" #include "Support/StringExtras.h" #include -#include -#include +#include using namespace llvm; namespace { - inline bool contains(const std::vector &V, const BasicBlock *BB){ - return std::find(V.begin(), V.end(), BB) != V.end(); - } - /// getFunctionArg - Return a pointer to F's ARGNOth argument. /// Argument *getFunctionArg(Function *F, unsigned argno) { @@ -49,19 +44,16 @@ typedef std::vector > PhiValChangesTy; typedef std::map PhiVal2ArgTy; PhiVal2ArgTy PhiVal2Arg; - + std::set BlocksToExtract; public: Function *ExtractCodeRegion(const std::vector &code); private: - void findInputsOutputs(const std::vector &code, - Values &inputs, - Values &outputs, + void findInputsOutputs(Values &inputs, Values &outputs, BasicBlock *newHeader, BasicBlock *newRootNode); void processPhiNodeInputs(PHINode *Phi, - const std::vector &code, Values &inputs, BasicBlock *newHeader, BasicBlock *newRootNode); @@ -71,15 +63,12 @@ Function *constructFunction(const Values &inputs, const Values &outputs, BasicBlock *newRootNode, BasicBlock *newHeader, - const std::vector &code, Function *oldFunction, Module *M); - void moveCodeToFunction(const std::vector &code, - Function *newFunction); + void moveCodeToFunction(Function *newFunction); void emitCallAndSwitchStatement(Function *newFunction, BasicBlock *newHeader, - const std::vector &code, Values &inputs, Values &outputs); @@ -87,7 +76,6 @@ } void CodeExtractor::processPhiNodeInputs(PHINode *Phi, - const std::vector &code, Values &inputs, BasicBlock *codeReplacer, BasicBlock *newFuncRoot) @@ -102,11 +90,11 @@ for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) { Value *phiVal = Phi->getIncomingValue(i); if (Instruction *Inst = dyn_cast(phiVal)) { - if (contains(code, Inst->getParent())) { - if (!contains(code, Phi->getIncomingBlock(i))) + if (BlocksToExtract.count(Inst->getParent())) { + if (!BlocksToExtract.count(Phi->getIncomingBlock(i))) IValEBB.push_back(i); } else { - if (contains(code, Phi->getIncomingBlock(i))) + if (BlocksToExtract.count(Phi->getIncomingBlock(i))) EValIBB.push_back(i); else EValEBB.push_back(i); @@ -114,11 +102,11 @@ } else if (Constant *Const = dyn_cast(phiVal)) { // Constants are internal, but considered `external' if they are coming // from an external block. - if (!contains(code, Phi->getIncomingBlock(i))) + if (!BlocksToExtract.count(Phi->getIncomingBlock(i))) EValEBB.push_back(i); } else if (Argument *Arg = dyn_cast(phiVal)) { // arguments are external - if (contains(code, Phi->getIncomingBlock(i))) + if (BlocksToExtract.count(Phi->getIncomingBlock(i))) EValIBB.push_back(i); else EValEBB.push_back(i); @@ -184,14 +172,13 @@ } -void CodeExtractor::findInputsOutputs(const std::vector &code, - Values &inputs, +void CodeExtractor::findInputsOutputs(Values &inputs, Values &outputs, BasicBlock *newHeader, BasicBlock *newRootNode) { - for (std::vector::const_iterator ci = code.begin(), - ce = code.end(); ci != ce; ++ci) { + for (std::set::const_iterator ci = BlocksToExtract.begin(), + ce = BlocksToExtract.end(); ci != ce; ++ci) { BasicBlock *BB = *ci; for (BasicBlock::iterator BBi = BB->begin(), BBe = BB->end(); BBi != BBe; ++BBi) { @@ -200,7 +187,7 @@ if (Instruction *I = dyn_cast(&*BBi)) { // If it's a phi node if (PHINode *Phi = dyn_cast(I)) { - processPhiNodeInputs(Phi, code, inputs, newHeader, newRootNode); + processPhiNodeInputs(Phi, inputs, newHeader, newRootNode); } else { // All other instructions go through the generic input finder // Loop over the operands of each instruction (inputs) @@ -208,7 +195,7 @@ op != opE; ++op) { if (Instruction *opI = dyn_cast(op->get())) { // Check if definition of this operand is within the loop - if (!contains(code, opI->getParent())) { + if (!BlocksToExtract.count(opI->getParent())) { // add this operand to the inputs inputs.push_back(opI); } @@ -220,7 +207,7 @@ for (Value::use_iterator use = I->use_begin(), useE = I->use_end(); use != useE; ++use) { if (Instruction* inst = dyn_cast(*use)) { - if (!contains(code, inst->getParent())) { + if (!BlocksToExtract.count(inst->getParent())) { // add this op to the outputs outputs.push_back(I); } @@ -276,11 +263,10 @@ const Values &outputs, BasicBlock *newRootNode, BasicBlock *newHeader, - const std::vector &code, Function *oldFunction, Module *M) { DEBUG(std::cerr << "inputs: " << inputs.size() << "\n"); DEBUG(std::cerr << "outputs: " << outputs.size() << "\n"); - BasicBlock *header = code[0]; + BasicBlock *header = *BlocksToExtract.begin(); // This function returns unsigned, outputs will go back by reference. Type *retTy = Type::UShortTy; @@ -327,7 +313,7 @@ for (std::vector::iterator use = Users.begin(), useE = Users.end(); use != useE; ++use) if (Instruction* inst = dyn_cast(*use)) - if (contains(code, inst->getParent())) + if (BlocksToExtract.count(inst->getParent())) inst->replaceUsesOfWith(inputs[i], getFunctionArg(newFunction, i)); } @@ -339,7 +325,7 @@ i != e; ++i) { if (BranchInst *inst = dyn_cast(*i)) { BasicBlock *BB = inst->getParent(); - if (!contains(code, BB) && BB->getParent() == oldFunction) { + if (!BlocksToExtract.count(BB) && BB->getParent() == oldFunction) { // The BasicBlock which contains the branch is not in the region // modify the branch target to a new block inst->replaceUsesOfWith(header, newHeader); @@ -350,29 +336,25 @@ return newFunction; } -void CodeExtractor::moveCodeToFunction(const std::vector &code, - Function *newFunction) +void CodeExtractor::moveCodeToFunction(Function *newFunction) { - Function *oldFunc = code[0]->getParent(); + Function *oldFunc = (*BlocksToExtract.begin())->getParent(); Function::BasicBlockListType &oldBlocks = oldFunc->getBasicBlockList(); Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList(); - for (std::vector::const_iterator i = code.begin(), e =code.end(); - i != e; ++i) { - BasicBlock *BB = *i; - + for (std::set::const_iterator i = BlocksToExtract.begin(), + e = BlocksToExtract.end(); i != e; ++i) { // Delete the basic block from the old function, and the list of blocks - oldBlocks.remove(BB); + oldBlocks.remove(*i); // Insert this basic block into the new function - newBlocks.push_back(BB); + newBlocks.push_back(*i); } } void CodeExtractor::emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer, - const std::vector &code, Values &inputs, Values &outputs) { @@ -399,7 +381,7 @@ for (std::vector::iterator use = Users.begin(), useE =Users.end(); use != useE; ++use) { if (Instruction* inst = dyn_cast(*use)) { - if (!contains(code, inst->getParent())) { + if (!BlocksToExtract.count(inst->getParent())) { inst->replaceUsesOfWith(*i, load); } } @@ -425,8 +407,8 @@ // Since there may be multiple exits from the original region, make the new // function return an unsigned, switch on that number unsigned switchVal = 0; - for (std::vector::const_iterator i =code.begin(), e = code.end(); - i != e; ++i) { + for (std::set::const_iterator i = BlocksToExtract.begin(), + e = BlocksToExtract.end(); i != e; ++i) { BasicBlock *BB = *i; // rewrite the terminator of the original BasicBlock @@ -436,16 +418,14 @@ // Restore values just before we exit // FIXME: Use a GetElementPtr to bunch the outputs in a struct for (unsigned outIdx = 0, outE = outputs.size(); outIdx != outE; ++outIdx) - { new StoreInst(outputs[outIdx], getFunctionArg(newFunction, outIdx), brInst); - } // Rewrite branches into exits which return a value based on which // exit we take from this function if (brInst->isUnconditional()) { - if (!contains(code, brInst->getSuccessor(0))) { + if (!BlocksToExtract.count(brInst->getSuccessor(0))) { ConstantUInt *brVal = ConstantUInt::get(Type::UShortTy, switchVal); ReturnInst *newRet = new ReturnInst(brVal); // add a new target to the switch @@ -461,7 +441,7 @@ // to two new blocks, each of which returns a different code. for (unsigned idx = 0; idx < 2; ++idx) { BasicBlock *oldTarget = brInst->getSuccessor(idx); - if (!contains(code, oldTarget)) { + if (!BlocksToExtract.count(oldTarget)) { // add a new basic block which returns the appropriate value BasicBlock *newTarget = new BasicBlock("newTarget", newFunction); ConstantUInt *brVal = ConstantUInt::get(Type::UShortTy, switchVal); @@ -475,13 +455,15 @@ } } } + } else if (SwitchInst *swTerm = dyn_cast(term)) { + + assert(0 && "Cannot handle switch instructions just yet."); + } else if (ReturnInst *retTerm = dyn_cast(term)) { assert(0 && "Cannot handle return instructions just yet."); // FIXME: what if the terminator is a return!??! // Need to rewrite: add new basic block, move the return there // treat the original as an unconditional branch to that basicblock - } else if (SwitchInst *swTerm = dyn_cast(term)) { - assert(0 && "Cannot handle switch instructions just yet."); } else if (InvokeInst *invInst = dyn_cast(term)) { assert(0 && "Cannot handle invoke instructions just yet."); } else { @@ -514,7 +496,8 @@ // * Add allocas for defs, pass as args by reference // * Pass in uses as args // 3) Move code region, add call instr to func - // + // + BlocksToExtract.insert(code.begin(), code.end()); Values inputs, outputs; @@ -548,19 +531,18 @@ // blocks moving to a new function. // SOLUTION: move Phi nodes out of the loop header into the codeReplacer, pass // the values as parameters to the function - findInputsOutputs(code, inputs, outputs, codeReplacer, newFuncRoot); + findInputsOutputs(inputs, outputs, codeReplacer, newFuncRoot); // Step 2: Construct new function based on inputs/outputs, // Add allocas for all defs Function *newFunction = constructFunction(inputs, outputs, newFuncRoot, - codeReplacer, code, - oldFunction, module); + codeReplacer, oldFunction, module); rewritePhiNodes(newFunction, newFuncRoot); - emitCallAndSwitchStatement(newFunction, codeReplacer, code, inputs, outputs); + emitCallAndSwitchStatement(newFunction, codeReplacer, inputs, outputs); - moveCodeToFunction(code, newFunction); + moveCodeToFunction(newFunction); DEBUG(if (verifyFunction(*newFunction)) abort()); return newFunction; From lattner at cs.uiuc.edu Sun Mar 14 17:06:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 17:06:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200403142305.RAA02218@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.6 -> 1.7 --- Log message: Simplify code a bit, and fix bug CodeExtractor/2004-03-14-NoSwitchSupport.ll This also implements a two minor improvements: * Don't insert live-out stores IN the region, insert them on the code path that exits the region * If the region is exited to the same block from multiple paths, share the switch statement entry, live-out store code, and the basic block. --- Diffs of the changes: (+34 -62) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.6 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.7 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.6 Sun Mar 14 16:34:55 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Sun Mar 14 17:05:49 2004 @@ -336,11 +336,10 @@ return newFunction; } -void CodeExtractor::moveCodeToFunction(Function *newFunction) -{ +void CodeExtractor::moveCodeToFunction(Function *newFunction) { Function *oldFunc = (*BlocksToExtract.begin())->getParent(); Function::BasicBlockListType &oldBlocks = oldFunc->getBasicBlockList(); - Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList(); + Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList(); for (std::set::const_iterator i = BlocksToExtract.begin(), e = BlocksToExtract.end(); i != e; ++i) { @@ -390,6 +389,7 @@ params.push_back(*i); } } + CallInst *call = new CallInst(newFunction, params, "targetBlock"); codeReplacer->getInstList().push_back(call); codeReplacer->getInstList().push_back(new BranchInst(codeReplacerTail)); @@ -405,70 +405,42 @@ codeReplacerTail); // Since there may be multiple exits from the original region, make the new - // function return an unsigned, switch on that number + // function return an unsigned, switch on that number. This loop iterates + // over all of the blocks in the extracted region, updating any terminator + // instructions in the to-be-extracted region that branch to blocks that are + // not in the region to be extracted. + std::map ExitBlockMap; + unsigned switchVal = 0; for (std::set::const_iterator i = BlocksToExtract.begin(), e = BlocksToExtract.end(); i != e; ++i) { - BasicBlock *BB = *i; - - // rewrite the terminator of the original BasicBlock - Instruction *term = BB->getTerminator(); - if (BranchInst *brInst = dyn_cast(term)) { - - // Restore values just before we exit - // FIXME: Use a GetElementPtr to bunch the outputs in a struct - for (unsigned outIdx = 0, outE = outputs.size(); outIdx != outE; ++outIdx) - new StoreInst(outputs[outIdx], - getFunctionArg(newFunction, outIdx), - brInst); - - // Rewrite branches into exits which return a value based on which - // exit we take from this function - if (brInst->isUnconditional()) { - if (!BlocksToExtract.count(brInst->getSuccessor(0))) { - ConstantUInt *brVal = ConstantUInt::get(Type::UShortTy, switchVal); - ReturnInst *newRet = new ReturnInst(brVal); - // add a new target to the switch - switchInst->addCase(brVal, brInst->getSuccessor(0)); - ++switchVal; - // rewrite the branch with a return - BasicBlock::iterator ii(brInst); - ReplaceInstWithInst(BB->getInstList(), ii, newRet); - delete brInst; - } - } else { - // Replace the conditional branch to branch - // to two new blocks, each of which returns a different code. - for (unsigned idx = 0; idx < 2; ++idx) { - BasicBlock *oldTarget = brInst->getSuccessor(idx); - if (!BlocksToExtract.count(oldTarget)) { - // add a new basic block which returns the appropriate value - BasicBlock *newTarget = new BasicBlock("newTarget", newFunction); - ConstantUInt *brVal = ConstantUInt::get(Type::UShortTy, switchVal); - ReturnInst *newRet = new ReturnInst(brVal); - newTarget->getInstList().push_back(newRet); - // rewrite the original branch instruction with this new target - brInst->setSuccessor(idx, newTarget); - // the switch statement knows what to do with this value - switchInst->addCase(brVal, oldTarget); - ++switchVal; - } + TerminatorInst *TI = (*i)->getTerminator(); + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) + if (!BlocksToExtract.count(TI->getSuccessor(i))) { + BasicBlock *OldTarget = TI->getSuccessor(i); + // add a new basic block which returns the appropriate value + BasicBlock *&NewTarget = ExitBlockMap[OldTarget]; + if (!NewTarget) { + // If we don't already have an exit stub for this non-extracted + // destination, create one now! + NewTarget = new BasicBlock(OldTarget->getName() + ".exitStub", + newFunction); + + ConstantUInt *brVal = ConstantUInt::get(Type::UShortTy, switchVal++); + ReturnInst *NTRet = new ReturnInst(brVal, NewTarget); + + // Update the switch instruction. + switchInst->addCase(brVal, OldTarget); + + // Restore values just before we exit + // FIXME: Use a GetElementPtr to bunch the outputs in a struct + for (unsigned out = 0, e = outputs.size(); out != e; ++out) + new StoreInst(outputs[out], getFunctionArg(newFunction, out),NTRet); } - } - } else if (SwitchInst *swTerm = dyn_cast(term)) { - - assert(0 && "Cannot handle switch instructions just yet."); - } else if (ReturnInst *retTerm = dyn_cast(term)) { - assert(0 && "Cannot handle return instructions just yet."); - // FIXME: what if the terminator is a return!??! - // Need to rewrite: add new basic block, move the return there - // treat the original as an unconditional branch to that basicblock - } else if (InvokeInst *invInst = dyn_cast(term)) { - assert(0 && "Cannot handle invoke instructions just yet."); - } else { - assert(0 && "Unrecognized terminator, or badly-formed BasicBlock."); - } + // rewrite the original branch instruction with this new target + TI->setSuccessor(i, NewTarget); + } } } From lattner at cs.uiuc.edu Sun Mar 14 17:44:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 17:44:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200403142343.RAA05619@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.7 -> 1.8 --- Log message: No correctness fixes here, just minor qoi fixes: * Don't insert a branch to the switch instruction after the call, just make it a single block. * Insert the new alloca instructions in the entry block of the original function instead of having them execute dynamically * Don't make the default edge of the switch instruction go back to the switch. The loop extractor shouldn't create new loops! * Give meaningful names to the alloca slots and the reload instructions * Some minor code simplifications --- Diffs of the changes: (+26 -30) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.7 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.8 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.7 Sun Mar 14 17:05:49 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Sun Mar 14 17:43:24 2004 @@ -34,9 +34,9 @@ /// getFunctionArg - Return a pointer to F's ARGNOth argument. /// Argument *getFunctionArg(Function *F, unsigned argno) { - Function::aiterator ai = F->abegin(); - while (argno) { ++ai; --argno; } - return &*ai; + Function::aiterator I = F->abegin(); + std::advance(I, argno); + return I; } struct CodeExtractor { @@ -359,30 +359,26 @@ { // Emit a call to the new function, passing allocated memory for outputs and // just plain inputs for non-scalars - std::vector params; - BasicBlock *codeReplacerTail = new BasicBlock("codeReplTail", - codeReplacer->getParent()); - for (Values::const_iterator i = inputs.begin(), - e = inputs.end(); i != e; ++i) - params.push_back(*i); - for (Values::const_iterator i = outputs.begin(), - e = outputs.end(); i != e; ++i) { + std::vector params(inputs); + + for (Values::const_iterator i = outputs.begin(), e = outputs.end(); i != e; + ++i) { + Value *Output = *i; // Create allocas for scalar outputs - if ((*i)->getType()->isPrimitiveType()) { - Constant *one = ConstantUInt::get(Type::UIntTy, 1); - AllocaInst *alloca = new AllocaInst((*i)->getType(), one); - codeReplacer->getInstList().push_back(alloca); + if (Output->getType()->isPrimitiveType()) { + AllocaInst *alloca = + new AllocaInst((*i)->getType(), 0, Output->getName()+".loc", + codeReplacer->getParent()->begin()->begin()); params.push_back(alloca); - LoadInst *load = new LoadInst(alloca, "alloca"); - codeReplacerTail->getInstList().push_back(load); + LoadInst *load = new LoadInst(alloca, Output->getName()+".reload"); + codeReplacer->getInstList().push_back(load); std::vector Users((*i)->use_begin(), (*i)->use_end()); for (std::vector::iterator use = Users.begin(), useE =Users.end(); use != useE; ++use) { if (Instruction* inst = dyn_cast(*use)) { - if (!BlocksToExtract.count(inst->getParent())) { + if (!BlocksToExtract.count(inst->getParent())) inst->replaceUsesOfWith(*i, load); - } } } } else { @@ -391,18 +387,10 @@ } CallInst *call = new CallInst(newFunction, params, "targetBlock"); - codeReplacer->getInstList().push_back(call); - codeReplacer->getInstList().push_back(new BranchInst(codeReplacerTail)); + codeReplacer->getInstList().push_front(call); // Now we can emit a switch statement using the call as a value. - // FIXME: perhaps instead of default being self BB, it should be a second - // dummy block which asserts that the value is not within the range...? - //BasicBlock *defaultBlock = new BasicBlock("defaultBlock", oldF); - //insert abort() ? - //defaultBlock->getInstList().push_back(new BranchInst(codeReplacer)); - - SwitchInst *switchInst = new SwitchInst(call, codeReplacerTail, - codeReplacerTail); + SwitchInst *TheSwitch = new SwitchInst(call, codeReplacer, codeReplacer); // Since there may be multiple exits from the original region, make the new // function return an unsigned, switch on that number. This loop iterates @@ -430,7 +418,7 @@ ReturnInst *NTRet = new ReturnInst(brVal, NewTarget); // Update the switch instruction. - switchInst->addCase(brVal, OldTarget); + TheSwitch->addCase(brVal, OldTarget); // Restore values just before we exit // FIXME: Use a GetElementPtr to bunch the outputs in a struct @@ -441,6 +429,14 @@ // rewrite the original branch instruction with this new target TI->setSuccessor(i, NewTarget); } + } + + // Now that we've done the deed, make the default destination of the switch + // instruction be one of the exit blocks of the region. + if (TheSwitch->getNumSuccessors() > 1) { + // FIXME: this is broken w.r.t. PHI nodes, but the old code was more broken. + // This edge is not traversable. + TheSwitch->setSuccessor(0, TheSwitch->getSuccessor(1)); } } From lattner at cs.uiuc.edu Sun Mar 14 18:03:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 18:03:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/LoopExtractor.cpp Message-ID: <200403150002.SAA06617@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: LoopExtractor.cpp updated: 1.6 -> 1.7 --- Log message: Fix several bugs in the loop extractor. In particular, subloops were never extracted, and a function that contained a single top-level loop never had the loop extracted, regardless of how much non-loop code there was. --- Diffs of the changes: (+48 -8) Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp diff -u llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.6 llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.7 --- llvm/lib/Transforms/IPO/LoopExtractor.cpp:1.6 Sun Mar 14 14:01:36 2004 +++ llvm/lib/Transforms/IPO/LoopExtractor.cpp Sun Mar 14 18:02:02 2004 @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" +#include "llvm/iTerminators.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Analysis/LoopInfo.h" @@ -54,17 +55,56 @@ bool LoopExtractor::runOnFunction(Function &F) { LoopInfo &LI = getAnalysis(); - // We don't want to keep extracting the only loop of a function into a new one - if (LI.begin() == LI.end() || LI.begin() + 1 == LI.end()) + // If this function has no loops, there is nothing to do. + if (LI.begin() == LI.end()) return false; + // If there is more than one top-level loop in this function, extract all of + // the loops. bool Changed = false; - - // Try to move each loop out of the code into separate function - for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; ++i) { - if (NumLoops == 0) return Changed; - --NumLoops; - Changed |= (ExtractLoop(*i) != 0); + if (LI.end()-LI.begin() > 1) { + for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; ++i) { + if (NumLoops == 0) return Changed; + --NumLoops; + Changed |= (ExtractLoop(*i) != 0); + } + } else { + // Otherwise there is exactly one top-level loop. If this function is more + // than a minimal wrapper around the loop, extract the loop. + Loop *TLL = *LI.begin(); + bool ShouldExtractLoop = false; + + // Extract the loop if the entry block doesn't branch to the loop header. + TerminatorInst *EntryTI = F.getEntryBlock().getTerminator(); + if (!isa(EntryTI) || + !cast(EntryTI)->isUnconditional() || + EntryTI->getSuccessor(0) != TLL->getHeader()) + ShouldExtractLoop = true; + else { + // Check to see if any exits from the loop are more than just return + // blocks. + for (unsigned i = 0, e = TLL->getExitBlocks().size(); i != e; ++i) + if (!isa(TLL->getExitBlocks()[i]->getTerminator())) { + ShouldExtractLoop = true; + break; + } + } + + if (ShouldExtractLoop) { + if (NumLoops == 0) return Changed; + --NumLoops; + Changed |= (ExtractLoop(TLL) != 0); + } else { + // Okay, this function is a minimal container around the specified loop. + // If we extract the loop, we will continue to just keep extracting it + // infinitely... so don't extract it. However, if the loop contains any + // subloops, extract them. + for (Loop::iterator i = TLL->begin(), e = TLL->end(); i != e; ++i) { + if (NumLoops == 0) return Changed; + --NumLoops; + Changed |= (ExtractLoop(*i) != 0); + } + } } return Changed; From lattner at cs.uiuc.edu Sun Mar 14 18:10:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 18:10:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/CodeExtractor/2004-03-14-DominanceProblem.ll Message-ID: <200403150008.SAA06688@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/CodeExtractor: 2004-03-14-DominanceProblem.ll added (r1.1) --- Log message: New testcase that causes the code extractor to generate bogus code. --- Diffs of the changes: (+34 -0) Index: llvm/test/Regression/Transforms/CodeExtractor/2004-03-14-DominanceProblem.ll diff -c /dev/null llvm/test/Regression/Transforms/CodeExtractor/2004-03-14-DominanceProblem.ll:1.1 *** /dev/null Sun Mar 14 18:08:59 2004 --- llvm/test/Regression/Transforms/CodeExtractor/2004-03-14-DominanceProblem.ll Sun Mar 14 18:08:49 2004 *************** *** 0 **** --- 1,34 ---- + ; RUN: llvm-as < %s | opt -loop-extract -disable-output + ; This testcase is failing the loop extractor because not all exit blocks + ; are dominated by all of the live-outs. + + implementation ; Functions: + + int %ab(int %alpha, int %beta) { + entry: + br label %loopentry.1.preheader + + loopentry.1.preheader: ; preds = %then.1 + br label %loopentry.1 + + loopentry.1: ; preds = %loopentry.1.preheader, %no_exit.1 + br bool false, label %no_exit.1, label %loopexit.0.loopexit1 + + no_exit.1: ; preds = %loopentry.1 + %tmp.53 = load int* null ; [#uses=1] + br bool false, label %shortcirc_next.2, label %loopentry.1 + + shortcirc_next.2: ; preds = %no_exit.1 + %tmp.563 = call int %wins( int 0, int %tmp.53, int 3 ) ; [#uses=0] + ret int 0 + + loopexit.0.loopexit1: ; preds = %loopentry.1 + br label %loopexit.0 + + loopexit.0: ; preds = %loopexit.0.loopexit, %loopexit.0.loopexit1 + ret int 0 + } + + declare int %wins(int, int, int) + + declare ushort %ab_code() From lattner at cs.uiuc.edu Sun Mar 14 19:19:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 19:19:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200403150118.TAA07845@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.8 -> 1.9 --- Log message: Assert that input blocks meet the invariants we expect Simplify the input/output finder. All elements of a basic block are instructions. Any used arguments are also inputs. An instruction can only be used by another instruction. --- Diffs of the changes: (+38 -42) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.8 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.9 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.8 Sun Mar 14 17:43:24 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Sun Mar 14 19:18:23 2004 @@ -172,50 +172,40 @@ } -void CodeExtractor::findInputsOutputs(Values &inputs, - Values &outputs, +void CodeExtractor::findInputsOutputs(Values &inputs, Values &outputs, BasicBlock *newHeader, - BasicBlock *newRootNode) -{ + BasicBlock *newRootNode) { for (std::set::const_iterator ci = BlocksToExtract.begin(), ce = BlocksToExtract.end(); ci != ce; ++ci) { BasicBlock *BB = *ci; - for (BasicBlock::iterator BBi = BB->begin(), BBe = BB->end(); - BBi != BBe; ++BBi) { - // If a use is defined outside the region, it's an input. - // If a def is used outside the region, it's an output. - if (Instruction *I = dyn_cast(&*BBi)) { - // If it's a phi node - if (PHINode *Phi = dyn_cast(I)) { - processPhiNodeInputs(Phi, inputs, newHeader, newRootNode); - } else { - // All other instructions go through the generic input finder - // Loop over the operands of each instruction (inputs) - for (User::op_iterator op = I->op_begin(), opE = I->op_end(); - op != opE; ++op) { - if (Instruction *opI = dyn_cast(op->get())) { - // Check if definition of this operand is within the loop - if (!BlocksToExtract.count(opI->getParent())) { - // add this operand to the inputs - inputs.push_back(opI); - } + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { + // If a used value is defined outside the region, it's an input. If an + // instruction is used outside the region, it's an output. + if (PHINode *Phi = dyn_cast(I)) { + processPhiNodeInputs(Phi, inputs, newHeader, newRootNode); + } else { + // All other instructions go through the generic input finder + // Loop over the operands of each instruction (inputs) + for (User::op_iterator op = I->op_begin(), opE = I->op_end(); + op != opE; ++op) + if (Instruction *opI = dyn_cast(*op)) { + // Check if definition of this operand is within the loop + if (!BlocksToExtract.count(opI->getParent())) { + // add this operand to the inputs + inputs.push_back(opI); } + } else if (isa(*op)) { + inputs.push_back(*op); } - } - - // Consider uses of this instruction (outputs) - for (Value::use_iterator use = I->use_begin(), useE = I->use_end(); - use != useE; ++use) { - if (Instruction* inst = dyn_cast(*use)) { - if (!BlocksToExtract.count(inst->getParent())) { - // add this op to the outputs - outputs.push_back(I); - } - } - } - } /* if */ - } /* for: insts */ - } /* for: basic blocks */ + } + + // Consider uses of this instruction (outputs) + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) + if (!BlocksToExtract.count(cast(*UI)->getParent())) + outputs.push_back(*UI); + } // for: insts + } // for: basic blocks } void CodeExtractor::rewritePhiNodes(Function *F, @@ -470,11 +460,16 @@ Values inputs, outputs; // Assumption: this is a single-entry code region, and the header is the first - // block in the region. FIXME: is this true for a list of blocks from a - // natural function? + // block in the region. BasicBlock *header = code[0]; + for (unsigned i = 1, e = code.size(); i != e; ++i) + for (pred_iterator PI = pred_begin(code[i]), E = pred_end(code[i]); + PI != E; ++PI) + assert(BlocksToExtract.count(*PI) && + "No blocks in this region may have entries from outside the region" + " except for the first block!"); + Function *oldFunction = header->getParent(); - Module *module = oldFunction->getParent(); // This takes place of the original loop BasicBlock *codeReplacer = new BasicBlock("codeRepl", oldFunction); @@ -504,7 +499,8 @@ // Step 2: Construct new function based on inputs/outputs, // Add allocas for all defs Function *newFunction = constructFunction(inputs, outputs, newFuncRoot, - codeReplacer, oldFunction, module); + codeReplacer, oldFunction, + oldFunction->getParent()); rewritePhiNodes(newFunction, newFuncRoot); From lattner at cs.uiuc.edu Sun Mar 14 19:27:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 19:27:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CodeExtractor.cpp Message-ID: <200403150126.TAA07967@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CodeExtractor.cpp updated: 1.9 -> 1.10 --- Log message: Mostly cosmetic improvements. Do fix the bug where a global value was considered an input. --- Diffs of the changes: (+23 -35) Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp diff -u llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.9 llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.10 --- llvm/lib/Transforms/Utils/CodeExtractor.cpp:1.9 Sun Mar 14 19:18:23 2004 +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp Sun Mar 14 19:26:44 2004 @@ -78,8 +78,7 @@ void CodeExtractor::processPhiNodeInputs(PHINode *Phi, Values &inputs, BasicBlock *codeReplacer, - BasicBlock *newFuncRoot) -{ + BasicBlock *newFuncRoot) { // Separate incoming values and BasicBlocks as internal/external. We ignore // the case where both the value and BasicBlock are internal, because we don't // need to do a thing. @@ -99,11 +98,6 @@ else EValEBB.push_back(i); } - } else if (Constant *Const = dyn_cast(phiVal)) { - // Constants are internal, but considered `external' if they are coming - // from an external block. - if (!BlocksToExtract.count(Phi->getIncomingBlock(i))) - EValEBB.push_back(i); } else if (Argument *Arg = dyn_cast(phiVal)) { // arguments are external if (BlocksToExtract.count(Phi->getIncomingBlock(i))) @@ -111,20 +105,21 @@ else EValEBB.push_back(i); } else { - phiVal->dump(); - assert(0 && "Unhandled input in a Phi node"); + // Globals/Constants are internal, but considered `external' if they are + // coming from an external block. + if (!BlocksToExtract.count(Phi->getIncomingBlock(i))) + EValEBB.push_back(i); } } - // Both value and block are external. Need to group all of - // these, have an external phi, pass the result as an - // argument, and have THIS phi use that result. + // Both value and block are external. Need to group all of these, have an + // external phi, pass the result as an argument, and have THIS phi use that + // result. if (EValEBB.size() > 0) { if (EValEBB.size() == 1) { // Now if it's coming from the newFuncRoot, it's that funky input unsigned phiIdx = EValEBB[0]; - if (!dyn_cast(Phi->getIncomingValue(phiIdx))) - { + if (!isa(Phi->getIncomingValue(phiIdx))) { PhiVal2Arg[Phi].push_back(std::make_pair(phiIdx, inputs.size())); // We can just pass this value in as argument inputs.push_back(Phi->getIncomingValue(phiIdx)); @@ -134,8 +129,7 @@ PHINode *externalPhi = new PHINode(Phi->getType(), "extPhi"); codeReplacer->getInstList().insert(codeReplacer->begin(), externalPhi); for (std::vector::iterator i = EValEBB.begin(), - e = EValEBB.end(); i != e; ++i) - { + e = EValEBB.end(); i != e; ++i) { externalPhi->addIncoming(Phi->getIncomingValue(*i), Phi->getIncomingBlock(*i)); @@ -152,21 +146,19 @@ } } - // When the value is external, but block internal... - // just pass it in as argument, no change to phi node + // When the value is external, but block internal... just pass it in as + // argument, no change to phi node for (std::vector::iterator i = EValIBB.begin(), - e = EValIBB.end(); i != e; ++i) - { + e = EValIBB.end(); i != e; ++i) { // rewrite the phi input node to be an argument PhiVal2Arg[Phi].push_back(std::make_pair(*i, inputs.size())); inputs.push_back(Phi->getIncomingValue(*i)); } - // Value internal, block external - // this can happen if we are extracting a part of a loop + // Value internal, block external this can happen if we are extracting a part + // of a loop. for (std::vector::iterator i = IValEBB.begin(), - e = IValEBB.end(); i != e; ++i) - { + e = IValEBB.end(); i != e; ++i) { assert(0 && "Cannot (YET) handle internal values via external blocks"); } } @@ -190,10 +182,8 @@ op != opE; ++op) if (Instruction *opI = dyn_cast(*op)) { // Check if definition of this operand is within the loop - if (!BlocksToExtract.count(opI->getParent())) { - // add this operand to the inputs + if (!BlocksToExtract.count(opI->getParent())) inputs.push_back(opI); - } } else if (isa(*op)) { inputs.push_back(*op); } @@ -212,10 +202,9 @@ BasicBlock *newFuncRoot) { // Write any changes that were saved before: use function arguments as inputs for (PhiVal2ArgTy::iterator i = PhiVal2Arg.begin(), e = PhiVal2Arg.end(); - i != e; ++i) - { - PHINode *phi = (*i).first; - PhiValChangesTy &values = (*i).second; + i != e; ++i) { + PHINode *phi = i->first; + PhiValChangesTy &values = i->second; for (unsigned cIdx = 0, ce = values.size(); cIdx != ce; ++cIdx) { unsigned phiValueIdx = values[cIdx].first, argNum = values[cIdx].second; @@ -228,9 +217,8 @@ // Delete any invalid Phi node inputs that were marked as NULL previously for (PhiVal2ArgTy::iterator i = PhiVal2Arg.begin(), e = PhiVal2Arg.end(); - i != e; ++i) - { - PHINode *phi = (*i).first; + i != e; ++i) { + PHINode *phi = i->first; for (unsigned idx = 0, end = phi->getNumIncomingValues(); idx != end; ++idx) { if (phi->getIncomingValue(idx) == 0 && phi->getIncomingBlock(idx) == 0) { @@ -287,7 +275,7 @@ DEBUG(std::cerr << "Function type: " << retTy << " f("); for (std::vector::iterator i = paramTy.begin(), e = paramTy.end(); i != e; ++i) - DEBUG(std::cerr << (*i) << ", "); + DEBUG(std::cerr << *i << ", "); DEBUG(std::cerr << ")\n"); const FunctionType *funcType = FunctionType::get(retTy, paramTy, false); From lattner at cs.uiuc.edu Sun Mar 14 20:00:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 20:00:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/AliasAnalysis.h Message-ID: <200403150159.TAA12409@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: AliasAnalysis.h updated: 1.11 -> 1.12 --- Log message: Add two new methods which can be used to enable a bunch of transformations in common cases. --- Diffs of the changes: (+22 -0) Index: llvm/include/llvm/Analysis/AliasAnalysis.h diff -u llvm/include/llvm/Analysis/AliasAnalysis.h:1.11 llvm/include/llvm/Analysis/AliasAnalysis.h:1.12 --- llvm/include/llvm/Analysis/AliasAnalysis.h:1.11 Thu Mar 11 17:08:20 2004 +++ llvm/include/llvm/Analysis/AliasAnalysis.h Sun Mar 14 19:58:54 2004 @@ -100,6 +100,28 @@ /// virtual bool pointsToConstantMemory(const Value *P) { return false; } + /// doesNotAccessMemory - If the specified function is known to never read or + /// write memory, return true. + /// + /// Many optimizations (such as CSE and LICM) can be performed on calls to it, + /// without worrying about aliasing properties, and many functions have this + /// property (e.g. 'sin' and 'cos'). + /// + /// This property corresponds to the GCC 'const' attribute. + /// + virtual bool doesNotAccessMemory(Function *F) { return false; } + + /// onlyReadsMemory - If the specified function is known to only read from + /// non-volatile memory (or not access memory at all), return true. + /// + /// This property allows many common optimizations to be performed in the + /// absence of interfering store instructions, such as CSE of strlen calls. + /// + /// This property corresponds to the GCC 'pure' attribute. + /// + virtual bool onlyReadsMemory(Function *F) { return doesNotAccessMemory(F); } + + //===--------------------------------------------------------------------===// /// Simple mod/ref information... /// From lattner at cs.uiuc.edu Sun Mar 14 21:38:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 21:38:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200403150337.VAA16528@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: BasicAliasAnalysis.cpp updated: 1.32 -> 1.33 --- Log message: Teach basicaa about some stdc functions. --- Diffs of the changes: (+100 -5) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.32 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.33 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.32 Fri Mar 12 17:12:55 2004 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Sun Mar 14 21:36:49 2004 @@ -21,13 +21,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Pass.h" -#include "llvm/Argument.h" -#include "llvm/iOther.h" -#include "llvm/iMemory.h" #include "llvm/Constants.h" -#include "llvm/GlobalVariable.h" #include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/GlobalVariable.h" +#include "llvm/iOther.h" +#include "llvm/iMemory.h" +#include "llvm/Pass.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/GetElementPtrTypeIterator.h" using namespace llvm; @@ -53,6 +53,9 @@ /// global) or not. bool pointsToConstantMemory(const Value *P); + virtual bool doesNotAccessMemory(Function *F); + virtual bool onlyReadsMemory(Function *F); + private: // CheckGEPInstructions - Check two GEP instructions with known // must-aliasing base pointers. This checks to see if the index expressions @@ -571,4 +574,96 @@ } return MayAlias; } + +namespace { + struct StringCompare { + bool operator()(const char *LHS, const char *RHS) { + return strcmp(LHS, RHS) < 0; + } + }; +} + +// Note that this list cannot contain libm functions (such as acos and sqrt) +// that set errno on a domain or other error. +static const char *DoesntAccessMemoryTable[] = { + "abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl", + "trunc", "truncf", "truncl", "ldexp", + + "atan", "atanf", "atanl", "atan2", "atan2f", "atan2l", + "cbrt", + "cos", "cosf", "cosl", "cosh", "coshf", "coshl", + "exp", "expf", "expl", + "hypot", + "sin", "sinf", "sinl", "sinh", "sinhf", "sinhl", + "tan", "tanf", "tanl", "tanh", "tanhf", "tanhl", + + "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower", "isprint" + "ispunct", "isspace", "isupper", "isxdigit", "tolower", "toupper", + + "iswalnum", "iswalpha", "iswcntrl", "iswdigit", "iswgraph", "iswlower", + "iswprint", "iswpunct", "iswspace", "iswupper", "iswxdigit", + + "btowc", "wctob", +}; + +static const unsigned DAMTableSize = + sizeof(DoesntAccessMemoryTable)/sizeof(DoesntAccessMemoryTable[0]); + +/// doesNotAccessMemory - Return true if we know that the function does not +/// access memory at all. Since basicaa does no analysis, we can only do simple +/// things here. In particular, if we have an external function with the name +/// of a standard C library function, we are allowed to assume it will be +/// resolved by libc, so we can hardcode some entries in here. +bool BasicAliasAnalysis::doesNotAccessMemory(Function *F) { + if (!F->isExternal()) return false; + + static bool Initialized = false; + if (!Initialized) { + // Sort the table the first time through. + std::sort(DoesntAccessMemoryTable, DoesntAccessMemoryTable+DAMTableSize, + StringCompare()); + Initialized = true; + } + + const char **Ptr = std::lower_bound(DoesntAccessMemoryTable, + DoesntAccessMemoryTable+DAMTableSize, + F->getName().c_str(), StringCompare()); + return Ptr != DoesntAccessMemoryTable+DAMTableSize && *Ptr == F->getName(); +} + + +static const char *OnlyReadsMemoryTable[] = { + "atoi", "atol", "atof", "atoll", "atoq", + "bcmp", "memcmp", "memchr", "wmemcmp", "wmemchr", + + // Strings + "strcmp", "strcasecmp", "strcoll", "strncmp", "strncasecmp", + "strchr", "strcspn", "strlen", "strpbrk", "strrchr", "strspn", "strstr", + + // Wide char strings + "wcschr", "wcscmp", "wcscoll", "wcscspn", "wcslen", "wcsncmp", "wcspbrk", + "wcsrchr", "wcsspn", "wcsstr", +}; + +static const unsigned ORMTableSize = + sizeof(OnlyReadsMemoryTable)/sizeof(OnlyReadsMemoryTable[0]); + +bool BasicAliasAnalysis::onlyReadsMemory(Function *F) { + if (doesNotAccessMemory(F)) return true; + if (!F->isExternal()) return false; + + static bool Initialized = false; + if (!Initialized) { + // Sort the table the first time through. + std::sort(OnlyReadsMemoryTable, OnlyReadsMemoryTable+ORMTableSize, + StringCompare()); + Initialized = true; + } + + const char **Ptr = std::lower_bound(OnlyReadsMemoryTable, + OnlyReadsMemoryTable+ORMTableSize, + F->getName().c_str(), StringCompare()); + return Ptr != OnlyReadsMemoryTable+ORMTableSize && *Ptr == F->getName(); +} + From lattner at cs.uiuc.edu Sun Mar 14 22:07:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 22:07:00 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisCounter.cpp Message-ID: <200403150406.WAA22537@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisCounter.cpp updated: 1.7 -> 1.8 --- Log message: Pass through the boolean queries --- Diffs of the changes: (+12 -0) Index: llvm/lib/Analysis/AliasAnalysisCounter.cpp diff -u llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.7 llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.8 --- llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.7 Wed Dec 10 09:34:03 2003 +++ llvm/lib/Analysis/AliasAnalysisCounter.cpp Sun Mar 14 22:06:46 2004 @@ -93,6 +93,18 @@ case ModRef: MR++; return ModRef; } } + + // FIXME: We could count these too... + bool pointsToConstantMemory(const Value *P) { + return getAnalysis().pointsToConstantMemory(P); + } + bool doesNotAccessMemory(Function *F) { + return getAnalysis().doesNotAccessMemory(F); + } + bool onlyReadsMemory(Function *F) { + return getAnalysis().onlyReadsMemory(F); + } + // Forwarding functions: just delegate to a real AA implementation, counting // the number of responses... From lattner at cs.uiuc.edu Sun Mar 14 22:08:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 22:08:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysis.cpp Message-ID: <200403150407.WAA22551@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysis.cpp updated: 1.16 -> 1.17 --- Log message: Deinline some virtual methods, provide better mod/ref answers through the use of the boolean queries --- Diffs of the changes: (+21 -5) Index: llvm/lib/Analysis/AliasAnalysis.cpp diff -u llvm/lib/Analysis/AliasAnalysis.cpp:1.16 llvm/lib/Analysis/AliasAnalysis.cpp:1.17 --- llvm/lib/Analysis/AliasAnalysis.cpp:1.16 Fri Jan 30 16:16:42 2004 +++ llvm/lib/Analysis/AliasAnalysis.cpp Sun Mar 14 22:07:29 2004 @@ -28,8 +28,7 @@ #include "llvm/BasicBlock.h" #include "llvm/iMemory.h" #include "llvm/Target/TargetData.h" - -namespace llvm { +using namespace llvm; // Register the AliasAnalysis interface, providing a nice name to refer to. namespace { @@ -55,6 +54,25 @@ return pointsToConstantMemory(P) ? NoModRef : Mod; } +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) { + if (Function *F = CS.getCalledFunction()) + if (onlyReadsMemory(F)) { + if (doesNotAccessMemory(F)) return NoModRef; + return Ref; + } + + // If P points to a constant memory location, the call definitely could not + // modify the memory location. + return pointsToConstantMemory(P) ? Ref : ModRef; +} + +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) { + // FIXME: could probably do better. + return ModRef; +} + // AliasAnalysis destructor: DO NOT move this to the header file for // AliasAnalysis or else clients of the AliasAnalysis class may not depend on @@ -110,7 +128,7 @@ // the risk of AliasAnalysis being used, but the default implementation not // being linked into the tool that uses it. // -extern void BasicAAStub(); +extern void llvm::BasicAAStub(); static IncludeFile INCLUDE_BASICAA_CPP((void*)&BasicAAStub); @@ -132,5 +150,3 @@ // Declare that we implement the AliasAnalysis interface RegisterAnalysisGroup Y; } // End of anonymous namespace - -} // End llvm namespace From lattner at cs.uiuc.edu Sun Mar 14 22:09:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 22:09:00 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/AliasSetTracker.h Message-ID: <200403150408.WAA22577@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: AliasSetTracker.h updated: 1.11 -> 1.12 --- Log message: Tweak argument --- Diffs of the changes: (+1 -1) Index: llvm/include/llvm/Analysis/AliasSetTracker.h diff -u llvm/include/llvm/Analysis/AliasSetTracker.h:1.11 llvm/include/llvm/Analysis/AliasSetTracker.h:1.12 --- llvm/include/llvm/Analysis/AliasSetTracker.h:1.11 Thu Dec 18 02:11:11 2003 +++ llvm/include/llvm/Analysis/AliasSetTracker.h Sun Mar 14 22:08:18 2004 @@ -218,7 +218,7 @@ void removeFromTracker(AliasSetTracker &AST); void addPointer(AliasSetTracker &AST, HashNodePair &Entry, unsigned Size); - void addCallSite(CallSite CS); + void addCallSite(CallSite CS, AliasAnalysis &AA); void setVolatile() { Volatile = true; } /// aliasesPointer - Return true if the specified pointer "may" (or must) From lattner at cs.uiuc.edu Sun Mar 14 22:09:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 22:09:11 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/AliasAnalysis.h Message-ID: <200403150408.WAA22563@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: AliasAnalysis.h updated: 1.12 -> 1.13 --- Log message: Deinline a couple of methods. Improve comment. --- Diffs of the changes: (+7 -12) Index: llvm/include/llvm/Analysis/AliasAnalysis.h diff -u llvm/include/llvm/Analysis/AliasAnalysis.h:1.12 llvm/include/llvm/Analysis/AliasAnalysis.h:1.13 --- llvm/include/llvm/Analysis/AliasAnalysis.h:1.12 Sun Mar 14 19:58:54 2004 +++ llvm/include/llvm/Analysis/AliasAnalysis.h Sun Mar 14 22:07:59 2004 @@ -101,7 +101,8 @@ virtual bool pointsToConstantMemory(const Value *P) { return false; } /// doesNotAccessMemory - If the specified function is known to never read or - /// write memory, return true. + /// write memory, return true. If the function only reads from known-constant + /// memory, it is also legal to return true. /// /// Many optimizations (such as CSE and LICM) can be performed on calls to it, /// without worrying about aliasing properties, and many functions have this @@ -139,11 +140,7 @@ /// a particular call site modifies or reads the memory specified by the /// pointer. /// - virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size) { - // If P points to a constant memory location, the call definitely could not - // modify the memory location. - return pointsToConstantMemory(P) ? Ref : ModRef; - } + virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); /// getModRefInfo - Return information about whether two call sites may refer /// to the same set of memory locations. This function returns NoModRef if @@ -151,17 +148,15 @@ /// some of the same memory, Mod if they both write to some of the same /// memory, and ModRef if they read and write to the same memory. /// - virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) { - return ModRef; - } + virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2); /// Convenience functions... ModRefResult getModRefInfo(LoadInst *L, Value *P, unsigned Size); - ModRefResult getModRefInfo(StoreInst*S, Value *P, unsigned Size); - ModRefResult getModRefInfo(CallInst *C, Value *P, unsigned Size) { + ModRefResult getModRefInfo(StoreInst *S, Value *P, unsigned Size); + ModRefResult getModRefInfo(CallInst *C, Value *P, unsigned Size) { return getModRefInfo(CallSite(C), P, Size); } - ModRefResult getModRefInfo(InvokeInst*I, Value *P, unsigned Size) { + ModRefResult getModRefInfo(InvokeInst *I, Value *P, unsigned Size) { return getModRefInfo(CallSite(I), P, Size); } ModRefResult getModRefInfo(Instruction *I, Value *P, unsigned Size) { From lattner at cs.uiuc.edu Sun Mar 14 22:09:23 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 22:09:23 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasSetTracker.cpp Message-ID: <200403150408.WAA22588@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasSetTracker.cpp updated: 1.10 -> 1.11 --- Log message: Don't be COMPLETELY pessimistic in the face of function calls --- Diffs of the changes: (+20 -4) Index: llvm/lib/Analysis/AliasSetTracker.cpp diff -u llvm/lib/Analysis/AliasSetTracker.cpp:1.10 llvm/lib/Analysis/AliasSetTracker.cpp:1.11 --- llvm/lib/Analysis/AliasSetTracker.cpp:1.10 Thu Dec 18 02:11:56 2003 +++ llvm/lib/Analysis/AliasSetTracker.cpp Sun Mar 14 22:08:36 2004 @@ -93,9 +93,21 @@ RefCount++; // Entry points to alias set... } -void AliasSet::addCallSite(CallSite CS) { +void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) { CallSites.push_back(CS); - AliasTy = MayAlias; // FIXME: Too conservative? + + if (Function *F = CS.getCalledFunction()) { + if (AA.doesNotAccessMemory(F)) + return; + else if (AA.onlyReadsMemory(F)) { + AliasTy = MayAlias; + AccessTy = Refs; + return; + } + } + + // FIXME: This should use mod/ref information to make this not suck so bad + AliasTy = MayAlias; AccessTy = ModRef; } @@ -129,7 +141,11 @@ } bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const { - // FIXME: Too conservative! + // FIXME: Use mod/ref information to prune this better! + if (Function *F = CS.getCalledFunction()) + if (AA.doesNotAccessMemory(F)) + return false; + return true; } @@ -213,7 +229,7 @@ AliasSets.push_back(AliasSet()); AS = &AliasSets.back(); } - AS->addCallSite(CS); + AS->addCallSite(CS, AA); } void AliasSetTracker::add(Instruction *I) { From lattner at cs.uiuc.edu Sun Mar 14 22:11:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 22:11:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll call_sink_pure_function.ll Message-ID: <200403150410.WAA22632@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LICM: call_sink_const_function.ll added (r1.1) call_sink_pure_function.ll added (r1.1) --- Log message: New testcases to test LICM of call instructions --- Diffs of the changes: (+30 -0) Index: llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll diff -c /dev/null llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll:1.1 *** /dev/null Sun Mar 14 22:10:18 2004 --- llvm/test/Regression/Transforms/LICM/call_sink_const_function.ll Sun Mar 14 22:10:08 2004 *************** *** 0 **** --- 1,16 ---- + ; RUN: llvm-as < %s | opt -basicaa -licm | llvm-dis | grep -C1 sin | grep Out: + declare double %sin(double) + declare void %foo() + + double %test(double %X) { + br label %Loop + + Loop: + call void %foo() ;; Unknown effects! + + %A = call double %sin(double %X) ;; Can still hoist/sink call + br bool true, label %Loop, label %Out + + Out: + ret double %A + } Index: llvm/test/Regression/Transforms/LICM/call_sink_pure_function.ll diff -c /dev/null llvm/test/Regression/Transforms/LICM/call_sink_pure_function.ll:1.1 *** /dev/null Sun Mar 14 22:10:18 2004 --- llvm/test/Regression/Transforms/LICM/call_sink_pure_function.ll Sun Mar 14 22:10:08 2004 *************** *** 0 **** --- 1,14 ---- + ; RUN: llvm-as < %s | opt -basicaa -licm | llvm-dis | grep -C1 strlen | grep Out: + declare int %strlen(sbyte*) + declare void %foo() + + int %test(sbyte* %P) { + br label %Loop + + Loop: + %A = call int %strlen(sbyte* %P) ;; Can hoist/sink call + br bool false, label %Loop, label %Out + + Out: + ret int %A + } From lattner at cs.uiuc.edu Sun Mar 14 22:12:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Mar 14 22:12:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200403150411.WAA22648@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.56 -> 1.57 --- Log message: Implement LICM of calls in simple cases. This is sufficient to move around sin/cos/strlen calls and stuff. This implements: LICM/call_sink_pure_function.ll LICM/call_sink_const_function.ll --- Diffs of the changes: (+31 -1) Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.56 llvm/lib/Transforms/Scalar/LICM.cpp:1.57 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.56 Mon Feb 2 14:09:22 2004 +++ llvm/lib/Transforms/Scalar/LICM.cpp Sun Mar 14 22:11:30 2004 @@ -57,6 +57,7 @@ Statistic<> NumSunk("licm", "Number of instructions sunk out of loop"); Statistic<> NumHoisted("licm", "Number of instructions hoisted out of loop"); Statistic<> NumMovedLoads("licm", "Number of load insts hoisted or sunk"); + Statistic<> NumMovedCalls("licm", "Number of call insts hoisted or sunk"); Statistic<> NumPromoted("licm", "Number of memory locations promoted to registers"); @@ -360,9 +361,35 @@ // Don't hoist loads which have may-aliased stores in loop. return !pointerInvalidatedByLoop(LI->getOperand(0)); + } else if (CallInst *CI = dyn_cast(&I)) { + // Handle obvious cases efficiently. + if (Function *Callee = CI->getCalledFunction()) { + if (AA->doesNotAccessMemory(Callee)) + return true; + else if (AA->onlyReadsMemory(Callee)) { + // If this call only reads from memory and there are no writes to memory + // in the loop, we can hoist or sink the call as appropriate. + bool FoundMod = false; + for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end(); + I != E; ++I) { + AliasSet &AS = *I; + if (!AS.isForwardingAliasSet() && AS.isMod()) { + FoundMod = true; + break; + } + } + if (!FoundMod) return true; + } + } + + // FIXME: This should use mod/ref information to see if we can hoist or sink + // the call. + + return false; } return isa(I) || isa(I) || isa(I) || + isa(I) || isa(I) || isa(I) || isa(I); } @@ -412,6 +439,7 @@ const std::vector &ExitBlocks = CurLoop->getExitBlocks(); if (isa(I)) ++NumMovedLoads; + else if (isa(I)) ++NumMovedCalls; ++NumSunk; Changed = true; @@ -541,6 +569,7 @@ Preheader->getInstList().insert(Preheader->getTerminator(), &I); if (isa(I)) ++NumMovedLoads; + else if (isa(I)) ++NumMovedCalls; ++NumHoisted; Changed = true; } @@ -679,7 +708,8 @@ I != E; ++I) { AliasSet &AS = *I; // We can promote this alias set if it has a store, if it is a "Must" alias - // set, if the pointer is loop invariant, if if we are not eliminating any volatile loads or stores. + // set, if the pointer is loop invariant, if if we are not eliminating any + // volatile loads or stores. if (!AS.isForwardingAliasSet() && AS.isMod() && AS.isMustAlias() && !AS.isVolatile() && isLoopInvariant(AS.begin()->first)) { assert(AS.begin() != AS.end() &&