From lattner at cs.uiuc.edu Mon Mar 21 00:25:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 00:25:09 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Verifier/2005-03-21-UndefinedTypeReference.ll Message-ID: <200503210625.j2L6P9XQ003447@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Verifier: 2005-03-21-UndefinedTypeReference.ll added (r1.1) --- Log message: New testcase that the assembler incorrectly accepts. --- Diffs of the changes: (+7 -0) 2005-03-21-UndefinedTypeReference.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/Regression/Verifier/2005-03-21-UndefinedTypeReference.ll diff -c /dev/null llvm/test/Regression/Verifier/2005-03-21-UndefinedTypeReference.ll:1.1 *** /dev/null Mon Mar 21 00:25:03 2005 --- llvm/test/Regression/Verifier/2005-03-21-UndefinedTypeReference.ll Mon Mar 21 00:24:53 2005 *************** *** 0 **** --- 1,7 ---- + ; RUN: not llvm-as -f %s -o /dev/null + + void %test() { + malloc %InvalidType + ret void + } + From lattner at cs.uiuc.edu Mon Mar 21 00:27:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 00:27:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200503210627.j2L6Rt6H003461@apoc.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.216 -> 1.217 --- Log message: Remove a bunch of cruft and dead code for handling the case when types were defined in function constant pools. The assembler grammar has long disallowed functions from having constant pools, so all of this stuff is dead. This makes it an immediate error for functions to refer to nonexisting types, fixing Regression/Verifier/2005-03-21-UndefinedTypeReference.ll. Before, references to non-existing types in functions would only be detected when the subsequent function was parsed, due to the call to "ResolveTypes". "ResolveTypes" has not resolved any types for a long time, instead it emitted an error message if no resolved types are left. Since the only caller of this method is in the module code, just inline it. --- Diffs of the changes: (+31 -49) llvmAsmParser.y | 80 +++++++++++++++++++++----------------------------------- 1 files changed, 31 insertions(+), 49 deletions(-) Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.216 llvm/lib/AsmParser/llvmAsmParser.y:1.217 --- llvm/lib/AsmParser/llvmAsmParser.y:1.216 Mon Mar 14 22:54:18 2005 +++ llvm/lib/AsmParser/llvmAsmParser.y Mon Mar 21 00:27:42 2005 @@ -130,8 +130,6 @@ std::map Values; // Keep track of #'d definitions std::map LateResolveValues; - std::vector Types; - std::map LateResolveTypes; bool isDeclare; // Is this function a forward declararation? /// BBForwardRefs - When we see forward references to basic blocks, keep @@ -162,7 +160,6 @@ ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues); Values.clear(); // Clear out function local definitions - Types.clear(); // Clear out function local types CurrentFunction = 0; isDeclare = false; } @@ -208,18 +205,22 @@ // if (DoNotImprovise) return 0; // Do we just want a null to be returned? - std::map &LateResolver = inFunctionScope() ? - CurFun.LateResolveTypes : CurModule.LateResolveTypes; - - std::map::iterator I = LateResolver.find(D); - if (I != LateResolver.end()) { - return I->second; + + if (inFunctionScope()) { + if (D.Type == ValID::NameVal) + ThrowException("Reference to an undefined type: '" + D.getName() + "'"); + else + ThrowException("Reference to an undefined type: #" + itostr(D.Num)); } + std::map::iterator I =CurModule.LateResolveTypes.find(D); + if (I != CurModule.LateResolveTypes.end()) + return I->second; + Type *Typ = OpaqueType::get(); - LateResolver.insert(std::make_pair(D, Typ)); + CurModule.LateResolveTypes.insert(std::make_pair(D, Typ)); return Typ; -} + } static Value *lookupInSymbolTable(const Type *Ty, const std::string &Name) { SymbolTable &SymTab = @@ -473,34 +474,15 @@ // refering to the number can be resolved. Do this now. // static void ResolveTypeTo(char *Name, const Type *ToTy) { - std::vector &Types = inFunctionScope() ? - CurFun.Types : CurModule.Types; - - ValID D; - if (Name) D = ValID::create(Name); - else D = ValID::create((int)Types.size()); - - std::map &LateResolver = inFunctionScope() ? - CurFun.LateResolveTypes : CurModule.LateResolveTypes; - - std::map::iterator I = LateResolver.find(D); - if (I != LateResolver.end()) { - ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); - LateResolver.erase(I); - } -} - -// ResolveTypes - At this point, all types should be resolved. Any that aren't -// are errors. -// -static void ResolveTypes(std::map &LateResolveTypes) { - if (!LateResolveTypes.empty()) { - const ValID &DID = LateResolveTypes.begin()->first; - - if (DID.Type == ValID::NameVal) - ThrowException("Reference to an invalid type: '" +DID.getName() + "'"); - else - ThrowException("Reference to an invalid type: #" + itostr(DID.Num)); + ValID D; + if (Name) D = ValID::create(Name); + else D = ValID::create((int)CurModule.Types.size()); + + std::map::iterator I = + CurModule.LateResolveTypes.find(D); + if (I != CurModule.LateResolveTypes.end()) { + ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); + CurModule.LateResolveTypes.erase(I); } } @@ -1457,12 +1439,18 @@ } | ConstPool { $$ = CurModule.CurrentModule; - // Resolve circular types before we parse the body of the module - ResolveTypes(CurModule.LateResolveTypes); + // Emit an error if there are any unresolved types left. + if (!CurModule.LateResolveTypes.empty()) { + const ValID &DID = CurModule.LateResolveTypes.begin()->first; + if (DID.Type == ValID::NameVal) + ThrowException("Reference to an undefined type: '"+DID.getName() + "'"); + else + ThrowException("Reference to an undefined type: #" + itostr(DID.Num)); + } }; // ConstPool - Constants with optional names assigned to them. -ConstPool : ConstPool OptAssign TYPE TypesV { // Types can be defined in the const pool +ConstPool : ConstPool OptAssign TYPE TypesV { // Eagerly resolve types. This is not an optimization, this is a // requirement that is due to the fact that we could have this: // @@ -1477,10 +1465,7 @@ if (!setTypeName(*$4, $2) && !$2) { // If this is a named type that is not a redefinition, add it to the slot // table. - if (inFunctionScope()) - CurFun.Types.push_back(*$4); - else - CurModule.Types.push_back(*$4); + CurModule.Types.push_back(*$4); } delete $4; @@ -1664,9 +1649,6 @@ // Make sure that we keep track of the linkage type even if there was a // previous "declare". $$->setLinkage($1); - - // Resolve circular types before we parse the body of the function. - ResolveTypes(CurFun.LateResolveTypes); }; END : ENDTOK | '}'; // Allow end of '}' to end a function From lattner at cs.uiuc.edu Mon Mar 21 02:43:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 02:43:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Message-ID: <200503210843.j2L8hnGi004100@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: TopDownClosure.cpp updated: 1.80 -> 1.81 --- Log message: 'note to self' --- Diffs of the changes: (+5 -2) TopDownClosure.cpp | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.80 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.81 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.80 Sun Mar 20 22:55:35 2005 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Mon Mar 21 02:43:32 2005 @@ -188,8 +188,11 @@ std::sort(EdgesFromCaller.begin(), EdgesFromCaller.end()); - // Merge information from the globals graph into this graph. - // FIXME: is this necessary? + // Merge information from the globals graph into this graph. FIXME: This is + // stupid. Instead of us cloning information from the GG into this graph, + // then having RemoveDeadNodes clone it back, we should do all of this as a + // post-pass over all of the graphs. We need to take cloning out of + // removeDeadNodes and gut removeDeadNodes at the same time first though. :( { DSGraph &GG = *DSG.getGlobalsGraph(); ReachabilityCloner RC(DSG, GG, From lattner at cs.uiuc.edu Mon Mar 21 03:18:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 03:18:56 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSSupport.h Message-ID: <200503210918.j2L9IuZ0004514@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSSupport.h updated: 1.37 -> 1.38 --- Log message: If merging two calls like: foo(A) and bar(B, C), make sure the result has two arguments, not one. --- Diffs of the changes: (+3 -0) DSSupport.h | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/include/llvm/Analysis/DataStructure/DSSupport.h diff -u llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.37 llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.38 --- llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.37 Tue Mar 15 11:51:51 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSSupport.h Mon Mar 21 03:18:39 2005 @@ -292,6 +292,9 @@ for (unsigned a = 0; a != MinArgs; ++a) getPtrArg(a).mergeWith(CS.getPtrArg(a)); + + for (unsigned a = MinArgs, e = CS.getNumPtrArgs(); a != e; ++a) + CallArgs.push_back(CS.getPtrArg(a)); } /// markReachableNodes - This method recursively traverses the specified From lattner at cs.uiuc.edu Mon Mar 21 03:38:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 03:38:55 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSSupport.h Message-ID: <200503210938.j2L9ctQq005309@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSSupport.h updated: 1.38 -> 1.39 --- Log message: add a method --- Diffs of the changes: (+4 -0) DSSupport.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/Analysis/DataStructure/DSSupport.h diff -u llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.38 llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.39 --- llvm/include/llvm/Analysis/DataStructure/DSSupport.h:1.38 Mon Mar 21 03:18:39 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSSupport.h Mon Mar 21 03:38:39 2005 @@ -272,6 +272,10 @@ return CallArgs[i]; } + void addPtrArg(const DSNodeHandle &NH) { + CallArgs.push_back(NH); + } + void swap(DSCallSite &CS) { if (this != &CS) { std::swap(Site, CS.Site); From lattner at cs.uiuc.edu Mon Mar 21 03:39:34 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 03:39:34 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503210939.j2L9dYuw005330@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.96 -> 1.97 --- Log message: Make the first operand of this method be modifiable. --- Diffs of the changes: (+1 -1) DSGraph.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.96 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.97 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.96 Sat Mar 19 22:30:16 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 03:39:20 2005 @@ -560,7 +560,7 @@ /// 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); + void mergeCallSite(DSCallSite &DestCS, const DSCallSite &SrcCS); bool clonedAnyNodes() const { return !NodeMap.empty(); } From lattner at cs.uiuc.edu Mon Mar 21 03:40:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 03:40:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503210940.j2L9e58B005346@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.215 -> 1.216 --- Log message: The reachability cloner should add arguments to merged calls when the RHS of the merge has more operands than the LHS. --- Diffs of the changes: (+4 -1) DataStructure.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.215 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.216 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.215 Sat Mar 19 22:30:30 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 03:39:51 2005 @@ -1087,7 +1087,7 @@ /// mergeCallSite - Merge the nodes reachable from the specified src call /// site into the nodes reachable from DestCS. -void ReachabilityCloner::mergeCallSite(const DSCallSite &DestCS, +void ReachabilityCloner::mergeCallSite(DSCallSite &DestCS, const DSCallSite &SrcCS) { merge(DestCS.getRetVal(), SrcCS.getRetVal()); unsigned MinArgs = DestCS.getNumPtrArgs(); @@ -1095,6 +1095,9 @@ for (unsigned a = 0; a != MinArgs; ++a) merge(DestCS.getPtrArg(a), SrcCS.getPtrArg(a)); + + for (unsigned a = MinArgs, e = SrcCS.getNumPtrArgs(); a != e; ++a) + DestCS.addPtrArg(getClonedNH(SrcCS.getPtrArg(a))); } From lattner at cs.uiuc.edu Mon Mar 21 04:00:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 04:00:50 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503211000.j2LA0orH005773@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.97 -> 1.98 --- Log message: Ugh, for some reason, I can't call this unless the reference is const!?!?!? --- Diffs of the changes: (+1 -1) DSGraph.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.97 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.98 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.97 Mon Mar 21 03:39:20 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 04:00:34 2005 @@ -560,7 +560,7 @@ /// mergeCallSite - Merge the nodes reachable from the specified src call /// site into the nodes reachable from DestCS. /// - void mergeCallSite(DSCallSite &DestCS, const DSCallSite &SrcCS); + void mergeCallSite(const DSCallSite &DestCS, const DSCallSite &SrcCS); bool clonedAnyNodes() const { return !NodeMap.empty(); } From lattner at cs.uiuc.edu Mon Mar 21 04:00:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 04:00:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503211000.j2LA0xqY005783@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.216 -> 1.217 --- Log message: Ugh, for some reason, I can't call this unless the reference is const!?!?!? --- Diffs of the changes: (+2 -2) DataStructure.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.216 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.217 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.216 Mon Mar 21 03:39:51 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 04:00:45 2005 @@ -1087,7 +1087,7 @@ /// mergeCallSite - Merge the nodes reachable from the specified src call /// site into the nodes reachable from DestCS. -void ReachabilityCloner::mergeCallSite(DSCallSite &DestCS, +void ReachabilityCloner::mergeCallSite(const DSCallSite &DestCS, const DSCallSite &SrcCS) { merge(DestCS.getRetVal(), SrcCS.getRetVal()); unsigned MinArgs = DestCS.getNumPtrArgs(); @@ -1097,7 +1097,7 @@ merge(DestCS.getPtrArg(a), SrcCS.getPtrArg(a)); for (unsigned a = MinArgs, e = SrcCS.getNumPtrArgs(); a != e; ++a) - DestCS.addPtrArg(getClonedNH(SrcCS.getPtrArg(a))); + const_cast(DestCS).addPtrArg(getClonedNH(SrcCS.getPtrArg(a))); } From alkis at cs.uiuc.edu Mon Mar 21 04:04:04 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 21 Mar 2005 04:04:04 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503211004.EAA21315@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.237 -> 1.238 --- Log message: Fix static field lookup algorithm as per the java vm spec --- Diffs of the changes: (+39 -19) Compiler.cpp | 58 +++++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 39 insertions(+), 19 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.237 llvm-java/lib/Compiler/Compiler.cpp:1.238 --- llvm-java/lib/Compiler/Compiler.cpp:1.237 Sun Mar 20 17:23:58 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Mon Mar 21 04:03:52 2005 @@ -1202,28 +1202,48 @@ ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); - std::string className = fieldRef->getClass()->getName()->str(); - - while (true) { - // Get ClassInfo for class owning the field - this will force - // the globals to be initialized. - const ClassFile* cf = ClassFile::get(className); - getClassInfo(cf); - - std::string globalName = - className + '/' + nameAndType->getName()->str(); - - DEBUG(std::cerr << "Looking up global: " << globalName << '\n'); - GlobalVariable* global = module_.getGlobalVariable - (globalName, getType(nameAndType->getDescriptor())); - if (global) + const std::string& className = fieldRef->getClass()->getName()->str(); + GlobalVariable* global = + getStaticField(ClassFile::get(className), + nameAndType->getName()->str(), + getType(nameAndType->getDescriptor())); + + assert(global && "Cannot find global for static field!"); + + return global; + } + + /// Finds a static field in the specified class, any of its + /// super clases, or any of the interfaces it implements. + GlobalVariable* getStaticField(const ClassFile* cf, + const std::string& name, + const Type* type) { + // Emit the static initializers for this class, making sure that + // the globals are inserted into the module. + emitStaticInitializers(cf); + const std::string& className = cf->getThisClass()->getName()->str(); + const std::string& globalName = className + '/' + name; + + DEBUG(std::cerr << "Looking up global: " << globalName << '\n'); + GlobalVariable* global = module_.getGlobalVariable(globalName, type); + if (global) + return global; + + const Classes& ifaces = cf->getInterfaces(); + for (unsigned i = 0, e = ifaces.size(); i != e; ++i) { + const ClassFile* ifaceCF = ClassFile::get(ifaces[i]->getName()->str()); + if (global = getStaticField(ifaceCF, name, type)) return global; - - assert(cf->getSuperClass() && "Cannot find global for static field!"); - className = cf->getSuperClass()->getName()->str(); } - return NULL; // never reached + // If we have no super class it means the lookup terminates + // unsuccesfully. + if (!cf->getSuperClass()) + return NULL; + + const ClassFile* superCF = + ClassFile::get(cf->getSuperClass()->getName()->str()); + return getStaticField(superCF, name, type); } /// Emits the necessary code to get a field from the passed From lattner at cs.uiuc.edu Mon Mar 21 11:55:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 11:55:57 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2003-12-30-TypeMapInvalidMemory.llx Message-ID: <200503211755.j2LHtvVf008747@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2003-12-30-TypeMapInvalidMemory.llx updated: 1.1 -> 1.2 --- Log message: This error message changed. --- Diffs of the changes: (+1 -1) 2003-12-30-TypeMapInvalidMemory.llx | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/Assembler/2003-12-30-TypeMapInvalidMemory.llx diff -u llvm/test/Regression/Assembler/2003-12-30-TypeMapInvalidMemory.llx:1.1 llvm/test/Regression/Assembler/2003-12-30-TypeMapInvalidMemory.llx:1.2 --- llvm/test/Regression/Assembler/2003-12-30-TypeMapInvalidMemory.llx:1.1 Tue Dec 30 21:24:14 2003 +++ llvm/test/Regression/Assembler/2003-12-30-TypeMapInvalidMemory.llx Mon Mar 21 11:55:41 2005 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s 2>&1 | grep 'Reference to an invalid type' +; RUN: llvm-as < %s 2>&1 | grep 'Reference to an undefined type' %d_reduction_0_dparser_gram = global { int (sbyte*, sbyte**, int, int, { %struct.Grammar*, void (\4, %struct.d_loc_t*, sbyte**)*, %struct.D_Scope*, void (\4)*, { int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\8, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }* (\4, int, { int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\9, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }**)*, void ({ int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\8, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }*)*, %struct.d_loc_t, int, int, int, int, int, int, int, int, int, int, int, int }*)*, int (sbyte*, sbyte**, int, int, { %struct.Grammar*, void (\4, %struct.d_loc_t*, sbyte**)*, %struct.D_Scope*, void (\4)*, { int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\8, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }* (\4, int, { int, %struct.d_loc_t, sbyt! e*, sbyte*, %struct.D_Scope*, void (\9, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }**)*, void ({ int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\8, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }*)*, %struct.d_loc_t, int, int, int, int, int, int, int, int, int, int, int, int }*)** } { int (sbyte*, sbyte**, int, int, { %struct.Grammar*, void (\4, %struct.d_loc_t*, sbyte**)*, %struct.D_Scope*, void (\4)*, { int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\8, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }* (\4, int, { int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\9, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }**)*, void ({ int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\8, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }*)*, %struct.d_loc_t, int, int, int, int, int, int, int, int, int, int, i! nt, int }*)* null, int (sbyte*, sbyte**, int, int, { %struct.G! rammar*, void (\4, %struct.d_loc_t*, sbyte**)*, %struct.D_Scope*, void (\4)*, { int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\8, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }* (\4, int, { int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\9, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }**)*, void ({ int, %struct.d_loc_t, sbyte*, sbyte*, %struct.D_Scope*, void (\8, %struct.d_loc_t*, sbyte**)*, %struct.Grammar*, %struct.ParseNode_User }*)*, %struct.d_loc_t, int, int, int, int, int, int, int, int, int, int, int, int }*)** null } From brukman at cs.uiuc.edu Mon Mar 21 13:22:25 2005 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 21 Mar 2005 13:22:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <200503211922.NAA24682@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.123 -> 1.124 --- Log message: We may be adding functions to the Module during initialization, so conservatively, it's modified --- Diffs of the changes: (+2 -2) PPC32ISelSimple.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.123 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.124 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.123 Mon Mar 14 22:54:19 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Mon Mar 21 13:22:14 2005 @@ -109,7 +109,7 @@ Target(tgt), Insert(ins), Shift(s), MB(b), ME(e) {} }; - // External functions used in the Module + // External functions we may use in compiling the Module Function *fmodfFn, *fmodFn, *__cmpdi2Fn, *__moddi3Fn, *__divdi3Fn, *__umoddi3Fn, *__udivdi3Fn, *__fixsfdiFn, *__fixdfdiFn, *__fixunssfdiFn, *__fixunsdfdiFn, *__floatdisfFn, *__floatdidfFn, *mallocFn, *freeFn; @@ -182,7 +182,7 @@ mallocFn = M.getOrInsertFunction("malloc", voidPtr, Type::UIntTy, 0); // void free(void*) freeFn = M.getOrInsertFunction("free", Type::VoidTy, voidPtr, 0); - return false; + return true; } /// runOnFunction - Top level implementation of instruction selection for From alkis at cs.uiuc.edu Mon Mar 21 13:49:10 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 21 Mar 2005 13:49:10 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Transforms/AddStubs.cpp Message-ID: <200503211949.NAA24970@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Transforms: AddStubs.cpp updated: 1.5 -> 1.6 --- Log message: Add stubs for gnu.* methods as well. --- Diffs of the changes: (+3 -1) AddStubs.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm-java/lib/Transforms/AddStubs.cpp diff -u llvm-java/lib/Transforms/AddStubs.cpp:1.5 llvm-java/lib/Transforms/AddStubs.cpp:1.6 --- llvm-java/lib/Transforms/AddStubs.cpp:1.5 Tue Mar 15 01:24:39 2005 +++ llvm-java/lib/Transforms/AddStubs.cpp Mon Mar 21 13:48:59 2005 @@ -32,7 +32,9 @@ struct AddStubs : public ModulePass { virtual bool runOnModule(Module &M) { for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) - if (F->empty() && F->getName().find("java") != std::string::npos) { + if (F->empty() && + (F->getName().find("java") != std::string::npos || + F->getName().find("gnu") != std::string::npos)) { DEBUG(std::cerr << "Stubbing out: " << F->getName() << '\n'); BasicBlock* entry = new BasicBlock("entry", F); if (F->getReturnType() == Type::VoidTy) From alkis at cs.uiuc.edu Mon Mar 21 13:51:06 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 21 Mar 2005 13:51:06 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/AbstractClassDoesNotImplementInterface.java Message-ID: <200503211951.NAA25047@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: AbstractClassDoesNotImplementInterface.java updated: 1.1 -> 1.2 --- Log message: Make test case print something so that we can compare outputs. --- Diffs of the changes: (+3 -2) AbstractClassDoesNotImplementInterface.java | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm-java/test/Programs/SingleSource/UnitTests/AbstractClassDoesNotImplementInterface.java diff -u llvm-java/test/Programs/SingleSource/UnitTests/AbstractClassDoesNotImplementInterface.java:1.1 llvm-java/test/Programs/SingleSource/UnitTests/AbstractClassDoesNotImplementInterface.java:1.2 --- llvm-java/test/Programs/SingleSource/UnitTests/AbstractClassDoesNotImplementInterface.java:1.1 Sun Mar 20 16:56:25 2005 +++ llvm-java/test/Programs/SingleSource/UnitTests/AbstractClassDoesNotImplementInterface.java Mon Mar 21 13:50:55 2005 @@ -9,10 +9,11 @@ } private static class Concrete extends Abstract { - public void iMethod() { } + public void iMethod() { Test.println(12345); } } public static void main(String[] args) { - Abstract a = new Concrete(); + Interface i = new Concrete(); + i.iMethod(); } } From alkis at cs.uiuc.edu Mon Mar 21 14:01:14 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 21 Mar 2005 14:01:14 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503212001.OAA25233@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.238 -> 1.239 --- Log message: Add more classes so that we can compile java.lang.String. --- Diffs of the changes: (+32 -26) Compiler.cpp | 58 ++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 32 insertions(+), 26 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.238 llvm-java/lib/Compiler/Compiler.cpp:1.239 --- llvm-java/lib/Compiler/Compiler.cpp:1.238 Mon Mar 21 04:03:52 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Mon Mar 21 14:01:03 2005 @@ -1355,26 +1355,32 @@ assert (!method->isAbstract() && "Trying to compile an abstract method!"); // HACK: skip most of the class libraries. - if (classMethodDesc.find("java/") == 0 && - classMethodDesc.find("java/lang/Object") != 0 && - (classMethodDesc.find("java/lang/Throwable") != 0 || - classMethodDesc.find("java/lang/Throwable$StaticData/getConstantClass(index); - const ClassFile* cf = ClassFile::get(classRef->getName()->str()); const ClassInfo& ci = getObjectArrayInfo(); - const ClassInfo& ei = getClassInfo(cf); - const VTableInfo& vi = getObjectArrayVTableInfo(cf); + // FIXME: Need to do handle different element types. This now + // assumes that all arrays of references are arrays of + // java/lang/Object's. + const VTableInfo& vi = + getObjectArrayVTableInfo(ClassFile::get("java/lang/Object")); - const Type* elementTy = PointerType::get(ei.getType()); - push(allocateArray(ci, elementTy, vi, count, currentBB_)); + push(allocateArray(ci, ObjectBaseRefTy, vi, count, currentBB_)); } void do_arraylength() { From lattner at cs.uiuc.edu Mon Mar 21 14:19:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 14:19:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/DSGraph/FunctionPointerTable-const.ll Message-ID: <200503212019.j2LKJ8A6010733@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: FunctionPointerTable-const.ll added (r1.1) --- Log message: New testcase, which is important to handle correctly. --- Diffs of the changes: (+27 -0) FunctionPointerTable-const.ll | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+) Index: llvm/test/Regression/Analysis/DSGraph/FunctionPointerTable-const.ll diff -c /dev/null llvm/test/Regression/Analysis/DSGraph/FunctionPointerTable-const.ll:1.1 *** /dev/null Mon Mar 21 14:19:02 2005 --- llvm/test/Regression/Analysis/DSGraph/FunctionPointerTable-const.ll Mon Mar 21 14:18:51 2005 *************** *** 0 **** --- 1,27 ---- + ; RUN: analyze %s -datastructure-gc -dsgc-dspass=bu -dsgc-check-flags=Y:SHM && \ + ; RUN: analyze %s -datastructure-gc -dsgc-dspass=td -dsgc-check-flags=P1:SHM,P2:SHM + + %G = internal constant [2 x int*(int*)*] [ + int*(int*)* %callee1, int*(int*)* %callee2 + ] + + implementation + + internal int* %callee1(int* %P1) { + ret int* %P1 + } + + internal int* %callee2(int* %P2) { + %X = malloc int + ret int* %X + } + + void %caller(int %callee) { + %FPP = getelementptr [2 x int*(int*)*]* %G, int 0, int %callee + %FP = load int*(int*)** %FPP + + %Y = alloca int + %Z = call int* %FP(int* %Y) + store int 4, int* %Z + ret void + } From lattner at cs.uiuc.edu Mon Mar 21 14:21:02 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 14:21:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Message-ID: <200503212021.j2LKL2Dv010790@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.101 -> 1.102 --- Log message: Fix a major problem where we didn't add call graph edges for call sites with more than 1 callee. This fixes Analysis/DSGraph/FunctionPointerTable-const.ll --- Diffs of the changes: (+10 -6) BottomUpClosure.cpp | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.101 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.102 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.101 Sat Mar 19 22:29:39 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Mon Mar 21 14:20:49 2005 @@ -354,11 +354,11 @@ continue; } else { DSGraph *GI; + Instruction *TheCall = CS.getCallSite().getInstruction(); if (CalledFuncs.size() == 1) { Function *Callee = CalledFuncs[0]; - ActualCallees.insert(std::make_pair(CS.getCallSite().getInstruction(), - Callee)); + ActualCallees.insert(std::make_pair(TheCall, Callee)); // Get the data structure graph for the called function. GI = &getDSGraph(*Callee); // Graph to inline @@ -378,12 +378,16 @@ std::cerr << " calls " << CalledFuncs.size() << " fns from site: " << CS.getCallSite().getInstruction() << " " << *CS.getCallSite().getInstruction(); - unsigned NumToPrint = CalledFuncs.size(); - if (NumToPrint > 8) NumToPrint = 8; std::cerr << " Fns ="; + unsigned NumPrinted = 0; + for (std::vector::iterator I = CalledFuncs.begin(), - E = CalledFuncs.end(); I != E && NumToPrint; ++I, --NumToPrint) - std::cerr << " " << (*I)->getName(); + E = CalledFuncs.end(); I != E; ++I) { + if (NumPrinted++ < 8) std::cerr << " " << (*I)->getName(); + + // Add the call edges to the call graph. + ActualCallees.insert(std::make_pair(TheCall, *I)); + } std::cerr << "\n"; // See if we already computed a graph for this set of callees. From lattner at cs.uiuc.edu Mon Mar 21 14:28:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 14:28:54 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503212028.j2LKSsDD011440@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.98 -> 1.99 --- Log message: make this const correct --- Diffs of the changes: (+1 -1) DSGraph.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.98 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.99 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.98 Mon Mar 21 04:00:34 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 14:28:40 2005 @@ -560,7 +560,7 @@ /// 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); + void mergeCallSite(DSCallSite &DestCS, const DSCallSite &SrcCS); bool clonedAnyNodes() const { return !NodeMap.empty(); } From lattner at cs.uiuc.edu Mon Mar 21 14:29:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 14:29:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503212029.j2LKT3eJ011456@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.217 -> 1.218 --- Log message: make this const correct --- Diffs of the changes: (+2 -2) DataStructure.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.217 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.218 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.217 Mon Mar 21 04:00:45 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 14:28:50 2005 @@ -1087,7 +1087,7 @@ /// mergeCallSite - Merge the nodes reachable from the specified src call /// site into the nodes reachable from DestCS. -void ReachabilityCloner::mergeCallSite(const DSCallSite &DestCS, +void ReachabilityCloner::mergeCallSite(DSCallSite &DestCS, const DSCallSite &SrcCS) { merge(DestCS.getRetVal(), SrcCS.getRetVal()); unsigned MinArgs = DestCS.getNumPtrArgs(); @@ -1097,7 +1097,7 @@ merge(DestCS.getPtrArg(a), SrcCS.getPtrArg(a)); for (unsigned a = MinArgs, e = SrcCS.getNumPtrArgs(); a != e; ++a) - const_cast(DestCS).addPtrArg(getClonedNH(SrcCS.getPtrArg(a))); + DestCS.addPtrArg(getClonedNH(SrcCS.getPtrArg(a))); } From lattner at cs.uiuc.edu Mon Mar 21 14:30:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 14:30:09 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DataStructure.h Message-ID: <200503212030.j2LKU9AF011512@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DataStructure.h updated: 1.87 -> 1.88 --- Log message: add a new map --- Diffs of the changes: (+8 -0) DataStructure.h | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/include/llvm/Analysis/DataStructure/DataStructure.h diff -u llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.87 llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.88 --- llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.87 Sun Mar 20 22:46:35 2005 +++ llvm/include/llvm/Analysis/DataStructure/DataStructure.h Mon Mar 21 14:29:56 2005 @@ -201,6 +201,14 @@ std::map > CallerEdges; + + // IndCallMap - We memoize the results of indirect call inlining operations + // that have multiple targets here to avoid N*M inlining. The key to the map + // is a sorted set of callee functions, the value is the DSGraph that holds + // all of the caller graphs merged together, and the DSCallSite to merge with + // the arguments for each function. + std::map, DSGraph*> IndCallMap; + public: ~TDDataStructures() { releaseMyMemory(); } From lattner at cs.uiuc.edu Mon Mar 21 14:31:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 14:31:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Message-ID: <200503212031.j2LKVgqo012147@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: TopDownClosure.cpp updated: 1.81 -> 1.82 --- Log message: Enhance the TD pass to build composite graphs when we have indirect call sites that target multiple callees. If we have a function table, for example, with N callees, and M callers call through it, we used to have to perform O(M*N) graph inlinings. Now we perform O(M+N) inlinings. This speeds up the td pass on perlbmk from 36.26s to 25.75s. --- Diffs of the changes: (+108 -17) TopDownClosure.cpp | 125 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 108 insertions(+), 17 deletions(-) Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.81 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.82 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.81 Mon Mar 21 02:43:32 2005 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Mon Mar 21 14:31:29 2005 @@ -62,9 +62,11 @@ const DSScalarMap &GGSM = GlobalsGraph->getScalarMap(); hash_set Visited; for (DSScalarMap::global_iterator I=GGSM.global_begin(), E=GGSM.global_end(); - I != E; ++I) - markReachableFunctionsExternallyAccessible(GGSM.find(*I)->second.getNode(), - Visited); + I != E; ++I) { + DSNode *N = GGSM.find(*I)->second.getNode(); + if (N->isIncomplete()) + markReachableFunctionsExternallyAccessible(N, Visited); + } // Loop over unresolved call nodes. Any functions passed into (but not // returned!) from unresolvable call nodes may be invoked outside of the @@ -104,6 +106,13 @@ PostOrder.pop_back(); } + // Free the IndCallMap. + while (!IndCallMap.empty()) { + delete IndCallMap.begin()->second; + IndCallMap.erase(IndCallMap.begin()); + } + + ArgsRemainIncomplete.clear(); GlobalsGraph->removeTriviallyDeadNodes(); @@ -202,8 +211,6 @@ GI = DSG.getScalarMap().global_begin(), E = DSG.getScalarMap().global_end(); GI != E; ++GI) RC.getClonedNH(GG.getNodeForValue(*GI)); - - } DEBUG(std::cerr << "[TD] Inlining callers into '" << DSG.getFunctionNames() @@ -223,16 +230,21 @@ do { const DSCallSite &CS = *EdgesFromCaller.back().CS; Function &CF = *EdgesFromCaller.back().CalledFunction; - DEBUG(std::cerr << " [TD] Inlining graph for call to Fn '" - << CF.getName() << "' from Fn '" - << CS.getCallSite().getInstruction()-> - getParent()->getParent()->getName() - << "': " << CF.getFunctionType()->getNumParams() + DEBUG(std::cerr << " [TD] Inlining graph into Fn '" + << CF.getName() << "' from "); + if (CallerGraph.getReturnNodes().empty()) + DEBUG(std::cerr << "SYNTHESIZED INDIRECT GRAPH"); + else + DEBUG (std::cerr << "Fn '" + << CS.getCallSite().getInstruction()-> + getParent()->getParent()->getName() << "'"); + DEBUG(std::cerr << ": " << CF.getFunctionType()->getNumParams() << " args\n"); // Get the formal argument and return nodes for the called function and // merge them with the cloned subgraph. - RC.mergeCallSite(DSG.getCallSiteForArguments(CF), CS); + DSCallSite T1 = DSG.getCallSiteForArguments(CF); + RC.mergeCallSite(T1, CS); ++NumTDInlines; EdgesFromCaller.pop_back(); @@ -276,19 +288,98 @@ // edges to the CallerEdges structure for each callee. for (DSGraph::fc_iterator CI = DSG.fc_begin(), E = DSG.fc_end(); CI != E; ++CI) { + + // Handle direct calls efficiently. + if (CI->isDirectCall()) { + if (!CI->getCalleeFunc()->isExternal() && + !DSG.getReturnNodes().count(CI->getCalleeFunc())) + CallerEdges[&getDSGraph(*CI->getCalleeFunc())] + .push_back(CallerCallEdge(&DSG, &*CI, CI->getCalleeFunc())); + continue; + } + Instruction *CallI = CI->getCallSite().getInstruction(); // For each function in the invoked function list at this call site... std::pair IP = ActualCallees.equal_range(CallI); - // Loop over each actual callee at this call site + + // Skip over all calls to this graph (SCC calls). + while (IP.first != IP.second && &getDSGraph(*IP.first->second) == &DSG) + ++IP.first; + + // All SCC calls? + if (IP.first == IP.second) continue; + + Function *FirstCallee = IP.first->second; + ++IP.first; + + // Skip over more SCC calls. + while (IP.first != IP.second && &getDSGraph(*IP.first->second) == &DSG) + ++IP.first; + + // If there is exactly one callee from this call site, remember the edge in + // CallerEdges. + if (IP.first == IP.second) { + if (!FirstCallee->isExternal()) + CallerEdges[&getDSGraph(*FirstCallee)] + .push_back(CallerCallEdge(&DSG, &*CI, FirstCallee)); + continue; + } + + // Otherwise, there are multiple callees from this call site, so it must be + // an indirect call. Chances are that there will be other call sites with + // this set of targets. If so, we don't want to do M*N inlining operations, + // so we build up a new, private, graph that represents the calls of all + // calls to this set of functions. + std::vector Callees; + IP = ActualCallees.equal_range(CallI); for (BUDataStructures::ActualCalleesTy::const_iterator I = IP.first; - I != IP.second; ++I) { - DSGraph& CalleeGraph = getDSGraph(*I->second); - if (&CalleeGraph != &DSG) - CallerEdges[&CalleeGraph].push_back(CallerCallEdge(&DSG, &*CI, - I->second)); + I != IP.second; ++I) + if (!I->second->isExternal()) + Callees.push_back(I->second); + std::sort(Callees.begin(), Callees.end()); + + std::map, DSGraph*>::iterator IndCallRecI = + IndCallMap.lower_bound(Callees); + + DSGraph *IndCallGraph; + + // If we already have this graph, recycle it. + if (IndCallRecI != IndCallMap.end() && IndCallRecI->first == Callees) { + std::cerr << " [TD] *** Reuse of indcall graph for " << Callees.size() + << " callees!\n"; + IndCallGraph = IndCallRecI->second; + } else { + // Otherwise, create a new DSGraph to represent this. + IndCallGraph = new DSGraph(DSG.getGlobalECs(), DSG.getTargetData()); + + // Make a nullary dummy call site, which will eventually get some content + // merged into it. The actual callee function doesn't matter here, so we + // just pass it something to keep the ctor happy. + std::vector ArgDummyVec; + DSCallSite DummyCS(CI->getCallSite(), DSNodeHandle(), Callees[0]/*dummy*/, + ArgDummyVec); + IndCallGraph->getFunctionCalls().push_back(DummyCS); + + IndCallRecI = IndCallMap.insert(IndCallRecI, + std::make_pair(Callees, IndCallGraph)); + + // Additionally, make sure that each of the callees inlines this graph + // exactly once. + DSCallSite *NCS = &IndCallGraph->getFunctionCalls().front(); + for (unsigned i = 0, e = Callees.size(); i != e; ++i) { + DSGraph& CalleeGraph = getDSGraph(*Callees[i]); + if (&CalleeGraph != &DSG) + CallerEdges[&CalleeGraph].push_back(CallerCallEdge(IndCallGraph, NCS, + Callees[i])); + } } + + // Now that we know which graph to use for this, merge the caller + // information into the graph, based on information from the call site. + ReachabilityCloner RC(*IndCallGraph, DSG, 0); + RC.mergeCallSite(IndCallGraph->getFunctionCalls().front(), *CI); } } From alkis at cs.uiuc.edu Mon Mar 21 14:55:33 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 21 Mar 2005 14:55:33 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/StringConcat.java Message-ID: <200503212055.OAA25906@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: StringConcat.java added (r1.1) --- Log message: Add string concatenation test --- Diffs of the changes: (+10 -0) StringConcat.java | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm-java/test/Programs/SingleSource/UnitTests/StringConcat.java diff -c /dev/null llvm-java/test/Programs/SingleSource/UnitTests/StringConcat.java:1.1 *** /dev/null Mon Mar 21 14:55:32 2005 --- llvm-java/test/Programs/SingleSource/UnitTests/StringConcat.java Mon Mar 21 14:55:22 2005 *************** *** 0 **** --- 1,10 ---- + public class StringConcat { + public static void main(String[] args) { + String foo = "foo"; + Test.println(foo); + String bar = "bar"; + Test.println(bar); + String foobar = foo + bar; + Test.println(foobar); + } + } From alkis at cs.uiuc.edu Mon Mar 21 14:56:20 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 21 Mar 2005 14:56:20 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/StringConcat.java Message-ID: <200503212056.OAA25919@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: StringConcat.java (r1.1) removed --- Log message: There is a test already for string concatenation --- Diffs of the changes: (+0 -0) 0 files changed From alkis at cs.uiuc.edu Mon Mar 21 14:59:27 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon, 21 Mar 2005 14:59:27 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503212059.OAA25975@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.239 -> 1.240 --- Log message: Add String support. We finally have strings in the java frontend :-) --- Diffs of the changes: (+110 -13) Compiler.cpp | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 110 insertions(+), 13 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.239 llvm-java/lib/Compiler/Compiler.cpp:1.240 --- llvm-java/lib/Compiler/Compiler.cpp:1.239 Mon Mar 21 14:01:03 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Mon Mar 21 14:59:16 2005 @@ -66,12 +66,14 @@ std::auto_ptr bbBuilder_; std::list bbWorkList_; typedef std::map OpStackDepthMap; - OpStackDepthMap opStackDepthMap_; + OpStackDepthMap opStackDepthMap_; + typedef std::map StringMap; + StringMap stringMap_; BasicBlock* currentBB_; Locals locals_; OperandStack opStack_; Function *getVtable_, *setVtable_, *throw_, *isInstanceOf_, - *memset_; + *memcpy_, *memset_; typedef SetVector FunctionSet; FunctionSet toCompileFunctions_; @@ -161,6 +163,11 @@ isInstanceOf_ = module_.getOrInsertFunction( "llvm_java_is_instance_of", Type::IntTy, ObjectBaseRefTy, VTableBaseRefTy, NULL); + memcpy_ = module_.getOrInsertFunction( + "llvm.memcpy", Type::VoidTy, + PointerType::get(Type::SByteTy), + PointerType::get(Type::SByteTy), + Type::ULongTy, Type::UIntTy, NULL); memset_ = module_.getOrInsertFunction( "llvm.memset", Type::VoidTy, PointerType::get(Type::SByteTy), @@ -187,13 +194,103 @@ return false; } - /// Given a llvm::Java::Constant returns a llvm::Constant. - llvm::Constant* getConstant(Constant* c) { - if (dynamic_cast(c)) - // FIXME: should return a String object represeting this ConstantString - return ConstantPointerNull::get( - PointerType::get( - getClassInfo(ClassFile::get("java/lang/String")).getType())); + template + Value* createNewString(const std::string& str, InsertionPointTy* ip) { + // Create a new byte[] object and initialize it with the + // contents of this string constant. + Value* count = ConstantUInt::get(Type::UIntTy, str.size()); + Value* arrayRef = allocateArray(getPrimitiveArrayInfo(BYTE), + Type::SByteTy, + getPrimitiveArrayVTableInfo(BYTE), + count, + ip); + // Copy string data. + std::vector indices; + indices.reserve(3); + indices.push_back(ConstantUInt::get(Type::UIntTy, 0)); + indices.push_back(ConstantUInt::get(Type::UIntTy, 2)); + indices.push_back(ConstantUInt::get(Type::UIntTy, 0)); + Value* arrayData = new GetElementPtrInst(arrayRef, indices, TMP, ip); + llvm::Constant* init = ConstantArray::get(str); + GlobalVariable* chars = new GlobalVariable( + init->getType(), + true, + GlobalVariable::InternalLinkage, + init, + str + ".str", + &module_); + + std::vector params; + params.reserve(4); + params.clear(); + params.push_back(arrayData); + params.push_back(ConstantExpr::getPtrPtrFromArrayPtr(chars)); + params.push_back(new CastInst(count, Type::ULongTy, TMP, ip)); + params.push_back(ConstantUInt::get(Type::UIntTy, 0)); + new CallInst(memcpy_, params, "", ip); + + // Get class information for java/lang/String. + const ClassFile* cf = ClassFile::get("java/lang/String"); + const ClassInfo& ci = getClassInfo(cf); + const VTableInfo& vi = getVTableInfo(cf); + + // Create a new java/lang/String object. + Value* objRef = allocateObject(ci, vi, ip); + + // Initialize it: call java/lang/String/(byte[],int) + Method* method = getMethod("java/lang/String/([BI)V"); + Function* function = getFunction(method); + scheduleFunction(function); + + params.reserve(3); + params.clear(); + params.push_back(new CastInst(objRef, ObjectBaseRefTy, TMP, ip)); + params.push_back(new CastInst(arrayRef, ObjectBaseRefTy, TMP, ip)); + params.push_back(ConstantSInt::get(Type::IntTy, 0)); + new CallInst(function, params, "", ip); + + return objRef; + } + + Value* getConstantString(ConstantString* s) { + const std::string& str = s->getValue()->str(); + StringMap::iterator it = stringMap_.find(str); + if (it == stringMap_.end()) { + // Create the global variable for the string. + const Type* StringRefTy = PointerType::get( + getClassInfo(ClassFile::get("java/lang/String")).getType()); + GlobalVariable* stringGlobal = new GlobalVariable( + StringRefTy, + false, + GlobalVariable::ExternalLinkage, + llvm::Constant::getNullValue(StringRefTy), + str + ".java/lang/String", + &module_); + + // Insert this new string into the map. + it = stringMap_.insert(it, std::make_pair(str, stringGlobal)); + + // Get the static initializer function and get its one and + // only basic block to add code to. + Function* hook = module_.getOrInsertFunction(LLVM_JAVA_STATIC_INIT, + Type::VoidTy, 0); + Instruction* I = hook->front().getTerminator(); + assert(I && LLVM_JAVA_STATIC_INIT " should have a terminator!"); + + Value* newString = createNewString(str, I); + + // Store the string reference to the global variable. + new StoreInst(newString, stringGlobal, I); + } + + return new LoadInst(it->second, TMP, currentBB_); + } + + /// Given a llvm::Java::Constant returns a Value + /// (java/lang/Strings are not llvm::Constants). + Value* getConstant(Constant* c) { + if (ConstantString* s = dynamic_cast(c)) + return getConstantString(s); else if (ConstantInteger* i = dynamic_cast(c)) return ConstantSInt::get(Type::IntTy, i->getValue()); else if (ConstantFloat* f = dynamic_cast(c)) @@ -1498,9 +1595,9 @@ // final fields with static initializers. bool isConstant = field->isStatic(); llvm::Constant* init; - if (ConstantValueAttribute* cv = field->getConstantValueAttribute()) - init = - ConstantExpr::getCast(getConstant(cv->getValue()), globalTy); + if (field->getConstantValueAttribute() && + dyn_cast(getConstant(field->getConstantValueAttribute()->getValue()))) + init = ConstantExpr::getCast(dyn_cast(getConstant(field->getConstantValueAttribute()->getValue())), globalTy); else { init = llvm::Constant::getNullValue(globalTy); isConstant = false; @@ -2371,7 +2468,7 @@ void do_athrow() { Value* objRef = pop(ObjectBaseRefTy); - new CallInst(throw_, objRef, TMP, currentBB_); + new CallInst(throw_, objRef, "", currentBB_); new UnreachableInst(currentBB_); } From lattner at cs.uiuc.edu Mon Mar 21 16:50:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 16:50:01 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503212250.j2LMo1qf003086@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.99 -> 1.100 --- Log message: allow passing clone flags into the ctor --- Diffs of the changes: (+2 -1) DSGraph.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.99 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.100 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.99 Mon Mar 21 14:28:40 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 16:49:43 2005 @@ -234,7 +234,8 @@ // source. You need to set a new GlobalsGraph with the setGlobalsGraph // method. // - DSGraph(const DSGraph &DSG, EquivalenceClasses &ECs); + DSGraph(const DSGraph &DSG, EquivalenceClasses &ECs, + unsigned CloneFlags = 0); DSGraph(const DSGraph &DSG, NodeMapTy &NodeMap, EquivalenceClasses &ECs); ~DSGraph(); From lattner at cs.uiuc.edu Mon Mar 21 16:50:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 16:50:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503212250.j2LMo7ad003098@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.218 -> 1.219 --- Log message: allow passing clone flags down to cloneInto --- Diffs of the changes: (+3 -2) DataStructure.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.218 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.219 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.218 Mon Mar 21 14:28:50 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 16:49:53 2005 @@ -1136,11 +1136,12 @@ } -DSGraph::DSGraph(const DSGraph &G, EquivalenceClasses &ECs) +DSGraph::DSGraph(const DSGraph &G, EquivalenceClasses &ECs, + unsigned CloneFlags) : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { PrintAuxCalls = false; NodeMapTy NodeMap; - cloneInto(G, ScalarMap, ReturnNodes, NodeMap); + cloneInto(G, ScalarMap, ReturnNodes, NodeMap, CloneFlags); } DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap, From lattner at cs.uiuc.edu Mon Mar 21 18:04:37 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:04:37 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200503220004.j2M04bwc015184@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.49 -> 1.50 --- Log message: don't generate temporary scalarmaps. --- Diffs of the changes: (+5 -17) Steensgaard.cpp | 22 +++++----------------- 1 files changed, 5 insertions(+), 17 deletions(-) Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.49 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.50 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.49 Sat Mar 19 22:23:57 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Mon Mar 21 18:04:21 2005 @@ -127,27 +127,15 @@ // Loop over the rest of the module, merging graphs for non-external functions // into this graph. // - unsigned Count = 0; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) { - DSGraph::ScalarMapTy ValMap(GlobalECs); - { // Scope to free NodeMap memory ASAP - DSGraph::NodeMapTy NodeMap; - const DSGraph &FDSG = LDS.getDSGraph(*I); - ResultGraph->cloneInto(FDSG, ValMap, RetValMap, NodeMap, 0); - } - - // Incorporate the inlined Function's ScalarMap into the global - // ScalarMap... - DSGraph::ScalarMapTy &GVM = ResultGraph->getScalarMap(); - for (DSGraph::ScalarMapTy::iterator I = ValMap.begin(), - E = ValMap.end(); I != E; ++I) - GVM[I->first].mergeWith(I->second); - - if ((++Count & 1) == 0) // Prune nodes out every other time... - ResultGraph->removeTriviallyDeadNodes(); + DSGraph::NodeMapTy NodeMap; + ResultGraph->cloneInto(LDS.getDSGraph(*I), ResultGraph->getScalarMap(), + RetValMap, NodeMap, 0); } + ResultGraph->removeTriviallyDeadNodes(); + // FIXME: Must recalculate and use the Incomplete markers!! // Now that we have all of the graphs inlined, we can go about eliminating From lattner at cs.uiuc.edu Mon Mar 21 18:09:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:09:49 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503220009.j2M09neT015208@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.100 -> 1.101 --- Log message: move this stuff out of line --- Diffs of the changes: (+4 -15) DSGraph.h | 19 ++++--------------- 1 files changed, 4 insertions(+), 15 deletions(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.100 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.101 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.100 Mon Mar 21 16:49:43 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 18:09:36 2005 @@ -118,7 +118,6 @@ ValueMap.insert(std::make_pair(New, I->second)); } - /// operator[] - Return the DSNodeHandle for the specified value, creating a /// new null handle if there is no entry yet. DSNodeHandle &operator[](Value *V) { @@ -126,20 +125,8 @@ if (I != ValueMap.end()) return I->second; // Return value if already exists. - if (GlobalValue *GV = dyn_cast(V)) { - // If the node doesn't exist, check to see if it's a global that is - // equated to another global in the program. - EquivalenceClasses::iterator ECI = GlobalECs.findValue(GV); - if (ECI != GlobalECs.end()) { - GlobalValue *Leader = *GlobalECs.findLeader(ECI); - if (Leader != GV) - return operator[]((Value*)Leader); - } - - // Okay, this is either not an equivalenced global or it is the leader, it - // will be inserted into the scalar map now. - GlobalSet.insert(GV); - } + if (GlobalValue *GV = dyn_cast(V)) + return AddGlobal(GV); return ValueMap.insert(std::make_pair(V, DSNodeHandle())).first->second; } @@ -163,6 +150,8 @@ global_iterator global_end() const { return GlobalSet.end(); } unsigned global_size() const { return GlobalSet.size(); } unsigned global_count(GlobalValue *GV) const { return GlobalSet.count(GV); } +private: + DSNodeHandle &AddGlobal(GlobalValue *GV); }; From lattner at cs.uiuc.edu Mon Mar 21 18:09:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:09:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503220009.j2M09wM5015218@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.219 -> 1.220 --- Log message: move this out of line --- Diffs of the changes: (+28 -0) DataStructure.cpp | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.219 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.220 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.219 Mon Mar 21 16:49:53 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 18:09:45 2005 @@ -76,6 +76,34 @@ } //===----------------------------------------------------------------------===// +// DSScalarMap Implementation +//===----------------------------------------------------------------------===// + +DSNodeHandle &DSScalarMap::AddGlobal(GlobalValue *GV) { + assert(ValueMap.count(GV) == 0 && "GV already exists!"); + + // If the node doesn't exist, check to see if it's a global that is + // equated to another global in the program. + EquivalenceClasses::iterator ECI = GlobalECs.findValue(GV); + if (ECI != GlobalECs.end()) { + GlobalValue *Leader = *GlobalECs.findLeader(ECI); + if (Leader != GV) { + GV = Leader; + iterator I = ValueMap.find(GV); + if (I != ValueMap.end()) + return I->second; + } + } + + // Okay, this is either not an equivalenced global or it is the leader, it + // will be inserted into the scalar map now. + GlobalSet.insert(GV); + + return ValueMap.insert(std::make_pair(GV, DSNodeHandle())).first->second; +} + + +//===----------------------------------------------------------------------===// // DSNode Implementation //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Mon Mar 21 18:12:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:12:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Message-ID: <200503220012.j2M0CDEs015341@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: TopDownClosure.cpp updated: 1.82 -> 1.83 --- Log message: add some timers, don't clone aux nodes --- Diffs of the changes: (+29 -2) TopDownClosure.cpp | 31 +++++++++++++++++++++++++++++-- 1 files changed, 29 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.82 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.83 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.82 Mon Mar 21 14:31:29 2005 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Mon Mar 21 18:12:00 2005 @@ -19,9 +19,17 @@ #include "llvm/DerivedTypes.h" #include "llvm/Analysis/DataStructure/DSGraph.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Timer.h" #include "llvm/ADT/Statistic.h" using namespace llvm; +#if 0 +#define TIME_REGION(VARNAME, DESC) \ + NamedRegionTimer VARNAME(DESC) +#else +#define TIME_REGION(VARNAME, DESC) +#endif + namespace { RegisterAnalysis // Register the pass Y("tddatastructure", "Top-down Data Structure Analysis"); @@ -90,6 +98,20 @@ const BUDataStructures::ActualCalleesTy &ActualCallees = getAnalysis().getActualCallees(); +#if 0 +{TIME_REGION(XXX, "td:Copy graphs"); + + // Visit each of the graphs in reverse post-order now! + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isExternal()) + getOrCreateDSGraph(*I); +} +//return false; +#endif + + +{TIME_REGION(XXX, "td:Compute postorder"); + // Calculate top-down from main... if (Function *F = M.getMainFunction()) ComputePostOrder(*F, VisitedGraph, PostOrder, ActualCallees); @@ -99,12 +121,16 @@ ComputePostOrder(*I, VisitedGraph, PostOrder, ActualCallees); VisitedGraph.clear(); // Release memory! +} + +{TIME_REGION(XXX, "td:Inline stuff"); // Visit each of the graphs in reverse post-order now! while (!PostOrder.empty()) { InlineCallersIntoGraph(*PostOrder.back()); PostOrder.pop_back(); } +} // Free the IndCallMap. while (!IndCallMap.empty()) { @@ -123,8 +149,9 @@ DSGraph &TDDataStructures::getOrCreateDSGraph(Function &F) { DSGraph *&G = DSInfo[&F]; if (G == 0) { // Not created yet? Clone BU graph... - G = new DSGraph(getAnalysis().getDSGraph(F), GlobalECs); - G->getAuxFunctionCalls().clear(); + G = new DSGraph(getAnalysis().getDSGraph(F), GlobalECs, + DSGraph::DontCloneAuxCallNodes); + assert(G->getAuxFunctionCalls().empty() && "Cloned aux calls?"); G->setPrintAuxCalls(); G->setGlobalsGraph(GlobalsGraph); } From lattner at cs.uiuc.edu Mon Mar 21 18:21:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:21:12 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503220021.j2M0LC4I015543@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.101 -> 1.102 --- Log message: drop the second argument to cloneInto, which is always the local scalar map. --- Diffs of the changes: (+1 -1) DSGraph.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.101 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.102 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.101 Mon Mar 21 18:09:36 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 18:20:56 2005 @@ -454,7 +454,7 @@ /// /// The CloneFlags member controls various aspects of the cloning process. /// - void cloneInto(const DSGraph &G, ScalarMapTy &OldValMap, + void cloneInto(const DSGraph &G, ReturnNodesTy &OldReturnNodes, NodeMapTy &OldNodeMap, unsigned CloneFlags = 0); From lattner at cs.uiuc.edu Mon Mar 21 18:21:18 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:21:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp CompleteBottomUp.cpp DataStructure.cpp EquivClassGraphs.cpp Steensgaard.cpp Message-ID: <200503220021.j2M0LI2U015580@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.102 -> 1.103 CompleteBottomUp.cpp updated: 1.25 -> 1.26 DataStructure.cpp updated: 1.220 -> 1.221 EquivClassGraphs.cpp updated: 1.36 -> 1.37 Steensgaard.cpp updated: 1.50 -> 1.51 --- Log message: remove the second argument to cloneInto --- Diffs of the changes: (+14 -19) BottomUpClosure.cpp | 6 ++---- CompleteBottomUp.cpp | 2 +- DataStructure.cpp | 13 +++++++------ EquivClassGraphs.cpp | 9 +++------ Steensgaard.cpp | 3 +-- 5 files changed, 14 insertions(+), 19 deletions(-) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.102 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.103 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.102 Mon Mar 21 14:20:49 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Mon Mar 21 18:21:05 2005 @@ -269,8 +269,7 @@ if (&G != SCCGraph) { { DSGraph::NodeMapTy NodeMap; - SCCGraph->cloneInto(G, SCCGraph->getScalarMap(), - SCCGraph->getReturnNodes(), NodeMap); + SCCGraph->cloneInto(G, SCCGraph->getReturnNodes(), NodeMap); } // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = G.retnodes_begin(), @@ -414,8 +413,7 @@ // bother merging it in again. if (!GI->containsFunction(*I)) { DSGraph::NodeMapTy NodeMap; - GI->cloneInto(getDSGraph(**I), GI->getScalarMap(), - GI->getReturnNodes(), NodeMap); + GI->cloneInto(getDSGraph(**I), GI->getReturnNodes(), NodeMap); ++NumBUInlines; } Index: llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp diff -u llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.25 llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.26 --- llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.25 Sat Mar 19 22:29:39 2005 +++ llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp Mon Mar 21 18:21:05 2005 @@ -176,7 +176,7 @@ ValMap[NG] = ~0U; DSGraph::NodeMapTy NodeMap; - FG.cloneInto(*NG, FG.getScalarMap(), FG.getReturnNodes(), NodeMap); + FG.cloneInto(*NG, FG.getReturnNodes(), NodeMap); // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = NG->retnodes_begin(); Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.220 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.221 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.220 Mon Mar 21 18:09:45 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 18:21:05 2005 @@ -1169,14 +1169,14 @@ : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { PrintAuxCalls = false; NodeMapTy NodeMap; - cloneInto(G, ScalarMap, ReturnNodes, NodeMap, CloneFlags); + cloneInto(G, ReturnNodes, NodeMap, CloneFlags); } DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap, EquivalenceClasses &ECs) : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { PrintAuxCalls = false; - cloneInto(G, ScalarMap, ReturnNodes, NodeMap); + cloneInto(G, ReturnNodes, NodeMap); } DSGraph::~DSGraph() { @@ -1236,12 +1236,13 @@ /// cloneInto - Clone the specified DSGraph into the current graph. The -/// translated ScalarMap for the old function is filled into the OldValMap -/// member, and the translated ReturnNodes map is returned into ReturnNodes. +/// translated ScalarMap for the old function is filled into the ScalarMap +/// for the graph, and the translated ReturnNodes map is returned into +/// ReturnNodes. /// /// The CloneFlags member controls various aspects of the cloning process. /// -void DSGraph::cloneInto(const DSGraph &G, DSScalarMap &OldValMap, +void DSGraph::cloneInto(const DSGraph &G, ReturnNodesTy &OldReturnNodes, NodeMapTy &OldNodeMap, unsigned CloneFlags) { TIME_REGION(X, "cloneInto"); @@ -1281,7 +1282,7 @@ for (DSScalarMap::const_iterator I = G.ScalarMap.begin(), E = G.ScalarMap.end(); I != E; ++I) { DSNodeHandle &MappedNode = OldNodeMap[I->second.getNode()]; - DSNodeHandle &H = OldValMap[I->first]; + DSNodeHandle &H = ScalarMap[I->first]; DSNode *MappedNodeN = MappedNode.getNode(); H.mergeWith(DSNodeHandle(MappedNodeN, I->second.getOffset()+MappedNode.getOffset())); Index: llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp diff -u llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.36 llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.37 --- llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.36 Sat Mar 19 22:29:39 2005 +++ llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp Mon Mar 21 18:21:05 2005 @@ -270,11 +270,8 @@ } // Clone this member of the equivalence class into MergedG. - { - DSGraph::NodeMapTy NodeMap; - MergedG.cloneInto(CBUGraph, MergedG.getScalarMap(), - MergedG.getReturnNodes(), NodeMap, 0); - } + DSGraph::NodeMapTy NodeMap; + MergedG.cloneInto(CBUGraph, MergedG.getReturnNodes(), NodeMap, 0); } // Merge the return nodes of all functions together. @@ -366,7 +363,7 @@ // If the SCC found is not the same as those found in CBU, make sure to // merge the graphs as appropriate. DSGraph::NodeMapTy NodeMap; - FG.cloneInto(*NG, FG.getScalarMap(), FG.getReturnNodes(), NodeMap); + FG.cloneInto(*NG, FG.getReturnNodes(), NodeMap); // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = NG->retnodes_begin(); Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.50 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.51 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.50 Mon Mar 21 18:04:21 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Mon Mar 21 18:21:05 2005 @@ -130,8 +130,7 @@ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) { DSGraph::NodeMapTy NodeMap; - ResultGraph->cloneInto(LDS.getDSGraph(*I), ResultGraph->getScalarMap(), - RetValMap, NodeMap, 0); + ResultGraph->cloneInto(LDS.getDSGraph(*I), RetValMap, NodeMap, 0); } ResultGraph->removeTriviallyDeadNodes(); From lattner at cs.uiuc.edu Mon Mar 21 18:22:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:22:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503220022.j2M0MwDE015710@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.221 -> 1.222 --- Log message: now that the valuemapping is always the local scalar map, we can eliminate this identity merge. --- Diffs of the changes: (+0 -4) DataStructure.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.221 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.222 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.221 Mon Mar 21 18:21:05 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 18:22:45 2005 @@ -1286,10 +1286,6 @@ DSNode *MappedNodeN = MappedNode.getNode(); H.mergeWith(DSNodeHandle(MappedNodeN, I->second.getOffset()+MappedNode.getOffset())); - - // If this is a global, add the global to this fn or merge if already exists - if (GlobalValue* GV = dyn_cast(I->first)) - ScalarMap[GV].mergeWith(H); } if (!(CloneFlags & DontCloneCallNodes)) { From alenhar2 at cs.uiuc.edu Mon Mar 21 18:24:21 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 21 Mar 2005 18:24:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp AlphaInstrInfo.td Message-ID: <200503220024.j2M0OLK8015799@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.64 -> 1.65 AlphaInstrInfo.td updated: 1.33 -> 1.34 --- Log message: two things: 1)evilness reduction patch, reduces the number of instructions hiding in the small jump CC moving code. 2)implement div of small data types by FP DIV (also reduces evilness and should speed things up) --- Diffs of the changes: (+58 -9) AlphaISelPattern.cpp | 45 ++++++++++++++++++++++++++++++++++++++++----- AlphaInstrInfo.td | 22 ++++++++++++++++++---- 2 files changed, 58 insertions(+), 9 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.64 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.65 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.64 Tue Mar 15 13:51:19 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Mon Mar 21 18:24:07 2005 @@ -679,10 +679,10 @@ } return Result; + case ISD::SDIV: case ISD::MUL: case ISD::ADD: case ISD::SUB: - case ISD::SDIV: switch( opcode ) { case ISD::MUL: Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS; break; case ISD::ADD: Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS; break; @@ -1050,9 +1050,39 @@ case ISD::SIGN_EXTEND_INREG: { + //do SDIV opt for all levels of ints + if (N.getOperand(0).getOpcode() == ISD::SDIV) + { + Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); + unsigned Size = MVT::getSizeInBits(MVT::f64)/8; + MachineFunction *F = BB->getParent(); + int FrameIdxL = F->getFrameInfo()->CreateStackObject(Size, 8); + int FrameIdxR = F->getFrameInfo()->CreateStackObject(Size, 8); + int FrameIdxF = F->getFrameInfo()->CreateStackObject(Size, 8); + unsigned Tmp4 = MakeReg(MVT::f64); + unsigned Tmp5 = MakeReg(MVT::f64); + unsigned Tmp6 = MakeReg(MVT::f64); + unsigned Tmp7 = MakeReg(MVT::f64); + unsigned Tmp8 = MakeReg(MVT::f64); + unsigned Tmp9 = MakeReg(MVT::f64); + + BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdxL).addReg(Alpha::F31); + BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdxR).addReg(Alpha::F31); + BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdxL).addReg(Alpha::F31); + BuildMI(BB, Alpha::LDT, 2, Tmp5).addFrameIndex(FrameIdxR).addReg(Alpha::F31); + BuildMI(BB, Alpha::CVTQT, 1, Tmp6).addReg(Tmp4); + BuildMI(BB, Alpha::CVTQT, 1, Tmp7).addReg(Tmp5); + BuildMI(BB, Alpha::DIVT, 2, Tmp8).addReg(Tmp6).addReg(Tmp7); + BuildMI(BB, Alpha::CVTTQ, 1, Tmp9).addReg(Tmp8); + BuildMI(BB, Alpha::STT, 3).addReg(Tmp9).addFrameIndex(FrameIdxF).addReg(Alpha::F31); + BuildMI(BB, Alpha::LDQ, 3).addReg(Result).addFrameIndex(FrameIdxF).addReg(Alpha::F31); + return Result; + } + //Alpha has instructions for a bunch of signed 32 bit stuff if( dyn_cast(Node)->getExtraValueType() == MVT::i32) - { + { switch (N.getOperand(0).getOpcode()) { case ISD::ADD: case ISD::SUB: @@ -1291,8 +1321,12 @@ BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); //now arrange for Result (int) to have a 1 or 0 - Opc = inv?Alpha::CC2INT_INV:Alpha::CC2INT; - BuildMI(BB, Opc, 1, Result).addReg(Tmp3); + unsigned Tmp4 = MakeReg(MVT::i64); + BuildMI(BB, Alpha::ADDQi, 2, Tmp4).addReg(Alpha::R31).addImm(1); + Opc = inv?Alpha::CMOVNEi_FP:Alpha::CMOVEQi_FP; + BuildMI(BB, Opc, 3, Result).addReg(Tmp4).addImm(0).addReg(Tmp3); +// Opc = inv?Alpha::CC2INT_INV:Alpha::CC2INT; +// BuildMI(BB, Opc, 1, Result).addReg(Tmp3); // // Spill the FP to memory and reload it from there. // unsigned Size = MVT::getSizeInBits(MVT::f64)/8; @@ -1412,9 +1446,9 @@ return Result; } + case ISD::SDIV: case ISD::UREM: case ISD::SREM: - case ISD::SDIV: case ISD::UDIV: //FIXME: alpha really doesn't support any of these operations, // the ops are expanded into special library calls with @@ -1470,6 +1504,7 @@ case ISD::SELECT: { + //FIXME: look at parent to decide if intCC can be folded, or if setCC(FP) and can save stack use Tmp1 = SelectExpr(N.getOperand(0)); //Cond Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.33 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.34 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.33 Tue Mar 15 13:51:19 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Mon Mar 21 18:24:07 2005 @@ -88,10 +88,24 @@ } //This is an improvement on the old style setcc (FP) -def CC2INT_INV : PseudoInstAlpha<(ops GPRC:$RES, FPRC:$COND), - "lda $RES,1($$31)\n\tfbeq $COND, 42f\n\tbis $$31,$$31,$RES\n42:\n">; -def CC2INT : PseudoInstAlpha<(ops GPRC:$RES, FPRC:$COND), - "lda $RES,1($$31)\n\tfbne $COND, 42f\n\tbis $$31,$$31,$RES\n42:\n">; +//def CC2INT_INV : PseudoInstAlpha<(ops GPRC:$RES, FPRC:$COND), +// "lda $RES,1($$31)\n\tfbeq $COND, 42f\n\tbis $$31,$$31,$RES\n42:\n">; +//def CC2INT : PseudoInstAlpha<(ops GPRC:$RES, FPRC:$COND), +// "lda $RES,1($$31)\n\tfbne $COND, 42f\n\tbis $$31,$$31,$RES\n42:\n">; + +//An even better improvement on the Int = SetCC(FP): SelectCC! +let isTwoAddress = 1 in { + def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), + "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; + def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND), + "fbne $RCOND, 42f\n\taddi $$31,$L,$RDEST\n42:\n">; + + def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), + "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; + def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND), + "fbeq $RCOND, 42f\n\taddi $$31,$L,$RDEST\n42:\n">; + +} //*********************** //Real instructions From lattner at cs.uiuc.edu Mon Mar 21 18:26:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:26:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200503220026.j2M0Q5CM015937@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.51 -> 1.52 --- Log message: instead of using a local RetValMap, just use the graph we are cloning into for the return node map. --- Diffs of the changes: (+5 -8) Steensgaard.cpp | 13 +++++-------- 1 files changed, 5 insertions(+), 8 deletions(-) Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.51 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.52 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.51 Mon Mar 21 18:21:05 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Mon Mar 21 18:25:52 2005 @@ -119,18 +119,14 @@ ResultGraph->setGlobalsGraph(GlobalsGraph); ResultGraph->setPrintAuxCalls(); - // RetValMap - Keep track of the return values for all functions that return - // valid pointers. - // - DSGraph::ReturnNodesTy RetValMap; - // Loop over the rest of the module, merging graphs for non-external functions // into this graph. // for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) { DSGraph::NodeMapTy NodeMap; - ResultGraph->cloneInto(LDS.getDSGraph(*I), RetValMap, NodeMap, 0); + ResultGraph->cloneInto(LDS.getDSGraph(*I), ResultGraph->getReturnNodes(), + NodeMap, 0); } ResultGraph->removeTriviallyDeadNodes(); @@ -161,7 +157,7 @@ // If we can eliminate this function call, do so! Function *F = CallTargets[c]; if (!F->isExternal()) { - ResolveFunctionCall(F, CurCall, RetValMap[F]); + ResolveFunctionCall(F, CurCall, ResultGraph->getReturnNodes()[F]); CallTargets[c] = CallTargets.back(); CallTargets.pop_back(); } else @@ -174,7 +170,8 @@ } } - RetValMap.clear(); + // Remove our knowledge of what the return values of the functions are. + ResultGraph->getReturnNodes().clear(); // Update the "incomplete" markers on the nodes, ignoring unknownness due to // incoming arguments... From lattner at cs.uiuc.edu Mon Mar 21 18:29:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:29:53 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503220029.j2M0TrxH016122@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.102 -> 1.103 --- Log message: now that the second argument is always this->ReturnNodes, don't bother passing it. --- Diffs of the changes: (+1 -2) DSGraph.h | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.102 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.103 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.102 Mon Mar 21 18:20:56 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 18:29:40 2005 @@ -454,8 +454,7 @@ /// /// The CloneFlags member controls various aspects of the cloning process. /// - void cloneInto(const DSGraph &G, - ReturnNodesTy &OldReturnNodes, NodeMapTy &OldNodeMap, + void cloneInto(const DSGraph &G, NodeMapTy &OldNodeMap, unsigned CloneFlags = 0); /// getFunctionArgumentsForCall - Given a function that is currently in this From lattner at cs.uiuc.edu Mon Mar 21 18:29:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:29:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp CompleteBottomUp.cpp DataStructure.cpp EquivClassGraphs.cpp Steensgaard.cpp Message-ID: <200503220029.j2M0TvTe016139@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.103 -> 1.104 CompleteBottomUp.cpp updated: 1.26 -> 1.27 DataStructure.cpp updated: 1.222 -> 1.223 EquivClassGraphs.cpp updated: 1.37 -> 1.38 Steensgaard.cpp updated: 1.52 -> 1.53 --- Log message: now that the second argument is always this->ReturnNodes, don't bother passing it. --- Diffs of the changes: (+18 -16) BottomUpClosure.cpp | 4 ++-- CompleteBottomUp.cpp | 6 ++++-- DataStructure.cpp | 13 ++++++------- EquivClassGraphs.cpp | 8 +++++--- Steensgaard.cpp | 3 +-- 5 files changed, 18 insertions(+), 16 deletions(-) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.103 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.104 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.103 Mon Mar 21 18:21:05 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Mon Mar 21 18:29:44 2005 @@ -269,7 +269,7 @@ if (&G != SCCGraph) { { DSGraph::NodeMapTy NodeMap; - SCCGraph->cloneInto(G, SCCGraph->getReturnNodes(), NodeMap); + SCCGraph->cloneInto(G, NodeMap); } // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = G.retnodes_begin(), @@ -413,7 +413,7 @@ // bother merging it in again. if (!GI->containsFunction(*I)) { DSGraph::NodeMapTy NodeMap; - GI->cloneInto(getDSGraph(**I), GI->getReturnNodes(), NodeMap); + GI->cloneInto(getDSGraph(**I), NodeMap); ++NumBUInlines; } Index: llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp diff -u llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.26 llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.27 --- llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.26 Mon Mar 21 18:21:05 2005 +++ llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp Mon Mar 21 18:29:44 2005 @@ -175,8 +175,10 @@ DSGraph *NG = Stack.back(); ValMap[NG] = ~0U; - DSGraph::NodeMapTy NodeMap; - FG.cloneInto(*NG, FG.getReturnNodes(), NodeMap); + { + DSGraph::NodeMapTy NodeMap; + FG.cloneInto(*NG, NodeMap); + } // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = NG->retnodes_begin(); Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.222 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.223 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.222 Mon Mar 21 18:22:45 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 18:29:44 2005 @@ -1169,14 +1169,14 @@ : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { PrintAuxCalls = false; NodeMapTy NodeMap; - cloneInto(G, ReturnNodes, NodeMap, CloneFlags); + cloneInto(G, NodeMap, CloneFlags); } DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap, EquivalenceClasses &ECs) : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { PrintAuxCalls = false; - cloneInto(G, ReturnNodes, NodeMap); + cloneInto(G, NodeMap); } DSGraph::~DSGraph() { @@ -1242,8 +1242,7 @@ /// /// The CloneFlags member controls various aspects of the cloning process. /// -void DSGraph::cloneInto(const DSGraph &G, - ReturnNodesTy &OldReturnNodes, NodeMapTy &OldNodeMap, +void DSGraph::cloneInto(const DSGraph &G, NodeMapTy &OldNodeMap, unsigned CloneFlags) { TIME_REGION(X, "cloneInto"); assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!"); @@ -1306,9 +1305,9 @@ const DSNodeHandle &Ret = I->second; DSNodeHandle &MappedRet = OldNodeMap[Ret.getNode()]; DSNode *MappedRetN = MappedRet.getNode(); - OldReturnNodes.insert(std::make_pair(I->first, - DSNodeHandle(MappedRetN, - MappedRet.getOffset()+Ret.getOffset()))); + ReturnNodes.insert(std::make_pair(I->first, + DSNodeHandle(MappedRetN, + MappedRet.getOffset()+Ret.getOffset()))); } } Index: llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp diff -u llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.37 llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.38 --- llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.37 Mon Mar 21 18:21:05 2005 +++ llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp Mon Mar 21 18:29:44 2005 @@ -271,7 +271,7 @@ // Clone this member of the equivalence class into MergedG. DSGraph::NodeMapTy NodeMap; - MergedG.cloneInto(CBUGraph, MergedG.getReturnNodes(), NodeMap, 0); + MergedG.cloneInto(CBUGraph, NodeMap); } // Merge the return nodes of all functions together. @@ -362,8 +362,10 @@ // If the SCC found is not the same as those found in CBU, make sure to // merge the graphs as appropriate. - DSGraph::NodeMapTy NodeMap; - FG.cloneInto(*NG, FG.getReturnNodes(), NodeMap); + { + DSGraph::NodeMapTy NodeMap; + FG.cloneInto(*NG, NodeMap); + } // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = NG->retnodes_begin(); Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.52 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.53 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.52 Mon Mar 21 18:25:52 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Mon Mar 21 18:29:44 2005 @@ -125,8 +125,7 @@ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) { DSGraph::NodeMapTy NodeMap; - ResultGraph->cloneInto(LDS.getDSGraph(*I), ResultGraph->getReturnNodes(), - NodeMap, 0); + ResultGraph->cloneInto(LDS.getDSGraph(*I), NodeMap, 0); } ResultGraph->removeTriviallyDeadNodes(); From lattner at cs.uiuc.edu Mon Mar 21 18:33:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:33:33 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503220033.j2M0XX94017716@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.103 -> 1.104 --- Log message: remove a dead ctor --- Diffs of the changes: (+0 -2) DSGraph.h | 2 -- 1 files changed, 2 deletions(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.103 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.104 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.103 Mon Mar 21 18:29:40 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 18:33:20 2005 @@ -225,8 +225,6 @@ // DSGraph(const DSGraph &DSG, EquivalenceClasses &ECs, unsigned CloneFlags = 0); - DSGraph(const DSGraph &DSG, NodeMapTy &NodeMap, - EquivalenceClasses &ECs); ~DSGraph(); DSGraph *getGlobalsGraph() const { return GlobalsGraph; } From lattner at cs.uiuc.edu Mon Mar 21 18:33:48 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:33:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503220033.j2M0Xm8x017727@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.223 -> 1.224 --- Log message: remove a dead ctor --- Diffs of the changes: (+0 -7) DataStructure.cpp | 7 ------- 1 files changed, 7 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.223 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.224 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.223 Mon Mar 21 18:29:44 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 18:33:35 2005 @@ -1172,13 +1172,6 @@ cloneInto(G, NodeMap, CloneFlags); } -DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap, - EquivalenceClasses &ECs) - : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { - PrintAuxCalls = false; - cloneInto(G, NodeMap); -} - DSGraph::~DSGraph() { FunctionCalls.clear(); AuxFunctionCalls.clear(); From lattner at cs.uiuc.edu Mon Mar 21 18:36:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:36:58 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503220036.j2M0awXd017909@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.104 -> 1.105 --- Log message: Now that the dead ctor is gone, nothing uses the old node mapping exported by cloneInto: make it an internally used mapping. --- Diffs of the changes: (+2 -7) DSGraph.h | 9 ++------- 1 files changed, 2 insertions(+), 7 deletions(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.104 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.105 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.104 Mon Mar 21 18:33:20 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 18:36:45 2005 @@ -444,16 +444,11 @@ void computeCalleeCallerMapping(DSCallSite CS, const Function &Callee, DSGraph &CalleeGraph, NodeMapTy &NodeMap); - /// cloneInto - Clone the specified DSGraph into the current graph. The - /// translated ScalarMap for the old function is filled into the OldValMap - /// member, and the translated ReturnNodes map is returned into ReturnNodes. - /// OldNodeMap contains a mapping from the original nodes to the newly cloned - /// nodes. + /// cloneInto - Clone the specified DSGraph into the current graph. /// /// The CloneFlags member controls various aspects of the cloning process. /// - void cloneInto(const DSGraph &G, NodeMapTy &OldNodeMap, - unsigned CloneFlags = 0); + void cloneInto(const DSGraph &G, unsigned CloneFlags = 0); /// getFunctionArgumentsForCall - Given a function that is currently in this /// graph, return the DSNodeHandles that correspond to the pointer-compatible From lattner at cs.uiuc.edu Mon Mar 21 18:37:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 18:37:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp CompleteBottomUp.cpp DataStructure.cpp EquivClassGraphs.cpp Steensgaard.cpp Message-ID: <200503220037.j2M0b4FA017926@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.104 -> 1.105 CompleteBottomUp.cpp updated: 1.27 -> 1.28 DataStructure.cpp updated: 1.224 -> 1.225 EquivClassGraphs.cpp updated: 1.38 -> 1.39 Steensgaard.cpp updated: 1.53 -> 1.54 --- Log message: Now that the dead ctor is gone, nothing uses the old node mapping exported by cloneInto: make it an internally used mapping. --- Diffs of the changes: (+12 -25) BottomUpClosure.cpp | 9 +++------ CompleteBottomUp.cpp | 5 +---- DataStructure.cpp | 9 ++++----- EquivClassGraphs.cpp | 8 ++------ Steensgaard.cpp | 6 ++---- 5 files changed, 12 insertions(+), 25 deletions(-) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.104 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.105 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.104 Mon Mar 21 18:29:44 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Mon Mar 21 18:36:51 2005 @@ -267,10 +267,8 @@ E = SCCGraphs.end(); I != E; ++I) { DSGraph &G = **I; if (&G != SCCGraph) { - { - DSGraph::NodeMapTy NodeMap; - SCCGraph->cloneInto(G, NodeMap); - } + SCCGraph->cloneInto(G); + // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = G.retnodes_begin(), E = G.retnodes_end(); I != E; ++I) @@ -412,8 +410,7 @@ // If the graph already contains the nodes for the function, don't // bother merging it in again. if (!GI->containsFunction(*I)) { - DSGraph::NodeMapTy NodeMap; - GI->cloneInto(getDSGraph(**I), NodeMap); + GI->cloneInto(getDSGraph(**I)); ++NumBUInlines; } Index: llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp diff -u llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.27 llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.28 --- llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.27 Mon Mar 21 18:29:44 2005 +++ llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp Mon Mar 21 18:36:51 2005 @@ -175,10 +175,7 @@ DSGraph *NG = Stack.back(); ValMap[NG] = ~0U; - { - DSGraph::NodeMapTy NodeMap; - FG.cloneInto(*NG, NodeMap); - } + FG.cloneInto(*NG); // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = NG->retnodes_begin(); Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.224 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.225 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.224 Mon Mar 21 18:33:35 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 18:36:51 2005 @@ -1168,8 +1168,7 @@ unsigned CloneFlags) : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) { PrintAuxCalls = false; - NodeMapTy NodeMap; - cloneInto(G, NodeMap, CloneFlags); + cloneInto(G, CloneFlags); } DSGraph::~DSGraph() { @@ -1235,12 +1234,12 @@ /// /// The CloneFlags member controls various aspects of the cloning process. /// -void DSGraph::cloneInto(const DSGraph &G, NodeMapTy &OldNodeMap, - unsigned CloneFlags) { +void DSGraph::cloneInto(const DSGraph &G, unsigned CloneFlags) { TIME_REGION(X, "cloneInto"); - assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!"); assert(&G != this && "Cannot clone graph into itself!"); + NodeMapTy OldNodeMap; + // Remove alloca or mod/ref bits as specified... unsigned BitsToClear = ((CloneFlags & StripAllocaBit)? DSNode::AllocaNode : 0) | ((CloneFlags & StripModRefBits)? (DSNode::Modified | DSNode::Read) : 0) Index: llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp diff -u llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.38 llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.39 --- llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.38 Mon Mar 21 18:29:44 2005 +++ llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp Mon Mar 21 18:36:51 2005 @@ -270,8 +270,7 @@ } // Clone this member of the equivalence class into MergedG. - DSGraph::NodeMapTy NodeMap; - MergedG.cloneInto(CBUGraph, NodeMap); + MergedG.cloneInto(CBUGraph); } // Merge the return nodes of all functions together. @@ -362,10 +361,7 @@ // If the SCC found is not the same as those found in CBU, make sure to // merge the graphs as appropriate. - { - DSGraph::NodeMapTy NodeMap; - FG.cloneInto(*NG, NodeMap); - } + FG.cloneInto(*NG); // Update the DSInfo map and delete the old graph... for (DSGraph::retnodes_iterator I = NG->retnodes_begin(); Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.53 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.54 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.53 Mon Mar 21 18:29:44 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Mon Mar 21 18:36:51 2005 @@ -123,10 +123,8 @@ // into this graph. // for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal()) { - DSGraph::NodeMapTy NodeMap; - ResultGraph->cloneInto(LDS.getDSGraph(*I), NodeMap, 0); - } + if (!I->isExternal()) + ResultGraph->cloneInto(LDS.getDSGraph(*I)); ResultGraph->removeTriviallyDeadNodes(); From lattner at cs.uiuc.edu Mon Mar 21 19:42:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 19:42:23 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503220142.j2M1gNgf019601@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.105 -> 1.106 --- Log message: add a method --- Diffs of the changes: (+6 -0) DSGraph.h | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.105 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.106 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.105 Mon Mar 21 18:36:45 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Mon Mar 21 19:42:10 2005 @@ -91,6 +91,12 @@ return I; } + /// getRawEntryRef - This method can be used by clients that are aware of the + /// global value equivalence class in effect. + DSNodeHandle &getRawEntryRef(Value *V) { + return ValueMap[V]; + } + unsigned count(Value *V) const { return ValueMap.find(V) != ValueMap.end(); } void erase(Value *V) { erase(ValueMap.find(V)); } From lattner at cs.uiuc.edu Mon Mar 21 19:43:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 19:43:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503220143.j2M1hCV2019612@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.225 -> 1.226 --- Log message: Don't use operator[], use the new method instead, which is faster. This speeds up the TD pass about 30% for povray and perlbmk. It's still not clear why copying a 5MB set of graphs turns into a 25MB set of graphs though :( --- Diffs of the changes: (+1 -1) DataStructure.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.225 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.226 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.225 Mon Mar 21 18:36:51 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Mar 21 19:42:59 2005 @@ -1273,7 +1273,7 @@ for (DSScalarMap::const_iterator I = G.ScalarMap.begin(), E = G.ScalarMap.end(); I != E; ++I) { DSNodeHandle &MappedNode = OldNodeMap[I->second.getNode()]; - DSNodeHandle &H = ScalarMap[I->first]; + DSNodeHandle &H = ScalarMap.getRawEntryRef(I->first); DSNode *MappedNodeN = MappedNode.getNode(); H.mergeWith(DSNodeHandle(MappedNodeN, I->second.getOffset()+MappedNode.getOffset())); From lattner at cs.uiuc.edu Mon Mar 21 19:50:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 19:50:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Message-ID: <200503220150.j2M1ot9c020211@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: TopDownClosure.cpp updated: 1.83 -> 1.84 --- Log message: When making a clone of a DSGraph from the BU pass, make sure to remember that this clone is supposed to be used for *ALL* of the functions in the SCC. This fixes the memory explosion problem the TD pass was having, reducing the memory growth from 24MB -> 3.5MB on povray and 270MB ->8.3MB on perlbmk! This obviously also speeds up the TD pass *a lot*. --- Diffs of the changes: (+8 -1) TopDownClosure.cpp | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.83 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.84 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.83 Mon Mar 21 18:12:00 2005 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Mon Mar 21 19:50:42 2005 @@ -105,8 +105,8 @@ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) getOrCreateDSGraph(*I); + return false; } -//return false; #endif @@ -154,6 +154,13 @@ assert(G->getAuxFunctionCalls().empty() && "Cloned aux calls?"); G->setPrintAuxCalls(); G->setGlobalsGraph(GlobalsGraph); + + // Note that this graph is the graph for ALL of the function in the SCC, not + // just F. + for (DSGraph::retnodes_iterator RI = G->retnodes_begin(), + E = G->retnodes_end(); RI != E; ++RI) + if (RI->first != &F) + DSInfo[RI->first] = G; } return *G; } From lattner at cs.uiuc.edu Mon Mar 21 20:45:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 20:45:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200503220245.j2M2jTof023043@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.131 -> 1.132 --- Log message: Remove an iteration pass over the entire scalarmap for each function created by not allowing integer constants to get into the scalar map in the first place. --- Diffs of the changes: (+8 -15) Local.cpp | 23 ++++++++--------------- 1 files changed, 8 insertions(+), 15 deletions(-) Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.131 llvm/lib/Analysis/DataStructure/Local.cpp:1.132 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.131 Sat Mar 19 21:32:35 2005 +++ llvm/lib/Analysis/DataStructure/Local.cpp Mon Mar 21 20:45:13 2005 @@ -82,7 +82,8 @@ FunctionCalls(&fc) { // Create scalar nodes for all pointer arguments... - for (Function::arg_iterator I = f.arg_begin(), E = f.arg_end(); I != E; ++I) + for (Function::arg_iterator I = f.arg_begin(), E = f.arg_end(); + I != E; ++I) if (isPointerType(I->getType())) getValueDest(*I); @@ -177,13 +178,6 @@ Timer::addPeakMemoryMeasurement(); #endif - // Remove all integral constants from the scalarmap! - for (DSScalarMap::iterator I = ScalarMap.begin(); I != ScalarMap.end();) - if (isa(I->first)) - ScalarMap.erase(I++); - else - ++I; - // If there are any constant globals referenced in this function, merge their // initializers into the local graph from the globals graph. if (ScalarMap.global_begin() != ScalarMap.global_end()) { @@ -228,9 +222,12 @@ N->addGlobal(GV); } else if (Constant *C = dyn_cast(V)) { if (ConstantExpr *CE = dyn_cast(C)) { - if (CE->getOpcode() == Instruction::Cast) - NH = getValueDest(*CE->getOperand(0)); - else if (CE->getOpcode() == Instruction::GetElementPtr) { + if (CE->getOpcode() == Instruction::Cast) { + if (isa(CE->getOperand(0)->getType())) + NH = getValueDest(*CE->getOperand(0)); + else + NH = createNode()->setUnknownNodeMarker(); + } else if (CE->getOpcode() == Instruction::GetElementPtr) { visitGetElementPtrInst(*CE); DSScalarMap::iterator I = ScalarMap.find(CE); assert(I != ScalarMap.end() && "GEP didn't get processed right?"); @@ -244,10 +241,6 @@ return 0; } return NH; - - } else if (ConstantIntegral *CI = dyn_cast(C)) { - // Random constants are unknown mem - return NH = createNode()->setUnknownNodeMarker(); } else if (isa(C)) { ScalarMap.erase(V); return 0; From lattner at cs.uiuc.edu Mon Mar 21 21:20:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 21:20:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Support/Timer.cpp Message-ID: <200503220320.j2M3Ksct025699@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: Timer.cpp updated: 1.43 -> 1.44 --- Log message: Timers SHOULD NOT record the time taken to count the bytes allocated in the heap! --- Diffs of the changes: (+2 -2) Timer.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Support/Timer.cpp diff -u llvm/lib/Support/Timer.cpp:1.43 llvm/lib/Support/Timer.cpp:1.44 --- llvm/lib/Support/Timer.cpp:1.43 Wed Feb 9 12:41:32 2005 +++ llvm/lib/Support/Timer.cpp Mon Mar 21 21:20:38 2005 @@ -112,11 +112,11 @@ ssize_t MemUsed = 0; if (Start) { - sys::Process::GetTimeUsage(now,user,sys); MemUsed = getMemUsage(); + sys::Process::GetTimeUsage(now,user,sys); } else { - MemUsed = getMemUsage(); sys::Process::GetTimeUsage(now,user,sys); + MemUsed = getMemUsage(); } Result.Elapsed = now.seconds() + now.microseconds() / 1000000.0; From lattner at cs.uiuc.edu Mon Mar 21 21:55:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 21:55:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/InstCount.cpp Message-ID: <200503220355.j2M3tQcb026838@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: InstCount.cpp updated: 1.10 -> 1.11 --- Log message: Directly count the number of memory instructions. --- Diffs of the changes: (+9 -4) InstCount.cpp | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) Index: llvm/lib/Analysis/InstCount.cpp diff -u llvm/lib/Analysis/InstCount.cpp:1.10 llvm/lib/Analysis/InstCount.cpp:1.11 --- llvm/lib/Analysis/InstCount.cpp:1.10 Tue Nov 16 00:58:55 2004 +++ llvm/lib/Analysis/InstCount.cpp Mon Mar 21 21:55:10 2005 @@ -15,13 +15,13 @@ #include "llvm/Function.h" #include "llvm/Support/InstVisitor.h" #include "llvm/ADT/Statistic.h" - -namespace llvm { +using namespace llvm; namespace { Statistic<> TotalInsts ("instcount", "Number of instructions (of all types)"); Statistic<> TotalBlocks("instcount", "Number of basic blocks"); Statistic<> TotalFuncs ("instcount", "Number of non-external functions"); + Statistic<> TotalMemInst("instcount", "Number of memory instructions"); #define HANDLE_INST(N, OPCODE, CLASS) \ Statistic<> Num##OPCODE##Inst("instcount", "Number of " #OPCODE " insts"); @@ -61,8 +61,13 @@ // function. // bool InstCount::runOnFunction(Function &F) { + unsigned StartMemInsts = + NumGetElementPtrInst + NumLoadInst + NumStoreInst + NumCallInst + + NumInvokeInst + NumAllocaInst + NumMallocInst + NumFreeInst; visit(F); + unsigned EndMemInsts = + NumGetElementPtrInst + NumLoadInst + NumStoreInst + NumCallInst + + NumInvokeInst + NumAllocaInst + NumMallocInst + NumFreeInst; + TotalMemInst += EndMemInsts-StartMemInsts; return false; } - -} // End llvm namespace From lattner at cs.uiuc.edu Mon Mar 21 22:05:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 22:05:17 -0600 Subject: [llvm-commits] CVS: llvm-test/TEST.dsgraph.Makefile TEST.dsgraph.report Message-ID: <200503220405.j2M45HbC027473@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsgraph.Makefile updated: 1.14 -> 1.15 TEST.dsgraph.report updated: 1.10 -> 1.11 --- Log message: Clean up this report a LOT. In particular, don't spew tons of crap to the console and eliminate pointless columns. The biggest change is that we now run DSA twice: once with and once without -track-memory. -track-memory can severely throw off timings, so we do a timing run without it, then do a run with it to get memory numbers. --- Diffs of the changes: (+48 -22) TEST.dsgraph.Makefile | 46 +++++++++++++++++++++++++++++++++++++++++----- TEST.dsgraph.report | 24 +++++++----------------- 2 files changed, 48 insertions(+), 22 deletions(-) Index: llvm-test/TEST.dsgraph.Makefile diff -u llvm-test/TEST.dsgraph.Makefile:1.14 llvm-test/TEST.dsgraph.Makefile:1.15 --- llvm-test/TEST.dsgraph.Makefile:1.14 Mon Jan 24 15:21:14 2005 +++ llvm-test/TEST.dsgraph.Makefile Mon Mar 21 22:05:01 2005 @@ -13,16 +13,52 @@ # PASS - The dsgraph pass to run: ds, bu, td PASS := td -ANALYZE_OPTS := -stats -time-passes -only-print-main-ds -dsstats -instcount - -MEM := -track-memory +ANALYZE_OPTS := -stats -time-passes -only-print-main-ds -dsstats +ANALYZE_OPTS += -instcount -disable-verify +MEM := -track-memory -time-passes $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.lib.bc Output/%.LOC.txt $(LANALYZE) $(LOPT) + @# Gather data + -($(LANALYZE) -$(PASS)datastructure $(ANALYZE_OPTS) $<)>> $@.time.1 2>&1 + -($(LANALYZE) $(MEM) -$(PASS)datastructure -disable-verify $<)> $@.mem.1 2>&1 + -($(LOPT) -steens-aa -time-passes -disable-output $<) >> $@.time.2 2>&1 + -($(LOPT) -steens-aa $(MEM) -disable-output $<) >> $@.mem.2 2>&1 + @# Emit data. @echo -n "LOC: " > $@ @cat Output/$*.LOC.txt >> $@ - -(time -p $(LANALYZE) $(MEM) -$(PASS)datastructure $(ANALYZE_OPTS) $<)>> $@ 2>&1 - -($(LOPT) -steens-aa $(MEM) -time-passes > /dev/null < $<) >> $@ 2>&1 + @echo -n "MEMINSTS: " >> $@ + - at grep 'Number of memory instructions' $@.time.1 >> $@ + @echo -n "FOLDEDNODES: " >> $@ + - at grep 'Number of folded nodes' $@.time.1 >> $@ + @echo -n "TOTALNODES: " >> $@ + - at grep 'Graphs contain.*nodes total' $@.time.1 >> $@ + @echo -n "MAXGRAPHSIZE: " >> $@ + - at grep 'Maximum graph size' $@.time.1 >> $@ + @echo -n "GLOBALSGRAPH: " >> $@ + - at grep 'td.GlobalsGraph.dot' $@.time.1 >> $@ + @echo -n "SCCSIZE: " >> $@ + - at grep 'Maximum SCC Size in Call Graph' $@.time.1 >> $@ + @# Emit timing data. + @echo -n "TIME: " >> $@ + - at grep ' Local Data Structure' $@.time.1 >> $@ + @echo -n "TIME: " >> $@ + - at grep ' Bottom-up Data Structure' $@.time.1 >> $@ + @echo -n "TIME: " >> $@ + - at grep ' Top-down Data Structure' $@.time.1 >> $@ + @echo -n "TIME: " >> $@ + - at grep ' Steensgaard.s alias analysis' $@.time.2 >> $@ + @# Emit space data. + @echo -n "MEM: " >> $@ + - at grep ' Local Data Structure' $@.mem.1 >> $@ + @echo -n "MEM: " >> $@ + - at grep ' Bottom-up Data Structure' $@.mem.1 >> $@ + @echo -n "MEM: " >> $@ + - at grep ' Top-down Data Structure' $@.mem.1 >> $@ + @echo -n "MEM: " >> $@ + - at grep ' Steensgaard.s alias analysis' $@.mem.2 >> $@ + + $(PROGRAMS_TO_TEST:%=test.$(TEST).%): \ test.$(TEST).%: Output/%.$(TEST).report.txt Index: llvm-test/TEST.dsgraph.report diff -u llvm-test/TEST.dsgraph.report:1.10 llvm-test/TEST.dsgraph.report:1.11 --- llvm-test/TEST.dsgraph.report:1.10 Sat Jul 10 23:04:10 2004 +++ llvm-test/TEST.dsgraph.report Mon Mar 21 22:05:01 2005 @@ -111,18 +111,20 @@ # These are the columns for the report. The first entry is the header for the # column, the second is the regex to use to match the value. Empty list create # seperators, and closures may be put in for custom processing. + +my $USERSYSTTIME = '([0-9.]+)[ 0-9.]+\([^)]+\)[ 0-9.]+\([^)]+\) +'; ( # Name ["Name:" , '\'([^\']+)\' Program'], ["LOC:" , 'LOC: *([0-9]+)'], + ["MemInsts", '([0-9]+).*Number of memory instructions'], [], # Times - ["Anlyz:", '([0-9.]+) \([^)]+\)[ 0-9]+TOTAL'], - ["LocTm:", '([0-9.]+) \([^)]+\)[ 0-9]+Local'], - ["BUTim:", '([0-9.]+) \([^)]+\)[ 0-9]+Bottom'], - ["TDTim:", '([0-9.]+) \([^)]+\)[ 0-9]+Top'], + ["LocTm:", "${USERSYSTTIME}Local"], + ["BUTim:", "${USERSYSTTIME}Bottom"], + ["TDTim:", "${USERSYSTTIME}Top"], ["SumTm:", sub { return SumCols(@_, 3); }], - ["SteTm:", '([0-9.]+) \([^)]+\)[ 0-9]+Steensgaard'], + ["SteTm:", "${USERSYSTTIME}Steensgaard"], [], # Sizes ["LcSize:" , '([0-9]+) Local'], @@ -136,17 +138,5 @@ ["MaxSz" , '([0-9]+).*Maximum graph size'], ["GlobGr" , '\\.GlobalsGraph\\.dot\'... \\[([0-9+]+)\\]'], ["MaxSCC" , '([0-9]+).*Maximum SCC Size in Call Graph'], - [], - ["Loads" , '([0-9]+).*Number of Load insts'], - ["Store" , '([0-9]+).*Number of Store insts'], - ["Calls" , '([0-9]+).*Number of Call insts'], - ["Allca" , '([0-9]+).*Number of Alloca insts'], - ["Mallc" , '([0-9]+).*Number of Malloc insts'], - ["GEP" , '([0-9]+).*Number of GetElementPtr insts'], - ["Sum" , sub { return SumCols(@_, 6); }], - [], - ["num/ind" , '([0-9]+).*number of indirect call sites'], - ["indcallee",'([0-9]+).*number of callee functions at'], - ["ratio" , \&Ratio], # indcallee / num/ind [] ); From lattner at cs.uiuc.edu Mon Mar 21 22:07:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 21 Mar 2005 22:07:58 -0600 Subject: [llvm-commits] CVS: llvm-test/TEST.dsgraph.Makefile Message-ID: <200503220407.j2M47wEA028301@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsgraph.Makefile updated: 1.15 -> 1.16 --- Log message: don't accumulate timing runs. --- Diffs of the changes: (+3 -3) TEST.dsgraph.Makefile | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm-test/TEST.dsgraph.Makefile diff -u llvm-test/TEST.dsgraph.Makefile:1.15 llvm-test/TEST.dsgraph.Makefile:1.16 --- llvm-test/TEST.dsgraph.Makefile:1.15 Mon Mar 21 22:05:01 2005 +++ llvm-test/TEST.dsgraph.Makefile Mon Mar 21 22:07:44 2005 @@ -20,10 +20,10 @@ $(PROGRAMS_TO_TEST:%=Output/%.$(TEST).report.txt): \ Output/%.$(TEST).report.txt: Output/%.lib.bc Output/%.LOC.txt $(LANALYZE) $(LOPT) @# Gather data - -($(LANALYZE) -$(PASS)datastructure $(ANALYZE_OPTS) $<)>> $@.time.1 2>&1 + -($(LANALYZE) -$(PASS)datastructure $(ANALYZE_OPTS) $<)> $@.time.1 2>&1 -($(LANALYZE) $(MEM) -$(PASS)datastructure -disable-verify $<)> $@.mem.1 2>&1 - -($(LOPT) -steens-aa -time-passes -disable-output $<) >> $@.time.2 2>&1 - -($(LOPT) -steens-aa $(MEM) -disable-output $<) >> $@.mem.2 2>&1 + -($(LOPT) -steens-aa -time-passes -disable-output $<) > $@.time.2 2>&1 + -($(LOPT) -steens-aa $(MEM) -disable-output $<) > $@.mem.2 2>&1 @# Emit data. @echo -n "LOC: " > $@ @cat Output/$*.LOC.txt >> $@ From alenhar2 at cs.uiuc.edu Tue Mar 22 10:43:08 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 22 Mar 2005 10:43:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.td Message-ID: <200503221643.j2MGh8cf003447@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.td updated: 1.34 -> 1.35 --- Log message: hum, it is good to use real instructions --- Diffs of the changes: (+2 -2) AlphaInstrInfo.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.34 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.35 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.34 Mon Mar 21 18:24:07 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Tue Mar 22 10:42:52 2005 @@ -98,12 +98,12 @@ def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND), - "fbne $RCOND, 42f\n\taddi $$31,$L,$RDEST\n42:\n">; + "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">; def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND), - "fbeq $RCOND, 42f\n\taddi $$31,$L,$RDEST\n42:\n">; + "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">; } From lattner at cs.uiuc.edu Tue Mar 22 13:44:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 13:44:28 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503221944.j2MJiSZT006052@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.106 -> 1.107 --- Log message: Fix a serious bug where we didn't insert globals into the globalset when cloning a graph. --- Diffs of the changes: (+6 -1) DSGraph.h | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.106 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.107 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.106 Mon Mar 21 19:42:10 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Tue Mar 22 13:44:11 2005 @@ -94,7 +94,12 @@ /// getRawEntryRef - This method can be used by clients that are aware of the /// global value equivalence class in effect. DSNodeHandle &getRawEntryRef(Value *V) { - return ValueMap[V]; + std::pair IP = + ValueMap.insert(std::make_pair(V, DSNodeHandle())); + if (IP.second) // Inserted the new entry into the map. + if (GlobalValue *GV = dyn_cast(V)) + GlobalSet.insert(GV); + return IP.first->second; } unsigned count(Value *V) const { return ValueMap.find(V) != ValueMap.end(); } From tbrethou at cs.uiuc.edu Tue Mar 22 15:33:35 2005 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Tue, 22 Mar 2005 15:33:35 -0600 Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200503222133.j2MLXZJw007495@apoc.cs.uiuc.edu> Changes in directory llvm: CREDITS.TXT updated: 1.38 -> 1.39 --- Log message: Updating my entry. --- Diffs of the changes: (+6 -5) CREDITS.TXT | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) Index: llvm/CREDITS.TXT diff -u llvm/CREDITS.TXT:1.38 llvm/CREDITS.TXT:1.39 --- llvm/CREDITS.TXT:1.38 Thu Mar 17 12:57:02 2005 +++ llvm/CREDITS.TXT Tue Mar 22 15:33:19 2005 @@ -19,11 +19,6 @@ E: natebegeman at mac.com D: Portions of the PowerPC backend -N: Tanya Brethour -E: tonic at nondot.org -W: http://nondot.org/~tonic/ -D: The llvm-ar tool - N: Misha Brukman E: brukman+llvm at uiuc.edu W: http://misha.brukman.net @@ -76,6 +71,12 @@ W: http://nondot.org/~sabre/ D: Primary architect of LLVM +N: Tanya Lattner (formerly Tanya Brethour) +E: tonic at nondot.org +W: http://nondot.org/~tonic/ +D: The initial llvm-ar tool, converted regression testsuite to dejagnu +D: Modulo scheduling in the SparcV9 backend + N: Andrew Lenharth E: alenhar2 at cs.uiuc.edu W: http://www.lenharth.org/~andrewl/ From lattner at cs.uiuc.edu Tue Mar 22 16:07:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 16:07:31 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll Message-ID: <200503222207.j2MM7Vw0008492@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: 2005-03-22-IncompleteGlobal.ll added (r1.1) --- Log message: New testcase, the BU pass is marking the global complete in the globals graph. --- Diffs of the changes: (+12 -0) 2005-03-22-IncompleteGlobal.ll | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll diff -c /dev/null llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll:1.1 *** /dev/null Tue Mar 22 16:07:25 2005 --- llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll Tue Mar 22 16:07:15 2005 *************** *** 0 **** --- 1,12 ---- + ; RUN: analyze %s -datastructure-gc -dsgc-check-flags=G:GIM -dsgc-dspass=bu + + + %S = type { double, int } + + %G = external global %S + + void %main() { + %b = getelementptr %S* %G, long 0, ubyte 0 + store double 0.1, double* %b + ret void + } From lattner at cs.uiuc.edu Tue Mar 22 16:10:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 16:10:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Message-ID: <200503222210.j2MMAc30008814@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.105 -> 1.106 --- Log message: Mark external globals incomplete in the BU Globals graph, fixing Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll --- Diffs of the changes: (+3 -0) BottomUpClosure.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.105 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.106 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.105 Mon Mar 21 18:36:51 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Tue Mar 22 16:10:22 2005 @@ -82,6 +82,9 @@ GlobalsGraph->removeTriviallyDeadNodes(); GlobalsGraph->maskIncompleteMarkers(); + // Mark external globals incomplete. + GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals); + // Merge the globals variables (not the calls) from the globals graph back // into the main function's graph so that the main function contains all of // the information about global pools and GV usage in the program. From lattner at cs.uiuc.edu Tue Mar 22 16:11:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 16:11:38 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll Message-ID: <200503222211.j2MMBcr4008848@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: 2005-03-22-IncompleteGlobal.ll updated: 1.1 -> 1.2 --- Log message: We might as well check the TD graphs as well, even though they are fine. --- Diffs of the changes: (+2 -2) 2005-03-22-IncompleteGlobal.ll | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll diff -u llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll:1.1 llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll:1.2 --- llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll:1.1 Tue Mar 22 16:07:15 2005 +++ llvm/test/Regression/Analysis/DSGraph/2005-03-22-IncompleteGlobal.ll Tue Mar 22 16:11:22 2005 @@ -1,5 +1,5 @@ -; RUN: analyze %s -datastructure-gc -dsgc-check-flags=G:GIM -dsgc-dspass=bu - +; RUN: analyze %s -datastructure-gc -dsgc-check-flags=G:GIM -dsgc-dspass=bu &&\ +; RUN: analyze %s -datastructure-gc -dsgc-check-flags=G:GIM -dsgc-dspass=td %S = type { double, int } From lattner at cs.uiuc.edu Tue Mar 22 19:29:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 19:29:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200503230129.j2N1TgFo017027@apoc.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.217 -> 1.218 --- Log message: don't crash in some bad cases. --- Diffs of the changes: (+3 -0) llvmAsmParser.y | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.217 llvm/lib/AsmParser/llvmAsmParser.y:1.218 --- llvm/lib/AsmParser/llvmAsmParser.y:1.217 Mon Mar 21 00:27:42 2005 +++ llvm/lib/AsmParser/llvmAsmParser.y Tue Mar 22 19:29:26 2005 @@ -330,6 +330,9 @@ Value *V = getValNonImprovising(Ty, ID); if (V) return V; + if (!Ty->isFirstClassType() && !isa(Ty)) + ThrowException("Invalid use of a composite type!"); + // If we reached here, we referenced either a symbol that we don't know about // or an id number that hasn't been read yet. We may be referencing something // forward, so just create an entry to be resolved later and get to it... From lattner at cs.uiuc.edu Tue Mar 22 19:32:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 19:32:16 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2005-02-14-IllegalAssembler.ll Message-ID: <200503230132.j2N1WGco017102@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2005-02-14-IllegalAssembler.ll updated: 1.1 -> 1.2 --- Log message: make sure this test tests the intended target. --- Diffs of the changes: (+1 -1) 2005-02-14-IllegalAssembler.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/X86/2005-02-14-IllegalAssembler.ll diff -u llvm/test/Regression/CodeGen/X86/2005-02-14-IllegalAssembler.ll:1.1 llvm/test/Regression/CodeGen/X86/2005-02-14-IllegalAssembler.ll:1.2 --- llvm/test/Regression/CodeGen/X86/2005-02-14-IllegalAssembler.ll:1.1 Mon Feb 14 15:31:41 2005 +++ llvm/test/Regression/CodeGen/X86/2005-02-14-IllegalAssembler.ll Tue Mar 22 19:32:03 2005 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc | not grep 18446744073709551612 +; RUN: llvm-as < %s | llc -march=x86 | not grep 18446744073709551612 %A = external global int From lattner at cs.uiuc.edu Tue Mar 22 19:47:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 19:47:12 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/DSGraph/field-sensitive.ll Message-ID: <200503230147.j2N1lCQv018228@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: field-sensitive.ll added (r1.1) --- Log message: new testcase to verify that we have field sensitive alias analysis info. This test cannot be satisfied without interprocedural information. --- Diffs of the changes: (+21 -0) field-sensitive.ll | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+) Index: llvm/test/Regression/Analysis/DSGraph/field-sensitive.ll diff -c /dev/null llvm/test/Regression/Analysis/DSGraph/field-sensitive.ll:1.1 *** /dev/null Tue Mar 22 19:47:10 2005 --- llvm/test/Regression/Analysis/DSGraph/field-sensitive.ll Tue Mar 22 19:46:59 2005 *************** *** 0 **** --- 1,21 ---- + ; Test that ds-aa can be used for queries that require field sensitive AA. + ; RUN: llvm-as < %s | opt -no-aa -ds-aa -load-vn -gcse | llvm-dis | not grep load + + %Pair = type { int, int } + + implementation + + %Pair* %id(%Pair* %P) { ret %Pair *%P } + + int %foo() { + %X = alloca %Pair + %XP = call %Pair* %id(%Pair* %X) + + %F1 = getelementptr %Pair* %X, int 0, uint 0 + %F2 = getelementptr %Pair* %XP, int 0, uint 1 + store int 14, int* %F1 + store int 0, int* %F2 ; no alias F1 + %B = load int* %F1 ; Should eliminate load! + ret int %B + } + From tbrethou at cs.uiuc.edu Tue Mar 22 19:47:31 2005 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Tue, 22 Mar 2005 19:47:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp MSSchedule.h MSchedGraph.cpp MSchedGraph.h ModuloScheduling.cpp ModuloScheduling.h Message-ID: <200503230147.j2N1lVow018258@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/ModuloScheduling: MSSchedule.cpp updated: 1.13 -> 1.14 MSSchedule.h updated: 1.4 -> 1.5 MSchedGraph.cpp updated: 1.13 -> 1.14 MSchedGraph.h updated: 1.7 -> 1.8 ModuloScheduling.cpp updated: 1.43 -> 1.44 ModuloScheduling.h updated: 1.24 -> 1.25 --- Log message: Added alias analysis. Fixed many many bugs. This now works on almost all Singlesource , and most of MultiSource. --- Diffs of the changes: (+724 -193) MSSchedule.cpp | 80 +++++++-- MSSchedule.h | 11 - MSchedGraph.cpp | 305 ++++++++++++++++++++++++++++++------- MSchedGraph.h | 76 +++++---- ModuloScheduling.cpp | 419 ++++++++++++++++++++++++++++++++++++++++----------- ModuloScheduling.h | 26 ++- 6 files changed, 724 insertions(+), 193 deletions(-) Index: llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp diff -u llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp:1.13 llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp:1.14 --- llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp:1.13 Tue Feb 22 20:01:42 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp Tue Mar 22 19:47:20 2005 @@ -165,12 +165,27 @@ } -bool MSSchedule::constructKernel(int II, std::vector &branches) { +bool MSSchedule::constructKernel(int II, std::vector &branches, std::map &indVar) { - int stageNum = (schedule.rbegin()->first)/ II; + //Our schedule is allowed to have negative numbers, so lets calculate this offset + int offset = schedule.begin()->first; + if(offset > 0) + offset = 0; + + DEBUG(std::cerr << "Offset: " << offset << "\n"); + + //Not sure what happens in this case, but assert if offset is > II + //assert(offset > -II && "Offset can not be more then II"); + + std::vector > tempKernel; + + + int stageNum = ((schedule.rbegin()->first-offset)+1)/ II; + int maxSN = 0; + DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n"); - for(int index = 0; index < II; ++index) { + for(int index = offset; index < (II+offset); ++index) { int count = 0; for(int i = index; i <= (schedule.rbegin()->first); i+=II) { if(schedule.count(i)) { @@ -179,26 +194,61 @@ //Check if its a branch if((*I)->isBranch()) { assert(count == 0 && "Branch can not be from a previous iteration"); - kernel.push_back(std::make_pair(*I, count)); + tempKernel.push_back(std::make_pair(*I, count)); } - else + else { //FIXME: Check if the instructions in the earlier stage conflict - kernel.push_back(std::make_pair(*I, count)); + tempKernel.push_back(std::make_pair(*I, count)); + maxSN = std::max(maxSN, count); + } } } ++count; } } - - //Push on branches. Branch vector is in order of last branch to first. - for(std::vector::reverse_iterator B = branches.rbegin() , BE = branches.rend(); B != BE; ++B) { - kernel.push_back(std::make_pair(*B, 0)); + + //Add in induction var code + for(std::vector >::iterator I = tempKernel.begin(), IE = tempKernel.end(); + I != IE; ++I) { + //Add indVar instructions before this one for the current iteration + if(I->second == 0) { + std::map tmpMap; + + //Loop over induction variable instructions in the map that come before this instr + for(std::map::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) { + + + if(N->second < I->first->getIndex()) + tmpMap[N->second] = (MachineInstr*) N->first; + } + + //Add to kernel, and delete from indVar + for(std::map::iterator N = tmpMap.begin(), NE = tmpMap.end(); N != NE; ++N) { + kernel.push_back(std::make_pair(N->second, 0)); + indVar.erase(N->second); + } + } + + kernel.push_back(std::make_pair((MachineInstr*) I->first->getInst(), I->second)); + + } + + std::map tmpMap; + + //Add remaining invar instructions + for(std::map::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) { + tmpMap[N->second] = (MachineInstr*) N->first; + } + + //Add to kernel, and delete from indVar + for(std::map::iterator N = tmpMap.begin(), NE = tmpMap.end(); N != NE; ++N) { + kernel.push_back(std::make_pair(N->second, 0)); + indVar.erase(N->second); } - if(stageNum > 0) - maxStage = stageNum; - else - maxStage = 0; + + maxStage = maxSN; + return true; } @@ -214,7 +264,7 @@ } os << "Kernel:\n"; - for(std::vector >::const_iterator I = kernel.begin(), + for(std::vector >::const_iterator I = kernel.begin(), E = kernel.end(); I != E; ++I) os << "Node: " << *(I->first) << " Stage: " << I->second << "\n"; } Index: llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.h diff -u llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.h:1.4 llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.h:1.5 --- llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.h:1.4 Tue Feb 22 20:01:42 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/MSSchedule.h Tue Mar 22 19:47:20 2005 @@ -16,6 +16,7 @@ #include "MSchedGraph.h" #include +#include namespace llvm { @@ -30,7 +31,7 @@ bool resourcesFree(MSchedGraphNode*, int); //Resulting kernel - std::vector > kernel; + std::vector > kernel; //Max stage count int maxStage; @@ -44,8 +45,8 @@ bool insert(MSchedGraphNode *node, int cycle); int getStartCycle(MSchedGraphNode *node); void clear() { schedule.clear(); resourceNumPerCycle.clear(); kernel.clear(); } - std::vector >* getKernel() { return &kernel; } - bool constructKernel(int II, std::vector &branches); + std::vector >* getKernel() { return &kernel; } + bool constructKernel(int II, std::vector &branches, std::map &indVar); int getMaxStage() { return maxStage; } @@ -56,8 +57,8 @@ schedule_iterator end() { return schedule.end(); }; void print(std::ostream &os) const; - typedef std::vector >::iterator kernel_iterator; - typedef std::vector >::const_iterator kernel_const_iterator; + typedef std::vector >::iterator kernel_iterator; + typedef std::vector >::const_iterator kernel_const_iterator; kernel_iterator kernel_begin() { return kernel.begin(); } kernel_iterator kernel_end() { return kernel.end(); } Index: llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp diff -u llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.13 llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.14 --- llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.13 Tue Feb 15 22:00:59 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp Tue Mar 22 19:47:20 2005 @@ -7,8 +7,11 @@ // //===----------------------------------------------------------------------===// // -// A graph class for dependencies -// +// A graph class for dependencies. This graph only contains true, anti, and +// output data dependencies for a given MachineBasicBlock. Dependencies +// across iterations are also computed. Unless data dependence analysis +// is provided, a conservative approach of adding dependencies between all +// loads and stores is taken. //===----------------------------------------------------------------------===// #define DEBUG_TYPE "ModuloSched" @@ -22,8 +25,11 @@ #include "llvm/Support/Debug.h" #include #include +#include + using namespace llvm; +//MSchedGraphNode constructor MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst, MSchedGraph *graph, unsigned idx, unsigned late, bool isBranch) @@ -33,6 +39,7 @@ graph->addNode(inst, this); } +//MSchedGraphNode copy constructor MSchedGraphNode::MSchedGraphNode(const MSchedGraphNode &N) : Predecessors(N.Predecessors), Successors(N.Successors) { @@ -44,10 +51,13 @@ } +//Print the node (instruction and latency) void MSchedGraphNode::print(std::ostream &os) const { os << "MSchedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n"; } + +//Get the edge from a predecessor to this node MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) { //Loop over all the successors of our predecessor //return the edge the corresponds to this in edge @@ -60,6 +70,7 @@ abort(); } +//Get the iteration difference for the edge from this node to its successor unsigned MSchedGraphNode::getIteDiff(MSchedGraphNode *succ) { for(std::vector::iterator I = Successors.begin(), E = Successors.end(); I != E; ++I) { @@ -69,7 +80,7 @@ return 0; } - +//Get the index into the vector of edges for the edge from pred to this node unsigned MSchedGraphNode::getInEdgeNum(MSchedGraphNode *pred) { //Loop over all the successors of our predecessor //return the edge the corresponds to this in edge @@ -83,6 +94,8 @@ assert(0 && "Should have found edge between this node and its predecessor!"); abort(); } + +//Determine if succ is a successor of this node bool MSchedGraphNode::isSuccessor(MSchedGraphNode *succ) { for(succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I) if(*I == succ) @@ -90,7 +103,7 @@ return false; } - +//Dtermine if pred is a predecessor of this node bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) { if(std::find( Predecessors.begin(), Predecessors.end(), pred) != Predecessors.end()) return true; @@ -98,7 +111,7 @@ return false; } - +//Add a node to the graph void MSchedGraph::addNode(const MachineInstr *MI, MSchedGraphNode *node) { @@ -109,6 +122,7 @@ GraphMap[MI] = node; } +//Delete a node to the graph void MSchedGraph::deleteNode(MSchedGraphNode *node) { //Delete the edge to this node from all predecessors @@ -123,7 +137,10 @@ } -MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ) +//Create a graph for a machine block. The ignoreInstrs map is so that we ignore instructions +//associated to the index variable since this is a special case in Modulo Scheduling. +//We only want to deal with the body of the loop. +MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, TargetData &TD, std::map &ignoreInstrs) : BB(bb), Target(targ) { //Make sure BB is not null, @@ -132,9 +149,13 @@ //DEBUG(std::cerr << "Constructing graph for " << bb << "\n"); //Create nodes and edges for this BB - buildNodesAndEdges(); + buildNodesAndEdges(AA, TD, ignoreInstrs); + + //Experimental! + //addBranchEdges(); } +//Copies the graph and keeps a map from old to new nodes MSchedGraph::MSchedGraph(const MSchedGraph &G, std::map &newNodes) : BB(G.BB), Target(G.Target) { @@ -169,13 +190,86 @@ } } - +//Deconstructor, deletes all nodes in the graph MSchedGraph::~MSchedGraph () { for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); I != E; ++I) delete I->second; } -void MSchedGraph::buildNodesAndEdges() { + +//Experimental code to add edges from the branch to all nodes dependent upon it. +void hasPath(MSchedGraphNode *node, std::set &visited, + std::set &branches, MSchedGraphNode *startNode, + std::set > &newEdges ) { + + visited.insert(node); + DEBUG(std::cerr << "Visiting: " << *node << "\n"); + //Loop over successors + for(unsigned i = 0; i < node->succ_size(); ++i) { + MSchedGraphEdge *edge = node->getSuccessor(i); + MSchedGraphNode *dest = edge->getDest(); + if(branches.count(dest)) + newEdges.insert(std::make_pair(dest, startNode)); + + //only visit if we have not already + else if(!visited.count(dest)) { + if(edge->getIteDiff() == 0) + hasPath(dest, visited, branches, startNode, newEdges);} + + } + +} + +//Experimental code to add edges from the branch to all nodes dependent upon it. +void MSchedGraph::addBranchEdges() { + std::set branches; + std::set nodes; + + for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); I != E; ++I) { + if(I->second->isBranch()) + if(I->second->hasPredecessors()) + branches.insert(I->second); + } + + //See if there is a path first instruction to the branches, if so, add an + //iteration dependence between that node and the branch + std::set > newEdges; + for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); I != E; ++I) { + std::set visited; + hasPath((I->second), visited, branches, (I->second), newEdges); + } + + //Spit out all edges we are going to add + unsigned min = GraphMap.size(); + if(newEdges.size() == 1) { + ((newEdges.begin())->first)->addOutEdge(((newEdges.begin())->second), + MSchedGraphEdge::BranchDep, + MSchedGraphEdge::NonDataDep, 1); + } + else { + + unsigned count = 0; + MSchedGraphNode *start; + MSchedGraphNode *end; + for(std::set >::iterator I = newEdges.begin(), E = newEdges.end(); I != E; ++I) { + + DEBUG(std::cerr << "Branch Edge from: " << *(I->first) << " to " << *(I->second) << "\n"); + + // if(I->second->getIndex() <= min) { + start = I->first; + end = I->second; + //min = I->second->getIndex(); + //} + start->addOutEdge(end, + MSchedGraphEdge::BranchDep, + MSchedGraphEdge::NonDataDep, 1); + } + } +} + + +//Add edges between the nodes +void MSchedGraph::buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map &ignoreInstrs) { //Get Machine target information for calculating latency const TargetInstrInfo *MTI = Target.getInstrInfo(); @@ -190,6 +284,13 @@ //Loop over instructions in MBB and add nodes and edges for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); MI != e; ++MI) { + + //Ignore indvar instructions + if(ignoreInstrs.count(MI)) { + ++index; + continue; + } + //Get each instruction of machine basic block, get the delay //using the op code, create a new node for it, and add to the //graph. @@ -262,7 +363,6 @@ DEBUG(std::cerr << "Read Operation in a PHI node\n"); continue; } - if (const Value* srcI = mOp.getVRegValue()) { @@ -274,7 +374,7 @@ //those instructions //to this one we are processing if(V != valuetoNodeMap.end()) { - addValueEdges(V->second, node, mOp.isUse(), mOp.isDef()); + addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs); //Add to value map V->second.push_back(std::make_pair(i,node)); @@ -295,14 +395,16 @@ if(const PHINode *PN = dyn_cast(I)) { MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN); for (unsigned j = 0; j < tempMvec.size(); j++) { - DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n"); - phiInstrs.push_back((MachineInstr*) tempMvec[j]); + if(!ignoreInstrs.count(tempMvec[j])) { + DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n"); + phiInstrs.push_back((MachineInstr*) tempMvec[j]); + } } } } - addMemEdges(memInstructions); + addMemEdges(memInstructions, AA, TD); addMachRegEdges(regNumtoNodeMap); //Finally deal with PHI Nodes and Value* @@ -324,28 +426,30 @@ //Get Operand const MachineOperand &mOp = (*I)->getOperand(i); if((mOp.getType() == MachineOperand::MO_VirtualRegister || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) { + //find the value in the map if (const Value* srcI = mOp.getVRegValue()) { - + //Find value in the map std::map >::iterator V - = valuetoNodeMap.find(srcI); - + = valuetoNodeMap.find(srcI); + //If there is something in the map already, add edges from //those instructions //to this one we are processing if(V != valuetoNodeMap.end()) { - addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), 1); + addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs, 1); } } } } - } -} + } +} +//Add dependencies for Value*s void MSchedGraph::addValueEdges(std::vector &NodesInMap, MSchedGraphNode *destNode, bool nodeIsUse, - bool nodeIsDef, int diff) { + bool nodeIsDef, std::vector &phiInstrs, int diff) { for(std::vector::iterator I = NodesInMap.begin(), E = NodesInMap.end(); I != E; ++I) { @@ -354,26 +458,34 @@ MSchedGraphNode *srcNode = I->second; MachineOperand mOp = srcNode->getInst()->getOperand(I->first); + if(diff > 0) + if(std::find(phiInstrs.begin(), phiInstrs.end(), srcNode->getInst()) == phiInstrs.end()) + continue; + //Node is a Def, so add output dep. if(nodeIsDef) { if(mOp.isUse()) { + DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=anti)\n"); srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep, MSchedGraphEdge::AntiDep, diff); } if(mOp.isDef()) { + DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=output)\n"); srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep, MSchedGraphEdge::OutputDep, diff); } } if(nodeIsUse) { - if(mOp.isDef()) + if(mOp.isDef()) { + DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=true)\n"); srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep, MSchedGraphEdge::TrueDep, diff); + } } } } - +//Add dependencies for machine registers across iterations void MSchedGraph::addMachRegEdges(std::map >& regNumtoNodeMap) { //Loop over all machine registers in the map, and add dependencies //between the instructions that use it @@ -469,7 +581,9 @@ } -void MSchedGraph::addMemEdges(const std::vector& memInst) { +//Add edges between all loads and stores +//Can be less strict with alias analysis and data dependence analysis. +void MSchedGraph::addMemEdges(const std::vector& memInst, AliasAnalysis &AA, TargetData &TD) { //Get Target machine instruction info const TargetInstrInfo *TMI = Target.getInstrInfo(); @@ -478,51 +592,132 @@ //Knowing that they are in execution, add true, anti, and output dependencies for (unsigned srcIndex = 0; srcIndex < memInst.size(); ++srcIndex) { + MachineInstr *srcInst = (MachineInstr*) memInst[srcIndex]->getInst(); + //Get the machine opCode to determine type of memory instruction - MachineOpCode srcNodeOpCode = memInst[srcIndex]->getInst()->getOpcode(); + MachineOpCode srcNodeOpCode = srcInst->getOpcode(); + //All instructions after this one in execution order have an iteration delay of 0 for(unsigned destIndex = srcIndex + 1; destIndex < memInst.size(); ++destIndex) { - - //source is a Load, so add anti-dependencies (store after load) - if(TMI->isLoad(srcNodeOpCode)) - if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::AntiDep); - + + MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst(); + + //Add Anti dependencies (store after load) + //Source is a Load + if(TMI->isLoad(srcNodeOpCode)) { + + //Destination is a store + if(TMI->isStore(destInst->getOpcode())) { + + //Get the Value* that we are reading from the load, always the first op + const MachineOperand &mOp = srcInst->getOperand(0); + assert((mOp.isUse() && (mOp.getType() == MachineOperand::MO_VirtualRegister)) && "Assumed first operand was a use and a value*\n"); + + //Get the value* for the store + const MachineOperand &mOp2 = destInst->getOperand(0); + assert(mOp2.getType() == MachineOperand::MO_VirtualRegister && "Assumed first operand was a value*\n"); + + //Only add the edge if we can't verify that they do not alias + if(AA.alias(mOp2.getVRegValue(), + (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()), + mOp.getVRegValue(), + (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType())) + != AliasAnalysis::NoAlias) { + + //Add edge from load to store + memInst[srcIndex]->addOutEdge(memInst[destIndex], + MSchedGraphEdge::MemoryDep, + MSchedGraphEdge::AntiDep); + } + } + } + //If source is a store, add output and true dependencies if(TMI->isStore(srcNodeOpCode)) { - if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::OutputDep); - else - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::TrueDep); + + //Get the Value* that we are reading from the store (src), always the first op + const MachineOperand &mOp = srcInst->getOperand(0); + assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Assumed first operand was a use and a value*\n"); + + //Get the Value* that we are reading from the load, always the first op + const MachineOperand &mOp2 = srcInst->getOperand(0); + assert((mOp2.isUse() && (mOp2.getType() == MachineOperand::MO_VirtualRegister)) && "Assumed first operand was a use and a value*\n"); + + //Only add the edge if we can't verify that they do not alias + if(AA.alias(mOp2.getVRegValue(), + (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()), + mOp.getVRegValue(), + (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType())) + != AliasAnalysis::NoAlias) { + + if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) + memInst[srcIndex]->addOutEdge(memInst[destIndex], + MSchedGraphEdge::MemoryDep, + MSchedGraphEdge::OutputDep); + else + memInst[srcIndex]->addOutEdge(memInst[destIndex], + MSchedGraphEdge::MemoryDep, + MSchedGraphEdge::TrueDep); + } } } //All instructions before the src in execution order have an iteration delay of 1 for(unsigned destIndex = 0; destIndex < srcIndex; ++destIndex) { + + MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst(); + //source is a Load, so add anti-dependencies (store after load) - if(TMI->isLoad(srcNodeOpCode)) - if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::AntiDep, 1); + if(TMI->isLoad(srcNodeOpCode)) { + //Get the Value* that we are reading from the load, always the first op + const MachineOperand &mOp = srcInst->getOperand(0); + assert((mOp.isUse() && (mOp.getType() == MachineOperand::MO_VirtualRegister)) && "Assumed first operand was a use and a value*\n"); + + //Get the value* for the store + const MachineOperand &mOp2 = destInst->getOperand(0); + assert(mOp2.getType() == MachineOperand::MO_VirtualRegister && "Assumed first operand was a value*\n"); + + //Only add the edge if we can't verify that they do not alias + if(AA.alias(mOp2.getVRegValue(), + (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()), + mOp.getVRegValue(), + (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType())) + != AliasAnalysis::NoAlias) { + if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) + memInst[srcIndex]->addOutEdge(memInst[destIndex], + MSchedGraphEdge::MemoryDep, + MSchedGraphEdge::AntiDep, 1); + } + } if(TMI->isStore(srcNodeOpCode)) { - if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::OutputDep, 1); - else - memInst[srcIndex]->addOutEdge(memInst[destIndex], - MSchedGraphEdge::MemoryDep, - MSchedGraphEdge::TrueDep, 1); + + //Get the Value* that we are reading from the store (src), always the first op + const MachineOperand &mOp = srcInst->getOperand(0); + assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Assumed first operand was a use and a value*\n"); + + //Get the Value* that we are reading from the load, always the first op + const MachineOperand &mOp2 = srcInst->getOperand(0); + assert((mOp2.isUse() && (mOp2.getType() == MachineOperand::MO_VirtualRegister)) && "Assumed first operand was a use and a value*\n"); + + //Only add the edge if we can't verify that they do not alias + if(AA.alias(mOp2.getVRegValue(), + (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()), + mOp.getVRegValue(), + (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType())) + != AliasAnalysis::NoAlias) { + + if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode())) + memInst[srcIndex]->addOutEdge(memInst[destIndex], + MSchedGraphEdge::MemoryDep, + MSchedGraphEdge::OutputDep, 1); + else + memInst[srcIndex]->addOutEdge(memInst[destIndex], + MSchedGraphEdge::MemoryDep, + MSchedGraphEdge::TrueDep, 1); + } } - + } } Index: llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h diff -u llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h:1.7 llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h:1.8 --- llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h:1.7 Thu Feb 10 11:02:58 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h Tue Mar 22 19:47:20 2005 @@ -7,37 +7,45 @@ // //===----------------------------------------------------------------------===// // -// A graph class for dependencies -// +// A graph class for dependencies. This graph only contains true, anti, and +// output data dependencies for a given MachineBasicBlock. Dependencies +// across iterations are also computed. Unless data dependence analysis +// is provided, a conservative approach of adding dependencies between all +// loads and stores is taken. //===----------------------------------------------------------------------===// #ifndef LLVM_MSCHEDGRAPH_H #define LLVM_MSCHEDGRAPH_H +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator" #include - namespace llvm { + class MSchedGraph; class MSchedGraphNode; template class MSchedGraphNodeIterator; - + //MSchedGraphEdge encapsulates the data dependence between nodes. It + //identifies the dependence type, on what, and the iteration + //difference struct MSchedGraphEdge { enum DataDepOrderType { TrueDep, AntiDep, OutputDep, NonDataDep }; enum MSchedGraphEdgeType { - MemoryDep, ValueDep, MachineRegister + MemoryDep, ValueDep, MachineRegister, BranchDep }; + //Get or set edge data MSchedGraphNode *getDest() const { return dest; } unsigned getIteDiff() { return iteDiff; } unsigned getDepOrderType() { return depOrderType; } @@ -55,6 +63,9 @@ unsigned iteDiff; }; + //MSchedGraphNode represents a machine instruction and its + //corresponding latency. Each node also contains a list of its + //predecessors and sucessors. class MSchedGraphNode { const MachineInstr* Inst; //Machine Instruction @@ -63,9 +74,8 @@ unsigned latency; //Latency of Instruction bool isBranchInstr; //Is this node the branch instr or not - std::vector Predecessors; //Predecessor Nodes - std::vector Successors; + std::vector Successors; //Successor edges public: MSchedGraphNode(const MachineInstr *inst, MSchedGraph *graph, @@ -73,7 +83,7 @@ MSchedGraphNode(const MSchedGraphNode &N); - //Iterators + //Iterators - Predecessor and Succussor typedef std::vector::iterator pred_iterator; pred_iterator pred_begin() { return Predecessors.begin(); } pred_iterator pred_end() { return Predecessors.end(); } @@ -83,7 +93,6 @@ pred_const_iterator pred_begin() const { return Predecessors.begin(); } pred_const_iterator pred_end() const { return Predecessors.end(); } - // Successor iterators. typedef MSchedGraphNodeIterator::const_iterator, const MSchedGraphNode> succ_const_iterator; succ_const_iterator succ_begin() const; @@ -93,39 +102,39 @@ MSchedGraphNode> succ_iterator; succ_iterator succ_begin(); succ_iterator succ_end(); - unsigned succ_size() { return Successors.size(); } + //Get or set predecessor nodes, or successor edges void setPredecessor(unsigned index, MSchedGraphNode *dest) { Predecessors[index] = dest; } - + MSchedGraphNode* getPredecessor(unsigned index) { return Predecessors[index]; } - + MSchedGraphEdge* getSuccessor(unsigned index) { return &Successors[index]; } - + void deleteSuccessor(MSchedGraphNode *node) { for (unsigned i = 0; i != Successors.size(); ++i) if (Successors[i].getDest() == node) { Successors.erase(Successors.begin()+i); node->Predecessors.erase(std::find(node->Predecessors.begin(), node->Predecessors.end(), this)); - --i; + --i; //Decrease index var since we deleted a node } } - - void addOutEdge(MSchedGraphNode *destination, MSchedGraphEdge::MSchedGraphEdgeType type, unsigned deptype, unsigned diff=0) { Successors.push_back(MSchedGraphEdge(destination, type, deptype,diff)); destination->Predecessors.push_back(this); } + + //General methods to get and set data for the node const MachineInstr* getInst() { return Inst; } MSchedGraph* getParent() { return Parent; } bool hasPredecessors() { return (Predecessors.size() > 0); } @@ -139,11 +148,13 @@ bool isSuccessor(MSchedGraphNode *); bool isPredecessor(MSchedGraphNode *); bool isBranch() { return isBranchInstr; } + //Debug support void print(std::ostream &os) const; void setParent(MSchedGraph *p) { Parent = p; } }; + //Node iterator for graph generation template class MSchedGraphNodeIterator : public forward_iterator { IteratorType I; // std::vector::iterator or const_iterator @@ -219,6 +230,7 @@ + //Graph class to represent dependence graph class MSchedGraph { const MachineBasicBlock *BB; //Machine basic block @@ -229,20 +241,26 @@ //Add Nodes and Edges to this graph for our BB typedef std::pair OpIndexNodePair; - void buildNodesAndEdges(); + void buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map &ignoreInstrs); void addValueEdges(std::vector &NodesInMap, MSchedGraphNode *node, - bool nodeIsUse, bool nodeIsDef, int diff=0); + bool nodeIsUse, bool nodeIsDef, std::vector &phiInstrs, int diff=0); void addMachRegEdges(std::map >& regNumtoNodeMap); - void addMemEdges(const std::vector& memInst); + void addMemEdges(const std::vector& memInst, AliasAnalysis &AA, TargetData &TD); + void addBranchEdges(); public: - MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ); + MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, TargetData &TD, + std::map &ignoreInstrs); + + //Copy constructor with maps to link old nodes to new nodes MSchedGraph(const MSchedGraph &G, std::map &newNodes); + + //Deconstructor! ~MSchedGraph(); - //Add Nodes to the Graph + //Add or delete nodes from the Graph void addNode(const MachineInstr* MI, MSchedGraphNode *node); void deleteNode(MSchedGraphNode *node); @@ -256,21 +274,23 @@ unsigned size() { return GraphMap.size(); } reverse_iterator rbegin() { return GraphMap.rbegin(); } reverse_iterator rend() { return GraphMap.rend(); } + + //Get Target or original machine basic block const TargetMachine* getTarget() { return &Target; } const MachineBasicBlock* getBB() { return BB; } }; + + + + // Provide specializations of GraphTraits to be able to use graph + // iterators on the scheduling graph static MSchedGraphNode& getSecond(std::pair &Pair) { + MSchedGraphNode*> &Pair) { return *Pair.second; } - - - // Provide specializations of GraphTraits to be able to use graph - // iterators on the scheduling graph! - // template <> struct GraphTraits { typedef MSchedGraphNode NodeType; typedef MSchedGraphNode::succ_iterator ChildIteratorType; @@ -361,8 +381,6 @@ return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond)); } }; - - } #endif Index: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp diff -u llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.43 llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.44 --- llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp:1.43 Tue Feb 22 20:01:42 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp Tue Mar 22 19:47:20 2005 @@ -15,6 +15,7 @@ #define DEBUG_TYPE "ModuloSched" #include "ModuloScheduling.h" +#include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Function.h" #include "llvm/CodeGen/MachineFunction.h" @@ -131,6 +132,9 @@ }; } + +#include + /// ModuloScheduling::runOnFunction - main transformation entry point /// The Swing Modulo Schedule algorithm has three basic steps: /// 1) Computation and Analysis of the dependence graph @@ -138,7 +142,8 @@ /// 3) Scheduling /// bool ModuloSchedulingPass::runOnFunction(Function &F) { - + alarm(300); + bool Changed = false; int numMS = 0; @@ -147,7 +152,9 @@ //Get MachineFunction MachineFunction &MF = MachineFunction::get(&F); - + AliasAnalysis &AA = getAnalysis(); + TargetData &TD = getAnalysis(); + //Worklist std::vector Worklist; @@ -169,6 +176,9 @@ //Print out BB for debugging DEBUG(std::cerr << "ModuloScheduling BB: \n"; (*BI)->print(std::cerr)); + //Print out LLVM BB + DEBUG(std::cerr << "ModuloScheduling LLVMBB: \n"; (*BI)->getBasicBlock()->print(std::cerr)); + //Catch the odd case where we only have TmpInstructions and no real Value*s if(!CreateDefMap(*BI)) { //Clear out our maps for the next basic block that is processed @@ -181,7 +191,7 @@ continue; } - MSchedGraph *MSG = new MSchedGraph(*BI, target); + MSchedGraph *MSG = new MSchedGraph(*BI, target, AA, TD, indVarInstrs[*BI]); //Write Graph out to file DEBUG(WriteGraphToFile(std::cerr, F.getName(), MSG)); @@ -242,7 +252,7 @@ }); //Finally schedule nodes - bool haveSched = computeSchedule(); + bool haveSched = computeSchedule(*BI); //Print out final schedule DEBUG(schedule.print(std::cerr)); @@ -278,7 +288,8 @@ //delete(llvmBB); //delete(*BI); } - + + alarm(0); return Changed; } @@ -345,7 +356,10 @@ //Get Target machine instruction info const TargetInstrInfo *TMI = target.getInstrInfo(); - //Check each instruction and look for calls + //Check each instruction and look for calls, keep map to get index later + std::map indexMap; + + unsigned count = 0; for(MachineBasicBlock::const_iterator I = BI->begin(), E = BI->end(); I != E; ++I) { //Get opcode to check instruction type MachineOpCode OC = I->getOpcode(); @@ -360,7 +374,111 @@ || OC == V9::MOVNEr || OC == V9::MOVNEi || OC == V9::MOVNEGr || OC == V9::MOVNEGi || OC == V9::MOVFNEr || OC == V9::MOVFNEi) return false; + + indexMap[I] = count; + + if(TMI->isNop(OC)) + continue; + + ++count; + } + + //Apply a simple pattern match to make sure this loop can be modulo scheduled + //This means only loops with a branch associated to the iteration count + + //Get the branch + BranchInst *b = dyn_cast(((BasicBlock*) BI->getBasicBlock())->getTerminator()); + + //Get the condition for the branch (we already checked if it was conditional) + Value *cond = b->getCondition(); + + DEBUG(std::cerr << "Condition: " << *cond << "\n"); + + //List of instructions associated with induction variable + std::set indVar; + std::vector stack; + + BasicBlock *BB = (BasicBlock*) BI->getBasicBlock(); + + //Add branch + indVar.insert(b); + + if(Instruction *I = dyn_cast(cond)) + if(I->getParent() == BB) { + if (!assocIndVar(I, indVar, stack, BB)) + return false; + } + else + return false; + else + return false; + + //The indVar set must be >= 3 instructions for this loop to match (FIX ME!) + if(indVar.size() < 3 ) + return false; + + //Dump out instructions associate with indvar for debug reasons + DEBUG(for(std::set::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) { + std::cerr << **N << "\n"; + }); + + //Convert list of LLVM Instructions to list of Machine instructions + std::map mIndVar; + for(std::set::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) { + MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(*N); + for (unsigned j = 0; j < tempMvec.size(); j++) { + MachineOpCode OC = (tempMvec[j])->getOpcode(); + if(TMI->isNop(OC)) + continue; + if(!indexMap.count(tempMvec[j])) + continue; + mIndVar[(MachineInstr*) tempMvec[j]] = indexMap[(MachineInstr*) tempMvec[j]]; + DEBUG(std::cerr << *(tempMvec[j]) << " at index " << indexMap[(MachineInstr*) tempMvec[j]] << "\n"); + } + } + + //Must have some guts to the loop body + if(mIndVar.size() >= (BI->size()-2)) + return false; + + //Put into a map for future access + indVarInstrs[BI] = mIndVar; + + return true; +} + +bool ModuloSchedulingPass::assocIndVar(Instruction *I, std::set &indVar, + std::vector &stack, BasicBlock *BB) { + + stack.push_back(I); + + //If this is a phi node, check if its the canonical indvar + if(PHINode *PN = dyn_cast(I)) { + if (Instruction *Inc = + dyn_cast(PN->getIncomingValueForBlock(BB))) + if (Inc->getOpcode() == Instruction::Add && Inc->getOperand(0) == PN) + if (ConstantInt *CI = dyn_cast(Inc->getOperand(1))) + if (CI->equalsInt(1)) { + //We have found the indvar, so add the stack, and inc instruction to the set + indVar.insert(stack.begin(), stack.end()); + indVar.insert(Inc); + stack.pop_back(); + return true; + } + return false; + } + else { + //Loop over each of the instructions operands, check if they are an instruction and in this BB + for(unsigned i = 0; i < I->getNumOperands(); ++i) { + if(Instruction *N = dyn_cast(I->getOperand(i))) { + if(N->getParent() == BB) + if(!assocIndVar(N, indVar, stack, BB)) + return false; + } + } } + + stack.pop_back(); return true; } @@ -444,7 +562,7 @@ findAllCircuits(graph, MII); int RecMII = 0; - for(std::set > >::iterator I = recurrenceList.begin(), E=recurrenceList.end(); I !=E; ++I) { + for(std::set > >::iterator I = recurrenceList.begin(), E=recurrenceList.end(); I !=E; ++I) { RecMII = std::max(RecMII, I->first); } @@ -508,6 +626,8 @@ bool findEdge = edgesToIgnore.count(std::make_pair(srcNode, destNode->getInEdgeNum(srcNode))); + DEBUG(std::cerr << "Ignoring edge? from: " << *srcNode << " to " << *destNode << "\n"); + return findEdge; } @@ -785,14 +905,21 @@ int totalDelay = 0; int totalDistance = 0; MSchedGraphNode *lastN = 0; + MSchedGraphNode *start = 0; + MSchedGraphNode *end = 0; //Loop over recurrence, get delay and distance for(std::vector::iterator N = stack.begin(), NE = stack.end(); N != NE; ++N) { totalDelay += (*N)->getLatency(); if(lastN) { - totalDistance += (*N)->getInEdge(lastN).getIteDiff(); - } + int iteDiff = (*N)->getInEdge(lastN).getIteDiff(); + totalDistance += iteDiff; + if(iteDiff > 0) { + start = lastN; + end = *N; + } + } //Get the original node lastN = *N; recc.push_back(newNodes[*N]); @@ -807,10 +934,17 @@ f = true; CircCount++; - //Insert reccurrence into the list - DEBUG(std::cerr << "Ignore Edge from: " << *lastN << " to " << **stack.begin() << "\n"); - edgesToIgnore.insert(std::make_pair(newNodes[lastN], newNodes[(*stack.begin())]->getInEdgeNum(newNodes[lastN]))); - + if(start && end) { + //Insert reccurrence into the list + DEBUG(std::cerr << "Ignore Edge from!!: " << *start << " to " << *end << "\n"); + edgesToIgnore.insert(std::make_pair(newNodes[start], (newNodes[end])->getInEdgeNum(newNodes[start]))); + } + else { + //Insert reccurrence into the list + DEBUG(std::cerr << "Ignore Edge from: " << *lastN << " to " << **stack.begin() << "\n"); + edgesToIgnore.insert(std::make_pair(newNodes[lastN], newNodes[(*stack.begin())]->getInEdgeNum(newNodes[lastN]))); + + } //Adjust II until we get close to the inequality delay - II*distance <= 0 int RecMII = II; //Starting value int value = totalDelay-(RecMII * totalDistance); @@ -903,7 +1037,7 @@ //Ignore self loops if(nextSCC.size() > 1) { - + //Get least vertex in Vk if(!s) { s = nextSCC[0]; @@ -1053,16 +1187,52 @@ if(PO->count(*S)) { nodesToAdd.insert(*S); } - searchPath(*S, path, nodesToAdd); + //terminate + else + searchPath(*S, path, nodesToAdd); } - } //Pop Node off the path path.pop_back(); } +void ModuloSchedulingPass::pathToRecc(MSchedGraphNode *node, + std::vector &path, + std::set &poSet, + std::set &lastNodes) { + //Push node onto the path + path.push_back(node); + + DEBUG(std::cerr << "Current node: " << *node << "\n"); + //Loop over all successors and see if there is a path from this node to + //a recurrence in the partial order, if so.. add all nodes to be added to recc + for(MSchedGraphNode::succ_iterator S = node->succ_begin(), SE = node->succ_end(); S != SE; + ++S) { + DEBUG(std::cerr << "Succ:" << **S << "\n"); + //Check if we should ignore this edge first + if(ignoreEdge(node,*S)) + continue; + + if(poSet.count(*S)) { + DEBUG(std::cerr << "Found path to recc from no pred\n"); + //Loop over path, if it exists in lastNodes, then add to poset, and remove from lastNodes + for(std::vector::iterator I = path.begin(), IE = path.end(); I != IE; ++I) { + if(lastNodes.count(*I)) { + DEBUG(std::cerr << "Inserting node into recc: " << **I << "\n"); + poSet.insert(*I); + lastNodes.erase(*I); + } + } + } + else + pathToRecc(*S, path, poSet, lastNodes); + } + + //Pop Node off the path + path.pop_back(); +} void ModuloSchedulingPass::computePartialOrder() { @@ -1095,7 +1265,7 @@ //Check if its a branch, and remove to handle special if(!found) { - if((*N)->isBranch()) { + if((*N)->isBranch() && !(*N)->hasPredecessors()) { branches.push_back(*N); } else @@ -1112,8 +1282,8 @@ //Add nodes that connect this recurrence to recurrences in the partial path for(std::set::iterator N = new_recurrence.begin(), - NE = new_recurrence.end(); N != NE; ++N) - searchPath(*N, path, nodesToAdd); + NE = new_recurrence.end(); N != NE; ++N) + searchPath(*N, path, nodesToAdd); //Add nodes to this recurrence if they are not already in the partial order for(std::set::iterator N = nodesToAdd.begin(), NE = nodesToAdd.end(); @@ -1138,6 +1308,7 @@ //Add any nodes that are not already in the partial order //Add them in a set, one set per connected component std::set lastNodes; + std::set noPredNodes; for(std::map::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { @@ -1150,23 +1321,42 @@ found = true; } if(!found) { - if(I->first->isBranch()) { + if(I->first->isBranch() && !I->first->hasPredecessors()) { if(std::find(branches.begin(), branches.end(), I->first) == branches.end()) branches.push_back(I->first); } - else + else { lastNodes.insert(I->first); + if(!I->first->hasPredecessors()) + noPredNodes.insert(I->first); + } } } + //For each node w/out preds, see if there is a path to one of the + //recurrences, and if so add them to that current recc + /*for(std::set::iterator N = noPredNodes.begin(), NE = noPredNodes.end(); + N != NE; ++N) { + DEBUG(std::cerr << "No Pred Path from: " << **N << "\n"); + for(std::vector >::iterator PO = partialOrder.begin(), + PE = partialOrder.end(); PO != PE; ++PO) { + std::vector path; + pathToRecc(*N, path, *PO, lastNodes); + } + }*/ + + //Break up remaining nodes that are not in the partial order - //into their connected compoenents - while(lastNodes.size() > 0) { - std::set ccSet; - connectedComponentSet(*(lastNodes.begin()),ccSet, lastNodes); - if(ccSet.size() > 0) - partialOrder.push_back(ccSet); - } + ///into their connected compoenents + /*while(lastNodes.size() > 0) { + std::set ccSet; + connectedComponentSet(*(lastNodes.begin()),ccSet, lastNodes); + if(ccSet.size() > 0) + partialOrder.push_back(ccSet); + }*/ + if(lastNodes.size() > 0) + partialOrder.push_back(lastNodes); + //Clean up branches by putting them in final order std::map branchOrder; @@ -1184,7 +1374,7 @@ //Add to final set if( !ccSet.count(node) && lastNodes.count(node)) { lastNodes.erase(node); -if(node->isBranch()) + if(node->isBranch() && !node->hasPredecessors()) FinalNodeOrder.push_back(node); else ccSet.insert(node); @@ -1463,7 +1653,7 @@ //return FinalNodeOrder; } -bool ModuloSchedulingPass::computeSchedule() { +bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB) { TIME_REGION(X, "computeSchedule"); @@ -1487,8 +1677,17 @@ int LateStart = 99999; //Set to something higher then we would ever expect (FIXME) bool hasSucc = false; bool hasPred = false; - - if(!(*I)->isBranch()) { + bool sched; + + if((*I)->isBranch()) + if((*I)->hasPredecessors()) + sched = true; + else + sched = false; + else + sched = true; + + if(sched) { //Loop over nodes in the schedule and determine if they are predecessors //or successors of the node we are trying to schedule for(MSSchedule::schedule_iterator nodesByCycle = schedule.begin(), nodesByCycleEnd = schedule.end(); @@ -1528,8 +1727,8 @@ B != BE; ++B) { if((*I)->isPredecessor(*B)) { int diff = (*I)->getInEdge(*B).getIteDiff(); - int ES_Temp = (II+count) + (*B)->getLatency() - diff * II; - DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << (II+count) << "\n"); + int ES_Temp = (II+count-1) + (*B)->getLatency() - diff * II; + DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << (II+count)-1 << "\n"); DEBUG(std::cerr << "Temp EarlyStart: " << ES_Temp << " Prev EarlyStart: " << EarlyStart << "\n"); EarlyStart = std::max(EarlyStart, ES_Temp); hasPred = true; @@ -1537,8 +1736,8 @@ if((*I)->isSuccessor(*B)) { int diff = (*B)->getInEdge(*I).getIteDiff(); - int LS_Temp = (II+count) - (*I)->getLatency() + diff * II; - DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << (II+count) << "\n"); + int LS_Temp = (II+count-1) - (*I)->getLatency() + diff * II; + DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << (II+count-1) << "\n"); DEBUG(std::cerr << "Temp LateStart: " << LS_Temp << " Prev LateStart: " << LateStart << "\n"); LateStart = std::min(LateStart, LS_Temp); hasSucc = true; @@ -1562,12 +1761,12 @@ success = scheduleNode(*I, LateStart, (LateStart - II +1)); else if(hasPred && hasSucc) { if(EarlyStart > LateStart) { - //success = false; - LateStart = EarlyStart; + success = false; + //LateStart = EarlyStart; DEBUG(std::cerr << "Early Start can not be later then the late start cycle, schedule fails\n"); } - //else - success = scheduleNode(*I, EarlyStart, std::min(LateStart, (EarlyStart + II -1))); + else + success = scheduleNode(*I, EarlyStart, std::min(LateStart, (EarlyStart + II -1))); } else success = scheduleNode(*I, EarlyStart, EarlyStart + II - 1); @@ -1583,13 +1782,14 @@ if(success) { DEBUG(std::cerr << "Constructing Schedule Kernel\n"); - success = schedule.constructKernel(II, branches); + success = schedule.constructKernel(II, branches, indVarInstrs[BB]); DEBUG(std::cerr << "Done Constructing Schedule Kernel\n"); if(!success) { ++IncreasedII; ++II; schedule.clear(); } + DEBUG(std::cerr << "Final II: " << II << "\n"); } if(II >= capII) { @@ -1610,12 +1810,12 @@ DEBUG(std::cerr << *node << " (Start Cycle: " << start << ", End Cycle: " << end << ")\n"); //Make sure start and end are not negative - if(start < 0) { - start = 0; + //if(start < 0) { + //start = 0; - } - if(end < 0) - end = 0; + //} + //if(end < 0) + //end = 0; bool forward = true; if(start > end) @@ -1652,7 +1852,7 @@ return success; } -void ModuloSchedulingPass::writePrologues(std::vector &prologues, MachineBasicBlock *origBB, std::vector &llvm_prologues, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation) { +void ModuloSchedulingPass::writePrologues(std::vector &prologues, MachineBasicBlock *origBB, std::vector &llvm_prologues, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation) { //Keep a map to easily know whats in the kernel std::map > inKernel; @@ -1671,15 +1871,9 @@ for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) { maxStageCount = std::max(maxStageCount, I->second); - //Ignore the branch, we will handle this separately - if(I->first->isBranch()) { - branches.push_back(I->first); - continue; - } - //Put int the map so we know what instructions in each stage are in the kernel - DEBUG(std::cerr << "Inserting instruction " << *(I->first->getInst()) << " into map at stage " << I->second << "\n"); - inKernel[I->second].insert(I->first->getInst()); + DEBUG(std::cerr << "Inserting instruction " << *(I->first) << " into map at stage " << I->second << "\n"); + inKernel[I->second].insert(I->first); } //Get target information to look at machine operands @@ -1691,18 +1885,23 @@ MachineBasicBlock *machineBB = new MachineBasicBlock(llvmBB); DEBUG(std::cerr << "i=" << i << "\n"); - for(int j = 0; j <= i; ++j) { + for(int j = i; j >= 0; --j) { for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) { if(inKernel[j].count(&*MI)) { MachineInstr *instClone = MI->clone(); machineBB->push_back(instClone); - + + //If its a branch, insert a nop + if(mii->isBranch(instClone->getOpcode())) + BuildMI(machineBB, V9::NOP, 0); + + DEBUG(std::cerr << "Cloning: " << *MI << "\n"); - Instruction *tmp; - //After cloning, we may need to save the value that this instruction defines for(unsigned opNum=0; opNum < MI->getNumOperands(); ++opNum) { + Instruction *tmp; + //get machine operand MachineOperand &mOp = instClone->getOperand(opNum); if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) { @@ -1724,8 +1923,15 @@ DEBUG(std::cerr << "Machine Instr Operands: " << *(mOp.getVRegValue()) << ", 0, " << *tmp << "\n"); //Create machine instruction and put int machineBB - MachineInstr *saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); - + MachineInstr *saveValue; + if(mOp.getVRegValue()->getType() == Type::FloatTy) + saveValue = BuildMI(machineBB, V9::FMOVS, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); + else if(mOp.getVRegValue()->getType() == Type::DoubleTy) + saveValue = BuildMI(machineBB, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); + else + saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); + + DEBUG(std::cerr << "Created new machine instr: " << *saveValue << "\n"); } } @@ -1758,14 +1964,14 @@ } - for(std::vector::iterator BR = branches.begin(), BE = branches.end(); BR != BE; ++BR) { + /*for(std::vector::iterator BR = branches.begin(), BE = branches.end(); BR != BE; ++BR) { //Stick in branch at the end machineBB->push_back((*BR)->getInst()->clone()); //Add nop BuildMI(machineBB, V9::NOP, 0); - } + }*/ (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB); @@ -1774,18 +1980,18 @@ } } -void ModuloSchedulingPass::writeEpilogues(std::vector &epilogues, const MachineBasicBlock *origBB, std::vector &llvm_epilogues, std::map > &valuesToSave, std::map > &newValues,std::map &newValLocation, std::map > &kernelPHIs ) { +void ModuloSchedulingPass::writeEpilogues(std::vector &epilogues, const MachineBasicBlock *origBB, std::vector &llvm_epilogues, std::map > &valuesToSave, std::map > &newValues,std::map &newValLocation, std::map > &kernelPHIs ) { std::map > inKernel; for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) { //Ignore the branch, we will handle this separately - if(I->first->isBranch()) - continue; + //if(I->first->isBranch()) + //continue; //Put int the map so we know what instructions in each stage are in the kernel - inKernel[I->second].insert(I->first->getInst()); + inKernel[I->second].insert(I->first); } std::map valPHIs; @@ -1827,7 +2033,7 @@ if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse())) { - DEBUG(std::cerr << "Writing PHI for " << *(mOp.getVRegValue()) << "\n"); + DEBUG(std::cerr << "Writing PHI for " << (mOp.getVRegValue()) << "\n"); //If this is the last instructions for the max iterations ago, don't update operands if(inEpilogue.count(mOp.getVRegValue())) @@ -1843,6 +2049,9 @@ MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst); tempMvec.addTemp((Value*) tmp); + //assert of no kernelPHI for this value + assert(kernelPHIs[mOp.getVRegValue()][i] !=0 && "Must have final kernel phi to construct epilogue phi"); + MachineInstr *saveValue = BuildMI(machineBB, V9::PHI, 3).addReg(newValues[mOp.getVRegValue()][i]).addReg(kernelPHIs[mOp.getVRegValue()][i]).addRegDef(tmp); DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n"); valPHIs[mOp.getVRegValue()] = tmp; @@ -1872,7 +2081,7 @@ } } -void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation, std::map > &kernelPHIs) { +void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation, std::map > &kernelPHIs) { //Keep track of operands that are read and saved from a previous iteration. The new clone //instruction will use the result of the phi instead. @@ -1882,26 +2091,32 @@ //Branches are a special case std::vector branches; - //Create TmpInstructions for the final phis - for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) { + //Get target information to look at machine operands + const TargetInstrInfo *mii = target.getInstrInfo(); + + //Create TmpInstructions for the final phis + for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) { - DEBUG(std::cerr << "Stage: " << I->second << " Inst: " << *(I->first->getInst()) << "\n";); + DEBUG(std::cerr << "Stage: " << I->second << " Inst: " << *(I->first) << "\n";); - if(I->first->isBranch()) { + /*if(I->first->isBranch()) { //Clone instruction const MachineInstr *inst = I->first->getInst(); MachineInstr *instClone = inst->clone(); branches.push_back(instClone); continue; - } + }*/ //Clone instruction - const MachineInstr *inst = I->first->getInst(); + const MachineInstr *inst = I->first; MachineInstr *instClone = inst->clone(); //Insert into machine basic block machineBB->push_back(instClone); + if(mii->isBranch(instClone->getOpcode())) + BuildMI(machineBB, V9::NOP, 0); + DEBUG(std::cerr << "Cloned Inst: " << *instClone << "\n"); //Loop over Machine Operands @@ -1953,7 +2168,14 @@ tempVec.addTemp((Value*) tmp); //Create new machine instr and put in MBB - MachineInstr *saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); + MachineInstr *saveValue; + if(mOp.getVRegValue()->getType() == Type::FloatTy) + saveValue = BuildMI(machineBB, V9::FMOVS, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); + else if(mOp.getVRegValue()->getType() == Type::DoubleTy) + saveValue = BuildMI(machineBB, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); + else + saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); + //Save for future cleanup kernelValue[mOp.getVRegValue()] = tmp; @@ -1994,9 +2216,10 @@ if(V->second.size() == 1) { assert(kernelValue[V->first] != 0 && "Kernel value* must exist to create phi"); MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(),V9::PHI, 3).addReg(V->second.begin()->second).addReg(kernelValue[V->first]).addRegDef(finalPHIValue[V->first]); - DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n"); - kernelPHIs[V->first][schedule.getMaxStage()-1] = kernelValue[V->first]; - } + DEBUG(std::cerr << "Resulting PHI (one live): " << *saveValue << "\n"); + kernelPHIs[V->first][V->second.begin()->first] = kernelValue[V->first]; + DEBUG(std::cerr << "Put kernel phi in at stage: " << schedule.getMaxStage()-1 << " (map stage = " << V->second.begin()->first << ")\n"); + } else { //Keep track of last phi created. @@ -2099,7 +2322,13 @@ if(TMI->isBranch(opc) || TMI->isNop(opc)) continue; else { - BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); + if(mOp.getVRegValue()->getType() == Type::FloatTy) + BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVS, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); + else if(mOp.getVRegValue()->getType() == Type::DoubleTy) + BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); + else + BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); + break; } @@ -2110,7 +2339,14 @@ //Remove the phi and replace it with an OR DEBUG(std::cerr << "Def: " << mOp << "\n"); //newORs.push_back(std::make_pair(tmp, mOp.getVRegValue())); - BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue()); + if(tmp->getType() == Type::FloatTy) + BuildMI(*kernelBB, I, V9::FMOVS, 3).addReg(tmp).addRegDef(mOp.getVRegValue()); + else if(tmp->getType() == Type::DoubleTy) + BuildMI(*kernelBB, I, V9::FMOVD, 3).addReg(tmp).addRegDef(mOp.getVRegValue()); + else + BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue()); + + worklist.push_back(std::make_pair(kernelBB, I)); } @@ -2162,7 +2398,14 @@ if(TMI->isBranch(opc) || TMI->isNop(opc)) continue; else { - BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); + if(mOp.getVRegValue()->getType() == Type::FloatTy) + BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVS, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); + else if(mOp.getVRegValue()->getType() == Type::DoubleTy) + BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp); + else + BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); + + break; } @@ -2172,7 +2415,13 @@ else { //Remove the phi and replace it with an OR DEBUG(std::cerr << "Def: " << mOp << "\n"); - BuildMI(**MB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue()); + if(tmp->getType() == Type::FloatTy) + BuildMI(**MB, I, V9::FMOVS, 3).addReg(tmp).addRegDef(mOp.getVRegValue()); + else if(tmp->getType() == Type::DoubleTy) + BuildMI(**MB, I, V9::FMOVD, 3).addReg(tmp).addRegDef(mOp.getVRegValue()); + else + BuildMI(**MB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue()); + worklist.push_back(std::make_pair(*MB,I)); } @@ -2213,7 +2462,7 @@ DEBUG(std::cerr << "Reconstructing Loop\n"); //First find the value *'s that we need to "save" - std::map > valuesToSave; + std::map > valuesToSave; //Keep track of instructions we have already seen and their stage because //we don't want to "save" values if they are used in the kernel immediately @@ -2226,7 +2475,7 @@ if(I->second !=0) { //For this instruction, get the Value*'s that it reads and put them into the set. //Assert if there is an operand of another type that we need to save - const MachineInstr *inst = I->first->getInst(); + const MachineInstr *inst = I->first; lastInstrs[inst] = I->second; for(unsigned i=0; i < inst->getNumOperands(); ++i) { Index: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h diff -u llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h:1.24 llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h:1.25 --- llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h:1.24 Tue Feb 22 20:01:42 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h Tue Mar 22 19:47:20 2005 @@ -17,6 +17,8 @@ #include "MSSchedule.h" #include "llvm/Function.h" #include "llvm/Pass.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Target/TargetData.h" #include namespace llvm { @@ -42,6 +44,9 @@ //Map to hold Value* defs std::map defMap; + //Map to hold list of instructions associate to the induction var for each BB + std::map > indVarInstrs; + //LLVM Instruction we know we can add TmpInstructions to its MCFI Instruction *defaultInst; @@ -69,6 +74,8 @@ //Internal functions bool CreateDefMap(MachineBasicBlock *BI); bool MachineBBisValid(const MachineBasicBlock *BI); + bool assocIndVar(Instruction *I, std::set &indVar, + std::vector &stack, BasicBlock *BB); int calculateResMII(const MachineBasicBlock *BI); int calculateRecMII(MSchedGraph *graph, int MII); void calculateNodeAttributes(MSchedGraph *graph, int MII); @@ -101,9 +108,13 @@ std::vector &path, std::set &nodesToAdd); + void pathToRecc(MSchedGraphNode *node, + std::vector &path, + std::set &poSet, std::set &lastNodes); + void computePartialOrder(); - bool computeSchedule(); + bool computeSchedule(const MachineBasicBlock *BB); bool scheduleNode(MSchedGraphNode *node, int start, int end); @@ -116,12 +127,12 @@ void fixBranches(std::vector &prologues, std::vector &llvm_prologues, MachineBasicBlock *machineBB, BasicBlock *llvmBB, std::vector &epilogues, std::vector &llvm_epilogues, MachineBasicBlock*); - void writePrologues(std::vector &prologues, MachineBasicBlock *origBB, std::vector &llvm_prologues, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation); + void writePrologues(std::vector &prologues, MachineBasicBlock *origBB, std::vector &llvm_prologues, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation); - void writeEpilogues(std::vector &epilogues, const MachineBasicBlock *origBB, std::vector &llvm_epilogues, std::map > &valuesToSave,std::map > &newValues, std::map &newValLocation, std::map > &kernelPHIs); + void writeEpilogues(std::vector &epilogues, const MachineBasicBlock *origBB, std::vector &llvm_epilogues, std::map > &valuesToSave,std::map > &newValues, std::map &newValLocation, std::map > &kernelPHIs); - void writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation, std::map > &kernelPHIs); + void writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation, std::map > &kernelPHIs); void removePHIs(const MachineBasicBlock *origBB, std::vector &prologues, std::vector &epilogues, MachineBasicBlock *kernelBB, std::map &newValLocation); @@ -131,6 +142,13 @@ ModuloSchedulingPass(TargetMachine &targ) : target(targ) {} virtual bool runOnFunction(Function &F); virtual const char* getPassName() const { return "ModuloScheduling"; } + + // getAnalysisUsage + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + } + }; } From lattner at cs.uiuc.edu Tue Mar 22 19:48:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 19:48:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200503230148.j2N1mPX2018446@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.54 -> 1.55 --- Log message: Make -steens-aa more conservative (aka correct) by making sure to obey incompleteness flags. Make it more aggressive by taking field sensitive information into account. --- Diffs of the changes: (+18 -8) Steensgaard.cpp | 26 ++++++++++++++++++-------- 1 files changed, 18 insertions(+), 8 deletions(-) Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.54 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.55 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.54 Mon Mar 21 18:36:51 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Tue Mar 22 19:48:09 2005 @@ -192,21 +192,31 @@ DSGraph::ScalarMapTy &GSM = ResultGraph->getScalarMap(); DSGraph::ScalarMapTy::iterator I = GSM.find(const_cast(V1)); - if (I != GSM.end() && I->second.getNode()) { + if (I != GSM.end() && !I->second.isNull() && + I->second.getNode()->isComplete()) { DSNodeHandle &V1H = I->second; DSGraph::ScalarMapTy::iterator J=GSM.find(const_cast(V2)); - if (J != GSM.end() && J->second.getNode()) { + if (J != GSM.end() && !J->second.isNull() && + J->second.getNode()->isComplete()) { DSNodeHandle &V2H = J->second; // If the two pointers point to different data structure graph nodes, they // cannot alias! - if (V1H.getNode() != V2H.getNode()) // FIXME: Handle incompleteness! + if (V1H.getNode() != V2H.getNode()) return NoAlias; - // FIXME: If the two pointers point to the same node, and the offsets are - // different, and the LinkIndex vector doesn't alias the section, then the - // two pointers do not alias. We need access size information for the two - // accesses though! - // + // See if they point to different offsets... if so, we may be able to + // determine that they do not alias... + unsigned O1 = I->second.getOffset(), O2 = J->second.getOffset(); + if (O1 != O2) { + if (O2 < O1) { // Ensure that O1 <= O2 + std::swap(V1, V2); + std::swap(O1, O2); + std::swap(V1Size, V2Size); + } + + if (O1+V1Size <= O2) + return NoAlias; + } } } From lattner at cs.uiuc.edu Tue Mar 22 19:48:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 19:48:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200503230148.j2N1mXf6018677@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.29 -> 1.30 --- Log message: implement Analysis/DSGraph/field-sensitive.ll --- Diffs of the changes: (+2 -3) DataStructureAA.cpp | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.29 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.30 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.29 Sat Mar 19 20:14:15 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Tue Mar 22 19:47:19 2005 @@ -161,9 +161,8 @@ std::swap(V1Size, V2Size); } - // FIXME: This is not correct because we do not handle array - // indexing correctly with this check! - //if (O1+V1Size <= O2) return NoAlias; + if (O1+V1Size <= O2) + return NoAlias; } } From lattner at cs.uiuc.edu Tue Mar 22 23:38:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 23:38:50 -0600 Subject: [llvm-commits] CVS: llvm-test/GenerateReport.pl Message-ID: <200503230538.j2N5corj031473@apoc.cs.uiuc.edu> Changes in directory llvm-test: GenerateReport.pl updated: 1.24 -> 1.25 --- Log message: add an option to remove all directories from test names. --- Diffs of the changes: (+10 -0) GenerateReport.pl | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm-test/GenerateReport.pl diff -u llvm-test/GenerateReport.pl:1.24 llvm-test/GenerateReport.pl:1.25 --- llvm-test/GenerateReport.pl:1.24 Mon Nov 8 15:06:21 2004 +++ llvm-test/GenerateReport.pl Tue Mar 22 23:38:34 2005 @@ -47,6 +47,7 @@ # If the report wants us to trim repeated path prefixes off of the start of the # strings in the first column of the report, we can do that. my $TrimRepeatedPrefix = 0; +my $TrimAllDirectories = 0; # Helper functions which may be called by the report description files... sub SumCols { @@ -166,6 +167,15 @@ } } +# If the report wants it, we can trim of all of the directories part of the +# first column. +if ($TrimAllDirectories and scalar(@Values)) { + foreach $Row (@Values) { + $Row->[0] =~ s|^.*/||g; + } +} + + # # Sort table now... # From lattner at cs.uiuc.edu Tue Mar 22 23:39:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 23:39:28 -0600 Subject: [llvm-commits] CVS: llvm-test/TEST.dsgraph.report TEST.dsprecision.report Message-ID: <200503230539.j2N5dSJW031529@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsgraph.report updated: 1.11 -> 1.12 TEST.dsprecision.report updated: 1.1 -> 1.2 --- Log message: clean up these reports --- Diffs of the changes: (+6 -10) TEST.dsgraph.report | 13 ++++--------- TEST.dsprecision.report | 3 ++- 2 files changed, 6 insertions(+), 10 deletions(-) Index: llvm-test/TEST.dsgraph.report diff -u llvm-test/TEST.dsgraph.report:1.11 llvm-test/TEST.dsgraph.report:1.12 --- llvm-test/TEST.dsgraph.report:1.11 Mon Mar 21 22:05:01 2005 +++ llvm-test/TEST.dsgraph.report Tue Mar 22 23:39:15 2005 @@ -4,9 +4,10 @@ # ##===----------------------------------------------------------------------===## -# Sort numerically, not textually... -$SortNumeric = 1; -$TrimRepeatedPrefix = 1; +$SortNumeric = 1; # Sort numerically, not textually. +$TrimAllDirectories = 1; # Trim off benchmark directories. +$SortCol = 2; # Sort by #MemInstrs +$SortReverse = 1; # Sort in descending order # Helper function @@ -41,12 +42,6 @@ return $1; } -# Sort by total analyze time -$SortCol = 7; - -# Sort in descending order -$SortReverse = 1; - # For latex output, limit benchmarks and rename as appropriate @LatexRowMapOrder = ( 'MultiSource/Olden/treeadd/treeadd' => 'Olden-treeadd', Index: llvm-test/TEST.dsprecision.report diff -u llvm-test/TEST.dsprecision.report:1.1 llvm-test/TEST.dsprecision.report:1.2 --- llvm-test/TEST.dsprecision.report:1.1 Thu Mar 17 13:59:05 2005 +++ llvm-test/TEST.dsprecision.report Tue Mar 22 23:39:15 2005 @@ -18,7 +18,8 @@ $SortCol = 0; #$SortNumeric = 1; -$TrimRepeatedPrefix = 1; +$TrimAllDirectories = 1; # Trim off benchmark directories. +#$TrimRepeatedPrefix = 1; # Sort in ascending order $SortReverse = 0; From alenhar2 at cs.uiuc.edu Wed Mar 23 09:20:18 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 23 Mar 2005 09:20:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200503231520.j2NFKIOM001827@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.65 -> 1.66 --- Log message: don't lie to the register allocator --- Diffs of the changes: (+2 -2) AlphaISelPattern.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.65 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.66 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.65 Mon Mar 21 18:24:07 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Wed Mar 23 09:20:01 2005 @@ -1068,7 +1068,7 @@ unsigned Tmp9 = MakeReg(MVT::f64); BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdxL).addReg(Alpha::F31); - BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addFrameIndex(FrameIdxR).addReg(Alpha::F31); + BuildMI(BB, Alpha::STQ, 3).addReg(Tmp2).addFrameIndex(FrameIdxR).addReg(Alpha::F31); BuildMI(BB, Alpha::LDT, 2, Tmp4).addFrameIndex(FrameIdxL).addReg(Alpha::F31); BuildMI(BB, Alpha::LDT, 2, Tmp5).addFrameIndex(FrameIdxR).addReg(Alpha::F31); BuildMI(BB, Alpha::CVTQT, 1, Tmp6).addReg(Tmp4); @@ -1076,7 +1076,7 @@ BuildMI(BB, Alpha::DIVT, 2, Tmp8).addReg(Tmp6).addReg(Tmp7); BuildMI(BB, Alpha::CVTTQ, 1, Tmp9).addReg(Tmp8); BuildMI(BB, Alpha::STT, 3).addReg(Tmp9).addFrameIndex(FrameIdxF).addReg(Alpha::F31); - BuildMI(BB, Alpha::LDQ, 3).addReg(Result).addFrameIndex(FrameIdxF).addReg(Alpha::F31); + BuildMI(BB, Alpha::LDQ, 2, Result).addFrameIndex(FrameIdxF).addReg(Alpha::F31); return Result; } From lattner at cs.uiuc.edu Wed Mar 23 10:43:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 10:43:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503231643.j2NGhRO7012384@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.227 -> 1.228 --- Log message: wrap a long line --- Diffs of the changes: (+2 -1) DataStructure.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.227 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.228 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.227 Tue Mar 22 17:54:52 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Mar 23 10:43:11 2005 @@ -1329,7 +1329,8 @@ void DSGraph::getFunctionArgumentsForCall(Function *F, std::vector &Args) const { Args.push_back(getReturnNodeFor(*F)); - for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI) + for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); + AI != E; ++AI) if (isPointerType(AI->getType())) { Args.push_back(getNodeForValue(AI)); assert(!Args.back().isNull() && "Pointer argument w/o scalarmap entry!?"); From lattner at cs.uiuc.edu Wed Mar 23 14:09:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 14:09:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503232009.j2NK9G0p018987@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.228 -> 1.229 --- Log message: Totally gut mergeInGraph. There is absolutely no reason to be merging global roots in from callees to callers. The BU graphs do not have accurate globals information and all of the clients know it. Instead, just make sure the GG is up-to-date, and they will be perfectly satiated. This speeds up the BU pass on 176.gcc from 5.5s to 1.5s, and Loc+BU+TD from 7s to 2.7s. --- Diffs of the changes: (+48 -74) DataStructure.cpp | 122 +++++++++++++++++++++--------------------------------- 1 files changed, 48 insertions(+), 74 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.228 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.229 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.228 Wed Mar 23 10:43:11 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Mar 23 14:08:59 2005 @@ -1348,95 +1348,69 @@ TIME_REGION(X, "mergeInGraph"); // 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 - // scalars in the old graph _used_ to point, and of the new nodes matching - // nodes of the old graph. - ReachabilityCloner RC(*this, Graph, CloneFlags); + if (&Graph == this) { + // Merge the return value with the return value of the context. + Args[0].mergeWith(CS.getRetVal()); - // Map the return node pointer over. - if (!CS.getRetVal().isNull()) - RC.merge(CS.getRetVal(), Args[0]); - - // Map over all of the arguments. + // Resolve all of the function arguments. for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) { if (i == Args.size()-1) break; // Add the link from the argument scalar to the provided value. - RC.merge(CS.getPtrArg(i), Args[i+1]); - } - - // If requested, copy all of the calls. - if (!(CloneFlags & DontCloneCallNodes)) { - // Copy the function calls list. - for (fc_iterator I = Graph.fc_begin(), E = Graph.fc_end(); I != E; ++I) - FunctionCalls.push_back(DSCallSite(*I, RC)); + Args[i+1].mergeWith(CS.getPtrArg(i)); } + return; + } - // 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::set CopiedAuxCall; + // Clone the callee's graph into the current graph, keeping track of where + // scalars in the old graph _used_ to point, and of the new nodes matching + // nodes of the old graph. + ReachabilityCloner RC(*this, Graph, CloneFlags); - // 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); + // Map the return node pointer over. + if (!CS.getRetVal().isNull()) + RC.merge(CS.getRetVal(), Args[0]); + + // Map over all of the arguments. + for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) { + if (i == Args.size()-1) + break; + + // Add the link from the argument scalar to the provided value. + RC.merge(CS.getPtrArg(i), Args[i+1]); + } - // 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; + // If requested, copy all of the calls. + if (!(CloneFlags & DontCloneCallNodes)) { + // Copy the function calls list. + for (fc_iterator I = Graph.fc_begin(), E = Graph.fc_end(); I != E; ++I) + FunctionCalls.push_back(DSCallSite(*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::set CopiedAuxCall; + + // 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; + if (!(CloneFlags & DontCloneAuxCallNodes)) 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 (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I) - if (CopiedAuxCall.insert(&*I).second && - PathExistsToClonedNode(*I, RC)) { - AuxFunctionCalls.push_back(DSCallSite(*I, RC)); - MadeChange = true; - } - } - } - - } else { - // Merge the return value with the return value of the context. - Args[0].mergeWith(CS.getRetVal()); - - // Resolve all of the function arguments. - for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) { - if (i == Args.size()-1) - break; - - // Add the link from the argument scalar to the provided value. - Args[i+1].mergeWith(CS.getPtrArg(i)); + for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I) + if (CopiedAuxCall.insert(&*I).second && + PathExistsToClonedNode(*I, RC)) { + AuxFunctionCalls.push_back(DSCallSite(*I, RC)); + MadeChange = true; + } } - } } From lattner at cs.uiuc.edu Wed Mar 23 14:12:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 14:12:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503232012.j2NKCLBl019006@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.229 -> 1.230 --- Log message: turn a dead conditional into an assert. --- Diffs of the changes: (+5 -9) DataStructure.cpp | 14 +++++--------- 1 files changed, 5 insertions(+), 9 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.229 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.230 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.229 Wed Mar 23 14:08:59 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Mar 23 14:12:08 2005 @@ -1347,6 +1347,9 @@ const DSGraph &Graph, unsigned CloneFlags) { TIME_REGION(X, "mergeInGraph"); + assert((CloneFlags & DontCloneCallNodes) && + "Doesn't support copying of call nodes!"); + // If this is not a recursive call, clone the graph into this graph... if (&Graph == this) { // Merge the return value with the return value of the context. @@ -1381,13 +1384,6 @@ RC.merge(CS.getPtrArg(i), Args[i+1]); } - // If requested, copy all of the calls. - if (!(CloneFlags & DontCloneCallNodes)) { - // Copy the function calls list. - for (fc_iterator I = Graph.fc_begin(), E = Graph.fc_end(); I != E; ++I) - FunctionCalls.push_back(DSCallSite(*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::set CopiedAuxCall; @@ -1405,10 +1401,10 @@ // If requested, copy any aux calls that can reach copied nodes. for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I) - if (CopiedAuxCall.insert(&*I).second && - PathExistsToClonedNode(*I, RC)) { + if (!CopiedAuxCall.count(&*I) && PathExistsToClonedNode(*I, RC)) { AuxFunctionCalls.push_back(DSCallSite(*I, RC)); MadeChange = true; + CopiedAuxCall.insert(&*I); } } } From lattner at cs.uiuc.edu Wed Mar 23 15:00:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 15:00:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200503232100.j2NL0SKR021270@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.70 -> 1.71 --- Log message: enable -debug-only=licm --- Diffs of the changes: (+1 -0) LICM.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.70 llvm/lib/Transforms/Scalar/LICM.cpp:1.71 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.70 Wed Dec 15 01:22:25 2004 +++ llvm/lib/Transforms/Scalar/LICM.cpp Wed Mar 23 15:00:12 2005 @@ -31,6 +31,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "licm" #include "llvm/Transforms/Scalar.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" From brukman at cs.uiuc.edu Wed Mar 23 15:14:44 2005 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed, 23 Mar 2005 15:14:44 -0600 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/crtend/Makefile Message-ID: <200503232114.PAA01665@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/crtend: Makefile updated: 1.27 -> 1.28 --- Log message: Fix grammar --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/runtime/GCCLibraries/crtend/Makefile diff -u llvm/runtime/GCCLibraries/crtend/Makefile:1.27 llvm/runtime/GCCLibraries/crtend/Makefile:1.28 --- llvm/runtime/GCCLibraries/crtend/Makefile:1.27 Tue Dec 21 23:57:33 2004 +++ llvm/runtime/GCCLibraries/crtend/Makefile Wed Mar 23 15:14:33 2005 @@ -21,7 +21,7 @@ LIBRARYNAME = crtend BYTECODE_DESTINATION = $(CFERuntimeLibDir) -# Note: We're using FAKE_SOURCES because the comp_*.c don't really exists. +# Note: We're using FAKE_SOURCES because the comp_*.c don't really exist. # However this makefile builds comp_*.bc and that's what we want in the library. # The FAKE_SOURCES variable supports this kind of construction. It uses the # FAKE_SOURCES to determine a list of things to build, but doesn't use From lattner at cs.uiuc.edu Wed Mar 23 15:59:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 15:59:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisCounter.cpp Message-ID: <200503232159.j2NLxNU4022929@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisCounter.cpp updated: 1.11 -> 1.12 --- Log message: Add two options to allow -count-aa to print queries either (1) all queries, or (2) only queries that are not successful (e.g. return may alias) --- Diffs of the changes: (+59 -25) AliasAnalysisCounter.cpp | 84 +++++++++++++++++++++++++++++++++-------------- 1 files changed, 59 insertions(+), 25 deletions(-) Index: llvm/lib/Analysis/AliasAnalysisCounter.cpp diff -u llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.11 llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.12 --- llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.11 Sat Jan 8 16:01:16 2005 +++ llvm/lib/Analysis/AliasAnalysisCounter.cpp Wed Mar 23 15:59:07 2005 @@ -13,16 +13,24 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Pass.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/Support/CommandLine.h" #include using namespace llvm; namespace { + cl::opt + PrintAll("count-aa-print-all-queries", cl::ReallyHidden); + cl::opt + PrintAllFailures("count-aa-print-all-failed-queries", cl::ReallyHidden); + class AliasAnalysisCounter : public ModulePass, public AliasAnalysis { unsigned No, May, Must; unsigned NoMR, JustRef, JustMod, MR; const char *Name; + Module *M; public: AliasAnalysisCounter() { No = May = Must = 0; @@ -66,6 +74,7 @@ } bool runOnModule(Module &M) { + this->M = &M; InitializeAliasAnalysis(this); Name = dynamic_cast(&getAnalysis())->getPassName(); return false; @@ -77,24 +86,6 @@ AU.setPreservesAll(); } - AliasResult count(AliasResult R) { - switch (R) { - default: assert(0 && "Unknown alias type!"); - case NoAlias: No++; return NoAlias; - case MayAlias: May++; return MayAlias; - case MustAlias: Must++; return MustAlias; - } - } - ModRefResult count(ModRefResult R) { - switch (R) { - default: assert(0 && "Unknown mod/ref type!"); - case NoModRef: NoMR++; return NoModRef; - case Ref: JustRef++; return Ref; - case Mod: JustMod++; return Mod; - case ModRef: MR++; return ModRef; - } - } - // FIXME: We could count these too... bool pointsToConstantMemory(const Value *P) { return getAnalysis().pointsToConstantMemory(P); @@ -110,12 +101,9 @@ // Forwarding functions: just delegate to a real AA implementation, counting // the number of responses... AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size) { - return count(getAnalysis().alias(V1, V1Size, V2, V2Size)); - } - ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size) { - return count(getAnalysis().getModRefInfo(CS, P, Size)); - } + const Value *V2, unsigned V2Size); + + ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) { return AliasAnalysis::getModRefInfo(CS1,CS2); } @@ -129,3 +117,49 @@ ModulePass *llvm::createAliasAnalysisCounterPass() { return new AliasAnalysisCounter(); } + +AliasAnalysis::AliasResult +AliasAnalysisCounter::alias(const Value *V1, unsigned V1Size, + const Value *V2, unsigned V2Size) { + AliasResult R = getAnalysis().alias(V1, V1Size, V2, V2Size); + + const char *AliasString; + switch (R) { + default: assert(0 && "Unknown alias type!"); + case NoAlias: No++; AliasString = "No alias"; break; + case MayAlias: May++; AliasString = "May alias"; break; + case MustAlias: Must++; AliasString = "Must alias"; break; + } + + if (PrintAll || (PrintAllFailures && R == MayAlias)) { + std::cerr << AliasString << ":\t"; + std::cerr << "[" << V1Size << "B] "; + WriteAsOperand(std::cerr, V1, true, true, M) << ", "; + std::cerr << "[" << V2Size << "B] "; + WriteAsOperand(std::cerr, V2, true, true, M) << "\n"; + } + + return R; +} + +AliasAnalysis::ModRefResult +AliasAnalysisCounter::getModRefInfo(CallSite CS, Value *P, unsigned Size) { + ModRefResult R = getAnalysis().getModRefInfo(CS, P, Size); + + const char *MRString; + switch (R) { + default: assert(0 && "Unknown mod/ref type!"); + case NoModRef: NoMR++; MRString = "NoModRef"; break; + case Ref: JustRef++; MRString = "JustRef"; break; + case Mod: JustMod++; MRString = "JustMod"; break; + case ModRef: MR++; MRString = "ModRef"; break; + } + + if (PrintAll || (PrintAllFailures && R == ModRef)) { + std::cerr << MRString << ": Ptr: "; + std::cerr << "[" << Size << "B] "; + WriteAsOperand(std::cerr, P, true, true, M); + std::cerr << "\t<->" << *CS.getInstruction(); + } + return R; +} From lattner at cs.uiuc.edu Wed Mar 23 15:59:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 15:59:44 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DataStructure.h Message-ID: <200503232159.j2NLxi0i022947@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DataStructure.h updated: 1.88 -> 1.89 --- Log message: a hack to allow count-aa to work with ds-aa :( --- Diffs of the changes: (+4 -5) DataStructure.h | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) Index: llvm/include/llvm/Analysis/DataStructure/DataStructure.h diff -u llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.88 llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.89 --- llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.88 Mon Mar 21 14:29:56 2005 +++ llvm/include/llvm/Analysis/DataStructure/DataStructure.h Wed Mar 23 15:59:31 2005 @@ -112,7 +112,7 @@ /// with other global values in the DSGraphs. EquivalenceClasses GlobalECs; public: - ~BUDataStructures() { releaseMemory(); } + ~BUDataStructures() { releaseMyMemory(); } virtual bool runOnModule(Module &M); @@ -143,10 +143,9 @@ /// void print(std::ostream &O, const Module *M) const; - /// releaseMemory - if the pass pipeline is done with this pass, we can - /// release our memory... - /// - virtual void releaseMemory(); + // FIXME: Once the pass manager is straightened out, rename this to + // releaseMemory. + void releaseMyMemory(); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); From lattner at cs.uiuc.edu Wed Mar 23 15:59:47 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 15:59:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Message-ID: <200503232159.j2NLxlVb022953@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.106 -> 1.107 --- Log message: a hack to allow count-aa to work with ds-aa :( --- Diffs of the changes: (+1 -1) BottomUpClosure.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.106 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.107 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.106 Tue Mar 22 16:10:22 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Wed Mar 23 15:59:34 2005 @@ -305,7 +305,7 @@ // releaseMemory - If the pass pipeline is done with this pass, we can release // our memory... here... // -void BUDataStructures::releaseMemory() { +void BUDataStructures::releaseMyMemory() { for (hash_map::iterator I = DSInfo.begin(), E = DSInfo.end(); I != E; ++I) { I->second->getReturnNodes().erase(I->first); From lattner at cs.uiuc.edu Wed Mar 23 16:06:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 16:06:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysis.cpp Message-ID: <200503232206.j2NM6wiC023086@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysis.cpp updated: 1.23 -> 1.24 --- Log message: Make this a bit more aggressive --- Diffs of the changes: (+1 -1) AliasAnalysis.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/AliasAnalysis.cpp diff -u llvm/lib/Analysis/AliasAnalysis.cpp:1.23 llvm/lib/Analysis/AliasAnalysis.cpp:1.24 --- llvm/lib/Analysis/AliasAnalysis.cpp:1.23 Thu Mar 17 09:36:18 2005 +++ llvm/lib/Analysis/AliasAnalysis.cpp Wed Mar 23 16:06:41 2005 @@ -125,7 +125,7 @@ // If P points to a constant memory location, the call definitely could not // modify the memory location. if ((Mask & Mod) && AA->pointsToConstantMemory(P)) - Mask = Ref; + Mask = ModRefResult(Mask & ~Mod); return ModRefResult(Mask & AA->getModRefInfo(CS, P, Size)); } From lattner at cs.uiuc.edu Wed Mar 23 17:27:14 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 17:27:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysis.cpp Message-ID: <200503232327.j2NNREbU027474@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysis.cpp updated: 1.24 -> 1.25 --- Log message: Make this more efficient by only making one virtual method call. --- Diffs of the changes: (+6 -4) AliasAnalysis.cpp | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/lib/Analysis/AliasAnalysis.cpp diff -u llvm/lib/Analysis/AliasAnalysis.cpp:1.24 llvm/lib/Analysis/AliasAnalysis.cpp:1.25 --- llvm/lib/Analysis/AliasAnalysis.cpp:1.24 Wed Mar 23 16:06:41 2005 +++ llvm/lib/Analysis/AliasAnalysis.cpp Wed Mar 23 17:26:58 2005 @@ -114,11 +114,13 @@ AliasAnalysis::ModRefResult AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) { ModRefResult Mask = ModRef; - if (Function *F = CS.getCalledFunction()) - if (onlyReadsMemory(F)) { - if (doesNotAccessMemory(F)) return NoModRef; + if (Function *F = CS.getCalledFunction()) { + ModRefBehavior MRB = getModRefBehavior(F, CallSite()); + if (MRB == OnlyReadsMemory) Mask = Ref; - } + else if (MRB == DoesNotAccessMemory) + return NoModRef; + } if (!AA) return Mask; From lattner at cs.uiuc.edu Wed Mar 23 17:27:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 17:27:52 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/AliasAnalysis.h Message-ID: <200503232327.j2NNRqgb029196@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: AliasAnalysis.h updated: 1.19 -> 1.20 --- Log message: if a function doesn't access memory at all, it definitely doesn't read it. --- Diffs of the changes: (+2 -1) AliasAnalysis.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/AliasAnalysis.h diff -u llvm/include/llvm/Analysis/AliasAnalysis.h:1.19 llvm/include/llvm/Analysis/AliasAnalysis.h:1.20 --- llvm/include/llvm/Analysis/AliasAnalysis.h:1.19 Fri Dec 17 11:02:54 2004 +++ llvm/include/llvm/Analysis/AliasAnalysis.h Wed Mar 23 17:27:34 2005 @@ -214,7 +214,8 @@ bool onlyReadsMemory(Function *F) { /// FIXME: If the analysis returns more precise info, we can reduce it to /// this. - return getModRefBehavior(F, CallSite()) == OnlyReadsMemory; + ModRefBehavior MRB = getModRefBehavior(F, CallSite()); + return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory; } From lattner at cs.uiuc.edu Wed Mar 23 17:49:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 17:49:12 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/GlobalsModRef/chaining-analysis.ll Message-ID: <200503232349.j2NNnCnd007035@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/GlobalsModRef: chaining-analysis.ll added (r1.1) --- Log message: GlobalMR should be able to analyze this function. --- Diffs of the changes: (+20 -0) chaining-analysis.ll | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+) Index: llvm/test/Regression/Analysis/GlobalsModRef/chaining-analysis.ll diff -c /dev/null llvm/test/Regression/Analysis/GlobalsModRef/chaining-analysis.ll:1.1 *** /dev/null Wed Mar 23 17:49:06 2005 --- llvm/test/Regression/Analysis/GlobalsModRef/chaining-analysis.ll Wed Mar 23 17:48:56 2005 *************** *** 0 **** --- 1,20 ---- + ; RUN: llvm-as < %s | opt -globalsmodref-aa -load-vn -gcse | llvm-dis | not grep load + + ; This test requires the use of previous analyses to determine that + ; doesnotmodX does not modify X (because 'sin' doesn't). + + %X = internal global int 4 + + declare double %sin(double) + + int %test(int *%P) { + store int 12, int* %X + call double %doesnotmodX(double 1.0) + %V = load int* %X + ret int %V + } + + double %doesnotmodX(double %V) { + %V2 = call double %sin(double %V) + ret double %V2 + } From lattner at cs.uiuc.edu Wed Mar 23 17:50:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 17:50:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/GlobalsModRef.cpp Message-ID: <200503232350.j2NNo18V007051@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: GlobalsModRef.cpp updated: 1.11 -> 1.12 --- Log message: If we are calling an external function, chain to another AA to potentially decide, don't just immediately give up. This implements GlobalsModRef/chaining-analysis.ll --- Diffs of the changes: (+20 -8) GlobalsModRef.cpp | 28 ++++++++++++++++++++-------- 1 files changed, 20 insertions(+), 8 deletions(-) Index: llvm/lib/Analysis/IPA/GlobalsModRef.cpp diff -u llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.11 llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.12 --- llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.11 Mon Mar 14 22:54:18 2005 +++ llvm/lib/Analysis/IPA/GlobalsModRef.cpp Wed Mar 23 17:49:47 2005 @@ -111,7 +111,7 @@ return DoesNotAccessMemory; else if ((FR->FunctionEffect & Mod) == 0) return OnlyReadsMemory; - return AliasAnalysis::getModRefBehavior(F, CS); + return AliasAnalysis::getModRefBehavior(F, CS, Info); } virtual void deleteValue(Value *V); @@ -198,11 +198,6 @@ // passing into the function. for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) if (CI->getOperand(i) == V) return true; - } else if (CallInst *CI = dyn_cast(*UI)) { - // Make sure that this is just the function being called, not that it is - // passing into the function. - for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) - if (CI->getOperand(i) == V) return true; } else if (InvokeInst *II = dyn_cast(*UI)) { // Make sure that this is just the function being called, not that it is // passing into the function. @@ -279,8 +274,25 @@ FR.GlobalInfo[GI->first] |= GI->second; } else { - CallsExternal = true; - break; + // Okay, if we can't say anything about it, maybe some other alias + // analysis can. + ModRefBehavior MRB = + AliasAnalysis::getModRefBehavior(Callee, CallSite()); + if (MRB != DoesNotAccessMemory) { + if (MRB == OnlyReadsMemory) { + // This reads memory, but we don't know what, just say that it + // reads all globals. + for (std::map::iterator + GI = CalleeFR->GlobalInfo.begin(), + E = CalleeFR->GlobalInfo.end(); + GI != E; ++GI) + FR.GlobalInfo[GI->first] |= Ref; + + } else { + CallsExternal = true; + break; + } + } } } else { CallsExternal = true; From lattner at cs.uiuc.edu Wed Mar 23 17:51:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 17:51:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/GlobalsModRef.cpp Message-ID: <200503232351.j2NNpQ6R007067@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: GlobalsModRef.cpp updated: 1.12 -> 1.13 --- Log message: wrap a long line --- Diffs of the changes: (+2 -1) GlobalsModRef.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/IPA/GlobalsModRef.cpp diff -u llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.12 llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.13 --- llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.12 Wed Mar 23 17:49:47 2005 +++ llvm/lib/Analysis/IPA/GlobalsModRef.cpp Wed Mar 23 17:51:12 2005 @@ -159,7 +159,8 @@ Readers.clear(); Writers.clear(); } - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) if (I->hasInternalLinkage()) { if (!AnalyzeUsesOfGlobal(I, Readers, Writers)) { // Remember that we are tracking this global, and the mod/ref fns From alkis at cs.uiuc.edu Wed Mar 23 19:04:40 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 23 Mar 2005 19:04:40 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Message-ID: <200503240104.TAA14540@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp updated: 1.41 -> 1.42 --- Log message: Add option to dump constant pool of a classfile. --- Diffs of the changes: (+19 -10) ClassFile.cpp | 29 +++++++++++++++++++---------- 1 files changed, 19 insertions(+), 10 deletions(-) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.41 llvm-java/lib/ClassFile/ClassFile.cpp:1.42 --- llvm-java/lib/ClassFile/ClassFile.cpp:1.41 Sun Feb 13 16:15:31 2005 +++ llvm-java/lib/ClassFile/ClassFile.cpp Wed Mar 23 19:04:28 2005 @@ -426,7 +426,7 @@ std::ostream& ConstantClass::dump(std::ostream& os) const { - return os << *getName(); + return os << "class (Name=" << nameIdx_ << ')'; } ConstantMemberRef::ConstantMemberRef(const ClassFile* cf, std::istream& is) @@ -437,9 +437,22 @@ } -std::ostream& ConstantMemberRef::dump(std::ostream& os) const +std::ostream& ConstantFieldRef::dump(std::ostream& os) const { - return os << *getNameAndType() << '(' << *getClass() << ')'; + return os << "fieldRef (class=" << classIdx_ + << ", nameAndType=" << nameAndTypeIdx_ << ')'; +} + +std::ostream& ConstantMethodRef::dump(std::ostream& os) const +{ + return os << "methodRef (class=" << classIdx_ + << ", nameAndType=" << nameAndTypeIdx_ << ')'; +} + +std::ostream& ConstantInterfaceMethodRef::dump(std::ostream& os) const +{ + return os << "interfaceMethodRef (class=" << classIdx_ + << ", nameAndType=" << nameAndTypeIdx_ << ')'; } ConstantString::ConstantString(const ClassFile* cf, std::istream& is) @@ -451,7 +464,7 @@ std::ostream& ConstantString::dump(std::ostream& os) const { - return os << "String " << *getValue(); + return os << "string (utf8=" << stringIdx_ << ')'; } ConstantInteger::ConstantInteger(const ClassFile* cf, std::istream& is) @@ -512,12 +525,8 @@ std::ostream& ConstantNameAndType::dump(std::ostream& os) const { - if (getName()->str() == "") - os << "\"\""; - else - os << *getName(); - - return os << ':' << *getDescriptor(); + return os << "nameAndType (name=" << nameIdx_ + << ", descriptor=" << descriptorIdx_ << ')'; } ConstantUtf8::ConstantUtf8(const ClassFile* cf, std::istream& is) From alkis at cs.uiuc.edu Wed Mar 23 19:04:40 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 23 Mar 2005 19:04:40 -0600 Subject: [llvm-commits] CVS: llvm-java/tools/classdump/classdump.cpp Message-ID: <200503240104.TAA14544@zion.cs.uiuc.edu> Changes in directory llvm-java/tools/classdump: classdump.cpp updated: 1.19 -> 1.20 --- Log message: Add option to dump constant pool of a classfile. --- Diffs of the changes: (+39 -4) classdump.cpp | 43 +++++++++++++++++++++++++++++++++++++++---- 1 files changed, 39 insertions(+), 4 deletions(-) Index: llvm-java/tools/classdump/classdump.cpp diff -u llvm-java/tools/classdump/classdump.cpp:1.19 llvm-java/tools/classdump/classdump.cpp:1.20 --- llvm-java/tools/classdump/classdump.cpp:1.19 Sat Feb 12 13:05:16 2005 +++ llvm-java/tools/classdump/classdump.cpp Wed Mar 23 19:04:28 2005 @@ -22,11 +22,24 @@ using namespace llvm; -static cl::opt -InputClass(cl::Positional, cl::desc("")); - namespace { + enum DumpType { code, constantPool }; + + cl::opt + InputClass(cl::Positional, cl::desc("")); + + cl::opt + DumpMode( + "dumptype", + cl::desc("Dump type: (default = code)"), + cl::Prefix, + cl::values( + clEnumVal(code, "code"), + clEnumVal(constantPool, "constant pool"), + clEnumValEnd), + cl::init(code)); + using namespace llvm::Java; class ClassDump : public BytecodeParser { @@ -638,7 +651,29 @@ try { const Java::ClassFile* cf(Java::ClassFile::get(InputClass)); - ClassDump(cf, std::cout); + switch (DumpMode) { + default: + std::cerr << "no dump type selected"; + abort(); + case code: { + ClassDump(cf, std::cout); + break; + } + case constantPool: { + for (unsigned i = 0, e = cf->getNumConstants(); i != e; ++i) { + Constant* c = cf->getConstant(i); + std::cout.width(6); + std::cout << i << ": "; + std::cout.width(0); + if (c) + std::cout << *cf->getConstant(i); + else + std::cout << "empty"; + std::cout << '\n'; + } + break; + } + } } catch (std::exception& e) { std::cerr << e.what() << '\n'; From alkis at cs.uiuc.edu Wed Mar 23 19:04:41 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 23 Mar 2005 19:04:41 -0600 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200503240104.TAA14548@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.32 -> 1.33 --- Log message: Add option to dump constant pool of a classfile. --- Diffs of the changes: (+5 -2) ClassFile.h | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.32 llvm-java/include/llvm/Java/ClassFile.h:1.33 --- llvm-java/include/llvm/Java/ClassFile.h:1.32 Sun Feb 13 16:15:41 2005 +++ llvm-java/include/llvm/Java/ClassFile.h Wed Mar 23 19:04:28 2005 @@ -83,6 +83,7 @@ uint16_t getMinorVersion() const { return minorV_; } uint16_t getMajorVersion() const { return majorV_; } + unsigned getNumConstants() const { return cPool_.size(); } Constant* getConstant(unsigned index) const { return cPool_[index]; } ConstantClass* getConstantClass(unsigned index) const; ConstantMemberRef* getConstantMemberRef(unsigned index) const; @@ -187,9 +188,9 @@ }; class ConstantMemberRef : public Constant { + protected: uint16_t classIdx_; uint16_t nameAndTypeIdx_; - protected: ConstantMemberRef(const ClassFile* cf, std::istream& is); public: @@ -199,25 +200,27 @@ ConstantNameAndType* getNameAndType() const { return parent_->getConstantNameAndType(nameAndTypeIdx_); } - std::ostream& dump(std::ostream& os) const; }; class ConstantFieldRef : public ConstantMemberRef { public: ConstantFieldRef(const ClassFile* cf, std::istream& is) : ConstantMemberRef(cf, is) { } + std::ostream& dump(std::ostream& os) const; }; class ConstantMethodRef : public ConstantMemberRef { public: ConstantMethodRef(const ClassFile* cf, std::istream& is) : ConstantMemberRef(cf, is) { } + std::ostream& dump(std::ostream& os) const; }; class ConstantInterfaceMethodRef : public ConstantMemberRef { public: ConstantInterfaceMethodRef(const ClassFile* cf, std::istream& is) : ConstantMemberRef(cf, is) { } + std::ostream& dump(std::ostream& os) const; }; class ConstantString : public Constant { From lattner at cs.uiuc.edu Wed Mar 23 19:23:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 19:23:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/GlobalsModRef.cpp Message-ID: <200503240123.j2O1N8qF008901@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: GlobalsModRef.cpp updated: 1.13 -> 1.14 --- Log message: fix a compiler crash in runtime/libprofile --- Diffs of the changes: (+1 -1) GlobalsModRef.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/IPA/GlobalsModRef.cpp diff -u llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.13 llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.14 --- llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.13 Wed Mar 23 17:51:12 2005 +++ llvm/lib/Analysis/IPA/GlobalsModRef.cpp Wed Mar 23 19:22:52 2005 @@ -280,7 +280,7 @@ ModRefBehavior MRB = AliasAnalysis::getModRefBehavior(Callee, CallSite()); if (MRB != DoesNotAccessMemory) { - if (MRB == OnlyReadsMemory) { + if (MRB == OnlyReadsMemory && CalleeFR) { // This reads memory, but we don't know what, just say that it // reads all globals. for (std::map::iterator From lattner at cs.uiuc.edu Wed Mar 23 20:41:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 20:41:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/GlobalsModRef.cpp Message-ID: <200503240241.j2O2fZEq013884@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: GlobalsModRef.cpp updated: 1.14 -> 1.15 --- Log message: Simplify dead code into a fixme :) --- Diffs of the changes: (+4 -13) GlobalsModRef.cpp | 17 ++++------------- 1 files changed, 4 insertions(+), 13 deletions(-) Index: llvm/lib/Analysis/IPA/GlobalsModRef.cpp diff -u llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.14 llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.15 --- llvm/lib/Analysis/IPA/GlobalsModRef.cpp:1.14 Wed Mar 23 19:22:52 2005 +++ llvm/lib/Analysis/IPA/GlobalsModRef.cpp Wed Mar 23 20:41:19 2005 @@ -280,19 +280,10 @@ ModRefBehavior MRB = AliasAnalysis::getModRefBehavior(Callee, CallSite()); if (MRB != DoesNotAccessMemory) { - if (MRB == OnlyReadsMemory && CalleeFR) { - // This reads memory, but we don't know what, just say that it - // reads all globals. - for (std::map::iterator - GI = CalleeFR->GlobalInfo.begin(), - E = CalleeFR->GlobalInfo.end(); - GI != E; ++GI) - FR.GlobalInfo[GI->first] |= Ref; - - } else { - CallsExternal = true; - break; - } + // FIXME: could make this more aggressive for functions that just + // read memory. We should just say they read all globals. + CallsExternal = true; + break; } } } else { From lattner at cs.uiuc.edu Wed Mar 23 21:05:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 21:05:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200503240305.j2O356eL014538@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.30 -> 1.31 --- Log message: teach ds-aa about mod/ref for external function calls. --- Diffs of the changes: (+25 -1) DataStructureAA.cpp | 26 +++++++++++++++++++++++++- 1 files changed, 25 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.30 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.31 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.30 Tue Mar 22 19:47:19 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Wed Mar 23 21:04:50 2005 @@ -178,9 +178,33 @@ AliasAnalysis::ModRefResult Result =AliasAnalysis::getModRefInfo(CS, P, Size); Function *F = CS.getCalledFunction(); - if (!F || F->isExternal() || Result == NoModRef) + if (!F || Result == NoModRef) return Result; + if (F->isExternal()) { + // If we are calling an external function, and if this global doesn't escape + // the portion of the program we have analyzed, we can draw conclusions + // based on whether the global escapes the program. + Function *Caller = CS.getInstruction()->getParent()->getParent(); + DSGraph *G = &TD->getDSGraph(*Caller); + DSScalarMap::iterator NI = G->getScalarMap().find(P); + if (NI == G->getScalarMap().end()) { + // If it wasn't in the local function graph, check the global graph. This + // can occur for globals who are locally reference but hoisted out to the + // globals graph despite that. + G = G->getGlobalsGraph(); + NI = G->getScalarMap().find(P); + if (NI == G->getScalarMap().end()) + return Result; + } + + // If we found a node and it's complete, it cannot be passed out to the + // called function. + if (NI->second.getNode()->isComplete()) + return NoModRef; + return Result; + } + // Get the graphs for the callee and caller. Note that we want the BU graph // for the callee because we don't want all caller's effects incorporated! const Function *Caller = CS.getInstruction()->getParent()->getParent(); From lattner at cs.uiuc.edu Wed Mar 23 22:22:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 22:22:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp TopDownClosure.cpp Message-ID: <200503240422.j2O4MLcd023505@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.107 -> 1.108 TopDownClosure.cpp updated: 1.84 -> 1.85 --- Log message: Fix a crash while promoting a value out of a loop from a global variable when using ds-aa --- Diffs of the changes: (+20 -2) BottomUpClosure.cpp | 11 ++++++++++- TopDownClosure.cpp | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.107 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.108 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.107 Wed Mar 23 15:59:34 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Wed Mar 23 22:22:04 2005 @@ -527,5 +527,14 @@ return; } - assert(!isa(From) && "Do not know how to copy GV's yet!"); + if (const Function *F = getFnForValue(To)) { + DSGraph &G = getDSGraph(*F); + G.getScalarMap().copyScalarIfExists(From, To); + return; + } + + std::cerr << *From; + std::cerr << *To; + assert(0 && "Do not know how to copy this yet!"); + abort(); } Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.84 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.85 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.84 Mon Mar 21 19:50:42 2005 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Wed Mar 23 22:22:04 2005 @@ -468,5 +468,14 @@ return; } - assert(!isa(From) && "Do not know how to copy GV's yet!"); + if (const Function *F = getFnForValue(To)) { + DSGraph &G = getDSGraph(*F); + G.getScalarMap().copyScalarIfExists(From, To); + return; + } + + std::cerr << *From; + std::cerr << *To; + assert(0 && "Do not know how to copy this yet!"); + abort(); } From alkis at cs.uiuc.edu Wed Mar 23 22:24:35 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 23 Mar 2005 22:24:35 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503240424.WAA02860@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.240 -> 1.241 --- Log message: Do not call getConstant() on a String constant since that adds a load instruction in the current basic block and we don't want that to happen in emitStaticInitializers. Strings are not LLVM constants anyway, so we don't need to check if the Value returned by getConstant() for a String is an LLVM constant. --- Diffs of the changes: (+10 -8) Compiler.cpp | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.240 llvm-java/lib/Compiler/Compiler.cpp:1.241 --- llvm-java/lib/Compiler/Compiler.cpp:1.240 Mon Mar 21 14:59:16 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Wed Mar 23 22:24:24 2005 @@ -1593,14 +1593,16 @@ // dynamic initializer. Because LLVM does not currently // support these semantics, we consider constants only // final fields with static initializers. - bool isConstant = field->isStatic(); - llvm::Constant* init; - if (field->getConstantValueAttribute() && - dyn_cast(getConstant(field->getConstantValueAttribute()->getValue()))) - init = ConstantExpr::getCast(dyn_cast(getConstant(field->getConstantValueAttribute()->getValue())), globalTy); - else { - init = llvm::Constant::getNullValue(globalTy); - isConstant = false; + bool isConstant = false; + llvm::Constant* init = llvm::Constant::getNullValue(globalTy); + if (field->getConstantValueAttribute()) { + Constant* constant = + field->getConstantValueAttribute()->getValue(); + if (!dynamic_cast(constant)) { + init = ConstantExpr::getCast( + dyn_cast(getConstant(constant)), globalTy); + isConstant = field->isFinal(); + } } std::string globalName = From natebegeman at mac.com Wed Mar 23 22:40:07 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 23 Mar 2005 22:40:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200503240440.WAA03817@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.92 -> 1.93 --- Log message: Remove comments that are now meaningless from the pattern ISels, at Chris's request. --- Diffs of the changes: (+1 -2) X86ISelPattern.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.92 llvm/lib/Target/X86/X86ISelPattern.cpp:1.93 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.92 Thu Mar 17 10:29:26 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Mar 23 22:39:54 2005 @@ -2723,8 +2723,7 @@ void ISel::Select(SDOperand N) { unsigned Tmp1, Tmp2, Opc; - // FIXME: Disable for our current expansion model! - if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, 1)).second) + if (!ExprMap.insert(std::make_pair(N, 1)).second) return; // Already selected. SDNode *Node = N.Val; From natebegeman at mac.com Wed Mar 23 22:40:07 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 23 Mar 2005 22:40:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200503240440.WAA03825@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.3 -> 1.4 --- Log message: Remove comments that are now meaningless from the pattern ISels, at Chris's request. --- Diffs of the changes: (+1 -2) IA64ISelPattern.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.3 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.4 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.3 Sat Mar 19 03:22:17 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Wed Mar 23 22:39:54 2005 @@ -1416,8 +1416,7 @@ unsigned Tmp1, Tmp2, Opc; unsigned opcode = N.getOpcode(); - // FIXME: Disable for our current expansion model! - if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second) + if (!LoweredTokens.insert(N).second) return; // Already selected. SDNode *Node = N.Val; From natebegeman at mac.com Wed Mar 23 22:40:07 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 23 Mar 2005 22:40:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200503240440.WAA03821@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.66 -> 1.67 --- Log message: Remove comments that are now meaningless from the pattern ISels, at Chris's request. --- Diffs of the changes: (+1 -2) AlphaISelPattern.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.66 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.67 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.66 Wed Mar 23 09:20:01 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Wed Mar 23 22:39:54 2005 @@ -1543,8 +1543,7 @@ unsigned Tmp1, Tmp2, Opc; unsigned opcode = N.getOpcode(); - // FIXME: Disable for our current expansion model! - if (/*!N->hasOneUse() &&*/ !ExprMap.insert(std::make_pair(N, notIn)).second) + if (!ExprMap.insert(std::make_pair(N, notIn)).second) return; // Already selected. SDNode *Node = N.Val; From natebegeman at mac.com Wed Mar 23 22:41:54 2005 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 23 Mar 2005 22:41:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PowerPC.h PowerPCTargetMachine.cpp Message-ID: <200503240441.WAA04295@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp added (r1.1) PowerPC.h updated: 1.11 -> 1.12 PowerPCTargetMachine.cpp updated: 1.46 -> 1.47 --- Log message: Addition of the PPC32 Pattern ISel. While it is far from complete, it will be brought up to parity with the current simple ISel in the coming days. Currently, -pattern-isel is required to trigger it. --- Diffs of the changes: (+761 -0) PPC32ISelPattern.cpp | 756 +++++++++++++++++++++++++++++++++++++++++++++++ PowerPC.h | 1 PowerPCTargetMachine.cpp | 4 3 files changed, 761 insertions(+) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -c /dev/null llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.1 *** /dev/null Wed Mar 23 22:41:53 2005 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Wed Mar 23 22:41:43 2005 *************** *** 0 **** --- 1,756 ---- + //===-- PPC32ISelPattern.cpp - A pattern matching inst selector for PPC32 -===// + // + // 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 defines a pattern matching instruction selector for 32 bit PowerPC. + // + //===----------------------------------------------------------------------===// + + #include "PowerPC.h" + #include "PowerPCInstrBuilder.h" + #include "PowerPCInstrInfo.h" + #include "PPC32RegisterInfo.h" + #include "llvm/Constants.h" // FIXME: REMOVE + #include "llvm/Function.h" + #include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SelectionDAGISel.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Target/TargetData.h" + #include "llvm/Target/TargetLowering.h" + #include "llvm/Support/Debug.h" + #include "llvm/Support/MathExtras.h" + #include "llvm/ADT/Statistic.h" + #include + #include + using namespace llvm; + + //===----------------------------------------------------------------------===// + // PPC32TargetLowering - PPC32 Implementation of the TargetLowering interface + namespace { + class PPC32TargetLowering : public TargetLowering { + int VarArgsFrameIndex; // FrameIndex for start of varargs area. + int ReturnAddrIndex; // FrameIndex for return slot. + public: + PPC32TargetLowering(TargetMachine &TM) : TargetLowering(TM) { + // Set up the TargetLowering object. + + // Set up the register classes. + addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass); + addRegisterClass(MVT::f32, PPC32::GPRCRegisterClass); + addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass); + + computeRegisterProperties(); + } + + /// LowerArguments - This hook must be implemented to indicate how we should + /// lower the arguments for the specified function, into the specified DAG. + virtual std::vector + LowerArguments(Function &F, SelectionDAG &DAG); + + /// LowerCallTo - This hook lowers an abstract call to a function into an + /// actual call. + virtual std::pair + LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG); + + virtual std::pair + LowerVAStart(SDOperand Chain, SelectionDAG &DAG); + + virtual std::pair + LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + const Type *ArgTy, SelectionDAG &DAG); + + virtual std::pair + LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG); + }; + } + + + std::vector + PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { + // + // add beautiful description of PPC stack frame format, or at least some docs + // + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineBasicBlock& BB = MF.front(); + std::vector ArgValues; + + // Due to the rather complicated nature of the PowerPC ABI, rather than a + // fixed size array of physical args, for the sake of simplicity let the STL + // handle tracking them for us. + std::vector argVR, argPR, argOp; + unsigned ArgOffset = 24; + unsigned GPR_remaining = 8; + unsigned FPR_remaining = 13; + unsigned GPR_idx = 0, FPR_idx = 0; + static const unsigned GPR[] = { + PPC::R3, PPC::R4, PPC::R5, PPC::R6, + PPC::R7, PPC::R8, PPC::R9, PPC::R10, + }; + static const unsigned FPR[] = { + PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, + PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 + }; + + // Add DAG nodes to load the arguments... On entry to a function on PPC, + // the arguments start at offset 24, although they are likely to be passed + // in registers. + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { + SDOperand newroot, argt; + unsigned ObjSize; + bool needsLoad = false; + MVT::ValueType ObjectVT = getValueType(I->getType()); + + switch (ObjectVT) { + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + ObjSize = 4; + if (GPR_remaining > 0) { + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + unsigned virtReg = + MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i32)); + argt = newroot = DAG.getCopyFromReg(virtReg, MVT::i32, DAG.getRoot()); + if (ObjectVT != MVT::i32) + argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot); + argVR.push_back(virtReg); + argPR.push_back(GPR[GPR_idx]); + argOp.push_back(PPC::OR); + } else { + needsLoad = true; + } + break; + case MVT::i64: ObjSize = 8; + if (GPR_remaining > 1) { + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]); + MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i32)); + unsigned virtReg = + MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i32))-1; + // FIXME: is this correct? + argt = newroot = DAG.getCopyFromReg(virtReg, MVT::i32, DAG.getRoot()); + argt = DAG.getCopyFromReg(virtReg+1, MVT::i32, newroot); + // Push the arguments for emitting into BB later + argVR.push_back(virtReg); argVR.push_back(virtReg+1); + argPR.push_back(GPR[GPR_idx]); argPR.push_back(GPR[GPR_idx+1]); + argOp.push_back(PPC::OR); argOp.push_back(PPC::OR); + } else { + needsLoad = true; + } + break; + case MVT::f32: ObjSize = 4; + case MVT::f64: ObjSize = 8; + if (FPR_remaining > 0) { + BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]); + unsigned virtReg = + MF.getSSARegMap()->createVirtualRegister(getRegClassFor(ObjectVT)); + argt = newroot = DAG.getCopyFromReg(virtReg, ObjectVT, DAG.getRoot()); + argVR.push_back(virtReg); + argPR.push_back(FPR[FPR_idx]); + argOp.push_back(PPC::FMR); + --FPR_remaining; + ++FPR_idx; + } else { + needsLoad = true; + } + break; + } + + // We need to load the argument to a virtual register if we determined above + // that we ran out of physical registers of the appropriate type + if (needsLoad) { + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN); + } + + // Every 4 bytes of argument space consumes one of the GPRs available for + // argument passing. + if (GPR_remaining > 0) { + unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1; + GPR_remaining -= delta; + GPR_idx += delta; + } + ArgOffset += ObjSize; + + DAG.setRoot(newroot.getValue(1)); + ArgValues.push_back(argt); + } + + for (int i = 0, count = argVR.size(); i < count; ++i) { + if (argOp[i] == PPC::FMR) + BuildMI(&BB, argOp[i], 1, argVR[i]).addReg(argPR[i]); + else + BuildMI(&BB, argOp[i], 2, argVR[i]).addReg(argPR[i]).addReg(argPR[i]); + } + + // If the function takes variable number of arguments, make a frame index for + // the start of the first vararg value... for expansion of llvm.va_start. + if (F.isVarArg()) + VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); + + return ArgValues; + } + + std::pair + PPC32TargetLowering::LowerCallTo(SDOperand Chain, + const Type *RetTy, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG) { + // FIXME + int NumBytes = 56; + + Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + std::vector args_to_use; + for (unsigned i = 0, e = Args.size(); i != e; ++i) + { + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + case MVT::f64: + case MVT::f32: + break; + } + args_to_use.push_back(Args[i].first); + } + + std::vector RetVals; + MVT::ValueType RetTyVT = getValueType(RetTy); + if (RetTyVT != MVT::isVoid) + RetVals.push_back(RetTyVT); + RetVals.push_back(MVT::Other); + + SDOperand TheCall = SDOperand(DAG.getCall(RetVals, + Chain, Callee, args_to_use), 0); + Chain = TheCall.getValue(RetTyVT != MVT::isVoid); + Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + return std::make_pair(TheCall, Chain); + } + + std::pair + PPC32TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { + //vastart just returns the address of the VarArgsFrameIndex slot. + return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32), Chain); + } + + std::pair PPC32TargetLowering:: + LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + const Type *ArgTy, SelectionDAG &DAG) { + abort(); + } + + + std::pair PPC32TargetLowering:: + LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG) { + abort(); + } + + namespace { + + //===--------------------------------------------------------------------===// + /// ISel - PPC32 specific code to select PPC32 machine instructions for + /// SelectionDAG operations. + //===--------------------------------------------------------------------===// + class ISel : public SelectionDAGISel { + + /// Comment Here. + PPC32TargetLowering PPC32Lowering; + + /// ExprMap - As shared expressions are codegen'd, we keep track of which + /// vreg the value is produced in, so we only emit one copy of each compiled + /// tree. + std::map ExprMap; + + public: + ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) + {} + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { + DEBUG(BB->dump()); + // Codegen the basic block. + Select(DAG.getRoot()); + + // Clear state used for selection. + ExprMap.clear(); + } + + unsigned SelectExpr(SDOperand N); + unsigned SelectExprFP(SDOperand N, unsigned Result); + void Select(SDOperand N); + + void SelectAddr(SDOperand N, unsigned& Reg, int& offset); + void SelectBranchCC(SDOperand N); + }; + + /// canUseAsImmediateForOpcode - This method returns a value indicating whether + /// the ConstantSDNode N can be used as an immediate to Opcode. The return + /// values are either 0, 1 or 2. 0 indicates that either N is not a + /// ConstantSDNode, or is not suitable for use by that opcode. A return value + /// of 1 indicates that the constant may be used in normal immediate form. A + /// return value of 2 indicates that the constant may be used in shifted + /// immediate form. If the return value is nonzero, the constant value is + /// placed in Imm. + /// + static unsigned canUseAsImmediateForOpcode(SDOperand N, unsigned Opcode, + unsigned& Imm) { + if (N.getOpcode() != ISD::Constant) return 0; + + int v = (int)cast(N)->getSignExtended(); + + switch(Opcode) { + default: return 0; + case ISD::ADD: + if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; } + if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; } + break; + case ISD::AND: + case ISD::XOR: + case ISD::OR: + if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; } + if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; } + break; + } + return 0; + } + } + + //Check to see if the load is a constant offset from a base register + void ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset) + { + Reg = SelectExpr(N); + offset = 0; + return; + } + + void ISel::SelectBranchCC(SDOperand N) + { + assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???"); + MachineBasicBlock *Dest = + cast(N.getOperand(2))->getBasicBlock(); + unsigned Opc; + + Select(N.getOperand(0)); //chain + SDOperand CC = N.getOperand(1); + + //Giveup and do the stupid thing + unsigned Tmp1 = SelectExpr(CC); + BuildMI(BB, PPC::BNE, 2).addReg(Tmp1).addMBB(Dest); + return; + } + + unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) + { + unsigned Tmp1, Tmp2, Tmp3; + unsigned Opc = 0; + SDNode *Node = N.Val; + MVT::ValueType DestType = N.getValueType(); + unsigned opcode = N.getOpcode(); + + switch (opcode) { + default: + Node->dump(); + assert(0 && "Node not handled!\n"); + + case ISD::SELECT: + abort(); + + case ISD::FP_ROUND: + assert (DestType == MVT::f32 && + N.getOperand(0).getValueType() == MVT::f64 && + "only f64 to f32 conversion supported here"); + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1); + return Result; + + case ISD::FP_EXTEND: + assert (DestType == MVT::f64 && + N.getOperand(0).getValueType() == MVT::f32 && + "only f32 to f64 conversion supported here"); + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1); + return Result; + + case ISD::CopyFromReg: + // FIXME: Handle copy from physregs! + // Just use the specified register as our input. + return dyn_cast(Node)->getReg(); + + case ISD::LOAD: + abort(); + + case ISD::ConstantFP: + abort(); + + case ISD::MUL: + case ISD::ADD: + case ISD::SUB: + case ISD::SDIV: + switch( opcode ) { + case ISD::MUL: Opc = DestType == MVT::f64 ? PPC::FMUL : PPC::FMULS; break; + case ISD::ADD: Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; break; + case ISD::SUB: Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; break; + case ISD::SDIV: Opc = DestType == MVT::f64 ? PPC::FDIV : PPC::FDIVS; break; + }; + + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); + return Result; + + case ISD::EXTLOAD: + abort(); + + case ISD::UINT_TO_FP: + case ISD::SINT_TO_FP: + abort(); + } + assert(0 && "should not get here"); + return 0; + } + + unsigned ISel::SelectExpr(SDOperand N) { + unsigned Result; + unsigned Tmp1, Tmp2, Tmp3; + unsigned Opc = 0; + unsigned opcode = N.getOpcode(); + + SDNode *Node = N.Val; + MVT::ValueType DestType = N.getValueType(); + + unsigned &Reg = ExprMap[N]; + if (Reg) return Reg; + + if (DestType == MVT::f64 || DestType == MVT::f32) + return SelectExprFP(N, Result); + + if (N.getOpcode() != ISD::CALL) + Reg = Result = (N.getValueType() != MVT::Other) ? + MakeReg(N.getValueType()) : 1; + else + abort(); // FIXME: Implement Call + + switch (opcode) { + default: + Node->dump(); + assert(0 && "Node not handled!\n"); + + case ISD::DYNAMIC_STACKALLOC: + abort(); + + case ISD::ConstantPool: + abort(); + + case ISD::FrameIndex: + abort(); + + case ISD::EXTLOAD: + case ISD::ZEXTLOAD: + case ISD::SEXTLOAD: + case ISD::LOAD: + case ISD::GlobalAddress: + case ISD::CALL: + abort(); + + case ISD::SIGN_EXTEND: + case ISD::SIGN_EXTEND_INREG: + Tmp1 = SelectExpr(N.getOperand(0)); + BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1); + return Result; + + case ISD::ZERO_EXTEND_INREG: + Tmp1 = SelectExpr(N.getOperand(0)); + switch(cast(Node)->getExtraValueType()) { + default: + Node->dump(); + assert(0 && "Zero Extend InReg not there yet"); + break; + case MVT::i16: Tmp2 = 16; break; + case MVT::i8: Tmp2 = 24; break; + case MVT::i1: Tmp2 = 31; break; + } + BuildMI(BB, PPC::RLWINM, 5, Result).addReg(Tmp1).addImm(0).addImm(0) + .addImm(Tmp2).addImm(31); + return Result; + + case ISD::SETCC: + abort(); + + case ISD::CopyFromReg: + if (Result == 1) + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + Tmp1 = dyn_cast(Node)->getReg(); + BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1); + return Result; + + case ISD::SHL: + case ISD::SRL: + case ISD::SRA: + case ISD::MUL: + abort(); + + case ISD::ADD: + assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); + Tmp1 = SelectExpr(N.getOperand(0)); + switch(canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + default: assert(0 && "unhandled result code"); + case 0: // No immediate + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case 1: // Low immediate + BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2); + break; + case 2: // Shifted immediate + BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Tmp1).addSImm(Tmp2); + break; + } + return Result; + + case ISD::SUB: + abort(); + + case ISD::AND: + case ISD::OR: + case ISD::XOR: + assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); + Tmp1 = SelectExpr(N.getOperand(0)); + switch(canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { + default: assert(0 && "unhandled result code"); + case 0: // No immediate + Tmp2 = SelectExpr(N.getOperand(1)); + switch (opcode) { + case ISD::AND: Tmp3 = PPC::AND; break; + case ISD::OR: Tmp3 = PPC::OR; break; + case ISD::XOR: Tmp3 = PPC::XOR; break; + } + BuildMI(BB, Tmp3, 2, Result).addReg(Tmp1).addReg(Tmp2); + break; + case 1: // Low immediate + switch (opcode) { + case ISD::AND: Tmp3 = PPC::ANDIo; break; + case ISD::OR: Tmp3 = PPC::ORI; break; + case ISD::XOR: Tmp3 = PPC::XORI; break; + } + BuildMI(BB, Tmp3, 2, Result).addReg(Tmp1).addImm(Tmp2); + break; + case 2: // Shifted immediate + switch (opcode) { + case ISD::AND: Tmp3 = PPC::ANDISo; break; + case ISD::OR: Tmp3 = PPC::ORIS; break; + case ISD::XOR: Tmp3 = PPC::XORIS; break; + } + BuildMI(BB, Tmp3, 2, Result).addReg(Tmp1).addImm(Tmp2); + break; + } + return Result; + + case ISD::UREM: + case ISD::SREM: + case ISD::SDIV: + case ISD::UDIV: + abort(); + + case ISD::FP_TO_UINT: + case ISD::FP_TO_SINT: + abort(); + + case ISD::SELECT: + abort(); + + case ISD::Constant: + switch (N.getValueType()) { + default: assert(0 && "Cannot use constants of this type!"); + case MVT::i1: + BuildMI(BB, PPC::LI, 1, Result) + .addSImm(!cast(N)->isNullValue()); + break; + case MVT::i32: + { + int v = (int)cast(N)->getSignExtended(); + if (v < 32768 && v >= -32768) { + BuildMI(BB, PPC::LI, 1, Result).addSImm(v); + } else { + unsigned Temp = MakeReg(MVT::i32); + BuildMI(BB, PPC::LIS, 1, Temp).addSImm(v >> 16); + BuildMI(BB, PPC::ORI, 2, Result).addReg(Temp).addImm(v & 0xFFFF); + } + } + } + return Result; + } + + return 0; + } + + void ISel::Select(SDOperand N) { + unsigned Tmp1, Tmp2, Opc; + unsigned opcode = N.getOpcode(); + + if (!ExprMap.insert(std::make_pair(N, 1)).second) + return; // Already selected. + + SDNode *Node = N.Val; + + switch (Node->getOpcode()) { + default: + Node->dump(); std::cerr << "\n"; + assert(0 && "Node not handled yet!"); + case ISD::EntryToken: return; // Noop + case ISD::TokenFactor: + for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) + Select(Node->getOperand(i)); + return; + case ISD::ADJCALLSTACKDOWN: + case ISD::ADJCALLSTACKUP: + Select(N.getOperand(0)); + Tmp1 = cast(N.getOperand(1))->getValue(); + Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? PPC::ADJCALLSTACKDOWN : + PPC::ADJCALLSTACKUP; + BuildMI(BB, Opc, 1).addImm(Tmp1); + return; + case ISD::BR: { + MachineBasicBlock *Dest = + cast(N.getOperand(1))->getBasicBlock(); + + Select(N.getOperand(0)); + BuildMI(BB, PPC::B, 1).addMBB(Dest); + return; + } + case ISD::BRCOND: + SelectBranchCC(N); + return; + case ISD::CopyToReg: + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = cast(N)->getReg(); + + if (Tmp1 != Tmp2) { + if (N.getOperand(1).getValueType() == MVT::f64 || + N.getOperand(1).getValueType() == MVT::f32) + BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1); + else + BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); + } + return; + case ISD::ImplicitDef: + Select(N.getOperand(0)); + BuildMI(BB, PPC::IMPLICIT_DEF, 0, cast(N)->getReg()); + return; + case ISD::RET: + switch (N.getNumOperands()) { + default: + assert(0 && "Unknown return instruction!"); + case 3: + assert(N.getOperand(1).getValueType() == MVT::i32 && + N.getOperand(2).getValueType() == MVT::i32 && + "Unknown two-register value!"); + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + Tmp2 = SelectExpr(N.getOperand(2)); + BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1); + BuildMI(BB, PPC::OR, 2, PPC::R4).addReg(Tmp2).addReg(Tmp2); + break; + case 2: + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + switch (N.getOperand(1).getValueType()) { + default: + assert(0 && "Unknown return type!"); + case MVT::f64: + case MVT::f32: + BuildMI(BB, PPC::FMR, 1, PPC::F1).addReg(Tmp1); + break; + case MVT::i32: + BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1); + break; + } + } + BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction + return; + + case ISD::TRUNCSTORE: + case ISD::STORE: + { + SDOperand Chain = N.getOperand(0); + SDOperand Value = N.getOperand(1); + SDOperand Address = N.getOperand(2); + Select(Chain); + + Tmp1 = SelectExpr(Value); //value + + if (opcode == ISD::STORE) { + switch(Value.getValueType()) { + default: assert(0 && "unknown Type in store"); + case MVT::i32: Opc = PPC::STW; break; + case MVT::f64: Opc = PPC::STFD; break; + case MVT::f32: Opc = PPC::STFS; break; + } + } else { //ISD::TRUNCSTORE + switch(cast(Node)->getExtraValueType()) { + default: assert(0 && "unknown Type in store"); + case MVT::i1: //FIXME: DAG does not promote this load + case MVT::i8: Opc = PPC::STB; break; + case MVT::i16: Opc = PPC::STH; break; + } + } + + if (Address.getOpcode() == ISD::GlobalAddress) + { + BuildMI(BB, Opc, 2).addReg(Tmp1) + .addGlobalAddress(cast(Address)->getGlobal()); + } + else if(Address.getOpcode() == ISD::FrameIndex) + { + BuildMI(BB, Opc, 2).addReg(Tmp1) + .addFrameIndex(cast(Address)->getIndex()); + } + else + { + int offset; + SelectAddr(Address, Tmp2, offset); + BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2); + } + return; + } + case ISD::EXTLOAD: + case ISD::SEXTLOAD: + case ISD::ZEXTLOAD: + case ISD::LOAD: + case ISD::CopyFromReg: + case ISD::CALL: + case ISD::DYNAMIC_STACKALLOC: + ExprMap.erase(N); + SelectExpr(N); + return; + } + assert(0 && "Should not be reached!"); + } + + + /// createPPC32PatternInstructionSelector - This pass converts an LLVM function + /// into a machine code representation using pattern matching and a machine + /// description file. + /// + FunctionPass *llvm::createPPC32ISelPattern(TargetMachine &TM) { + return new ISel(TM); + } \ No newline at end of file Index: llvm/lib/Target/PowerPC/PowerPC.h diff -u llvm/lib/Target/PowerPC/PowerPC.h:1.11 llvm/lib/Target/PowerPC/PowerPC.h:1.12 --- llvm/lib/Target/PowerPC/PowerPC.h:1.11 Sun Nov 14 14:34:01 2004 +++ llvm/lib/Target/PowerPC/PowerPC.h Wed Mar 23 22:41:43 2005 @@ -24,6 +24,7 @@ FunctionPass *createPPCBranchSelectionPass(); FunctionPass *createPPC32ISelSimple(TargetMachine &TM); +FunctionPass *createPPC32ISelPattern(TargetMachine &TM); FunctionPass *createPPC64ISelSimple(TargetMachine &TM); FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM); FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM); Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.46 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.47 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.46 Wed Mar 2 15:56:00 2005 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Wed Mar 23 22:41:43 2005 @@ -37,6 +37,8 @@ cl::opt EnablePPCLSR("enable-lsr-for-ppc", cl::desc("Enable LSR for PPC (beta option!)"), cl::Hidden); + cl::opt EnablePatternISel("pattern-isel", cl::Hidden, + cl::desc("Enable the pattern isel XXX FIXME")); } namespace { @@ -96,6 +98,8 @@ if (LP64) PM.add(createPPC64ISelSimple(*this)); + else if (EnablePatternISel) + PM.add(createPPC32ISelPattern(*this)); else PM.add(createPPC32ISelSimple(*this)); From alkis at cs.uiuc.edu Wed Mar 23 22:47:58 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 23 Mar 2005 22:47:58 -0600 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/Compiler.h Message-ID: <200503240447.WAA04335@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: Compiler.h updated: 1.13 -> 1.14 --- Log message: Remove ClassInfo class and introduce the Class class that represents a compile time java/lang/Class. The new Class object represents not only classes read from class files but also primitive and array classes. This allows us to simplify the way class information is gathered. The goal is to eliminate the VTableInfo class by merging it with Class as well. This will simplify a lot of code: both Class representation code and code generation code in the Compiler itself. --- Diffs of the changes: (+0 -2) Compiler.h | 2 -- 1 files changed, 2 deletions(-) Index: llvm-java/include/llvm/Java/Compiler.h diff -u llvm-java/include/llvm/Java/Compiler.h:1.13 llvm-java/include/llvm/Java/Compiler.h:1.14 --- llvm-java/include/llvm/Java/Compiler.h:1.13 Tue Jan 25 17:46:34 2005 +++ llvm-java/include/llvm/Java/Compiler.h Wed Mar 23 22:47:47 2005 @@ -21,8 +21,6 @@ std::auto_ptr compile(const std::string& className); - extern Type* ObjectBaseTy; - extern Type* ObjectBaseRefTy; extern Type* VTableBaseTy; extern Type* VTableBaseRefTy; From alkis at cs.uiuc.edu Wed Mar 23 22:47:58 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed, 23 Mar 2005 22:47:58 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.h Resolver.cpp Class.h Class.cpp OperandStack.h OperandStack.cpp Locals.h Locals.cpp Compiler.cpp Support.h Message-ID: <200503240447.WAA04355@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.h added (r1.1) Resolver.cpp added (r1.1) Class.h added (r1.1) Class.cpp added (r1.1) OperandStack.h updated: 1.3 -> 1.4 OperandStack.cpp updated: 1.12 -> 1.13 Locals.h updated: 1.5 -> 1.6 Locals.cpp updated: 1.10 -> 1.11 Compiler.cpp updated: 1.241 -> 1.242 Support.h (r1.2) removed --- Log message: Remove ClassInfo class and introduce the Class class that represents a compile time java/lang/Class. The new Class object represents not only classes read from class files but also primitive and array classes. This allows us to simplify the way class information is gathered. The goal is to eliminate the VTableInfo class by merging it with Class as well. This will simplify a lot of code: both Class representation code and code generation code in the Compiler itself. --- Diffs of the changes: (+658 -490) Class.cpp | 108 ++++++++++ Class.h | 67 ++++++ Compiler.cpp | 581 ++++++++++++++----------------------------------------- Locals.cpp | 14 - Locals.h | 7 OperandStack.cpp | 93 ++++---- OperandStack.h | 21 + Resolver.cpp | 177 ++++++++++++++++ Resolver.h | 80 +++++++ 9 files changed, 658 insertions(+), 490 deletions(-) Index: llvm-java/lib/Compiler/Resolver.h diff -c /dev/null llvm-java/lib/Compiler/Resolver.h:1.1 *** /dev/null Wed Mar 23 22:47:57 2005 --- llvm-java/lib/Compiler/Resolver.h Wed Mar 23 22:47:47 2005 *************** *** 0 **** --- 1,80 ---- + //===-- Resolver.h - Class resolver for Java classes ------------*- 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 declaration of a Java class resolver. This + // object creates Class objects out of loaded ClassFiles. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_JAVA_RESOLVER_H + #define LLVM_JAVA_RESOLVER_H + + #include "Class.h" + #include + #include + #include + #include + #include + #include + + namespace llvm { namespace Java { + + class Resolver { + Module& module_; + typedef std::map ClassMap; + ClassMap classMap_; + unsigned nextInterfaceIndex_; + const Type* objectBaseType_; + const Type* objectBaseRefType_; + + const Class& getClassForDesc(const std::string& descriptor); + + const Type* getTypeHelper(const std::string&, + unsigned& i, + bool memberMethod = false) const; + + public: + Resolver(Module& module); + + const Type* getObjectBaseType() const { return objectBaseType_; } + const Type* getObjectBaseRefType() const { return objectBaseRefType_; } + + const Class& getFieldClass(const std::string& descriptor); + const Type* getType(const std::string& descriptor, + bool memberMethod = false) const; + const Type* getStorageType(const Type* type) const; + + inline bool isTwoSlotType(const Type* type) const { + return type == Type::LongTy || type == Type::DoubleTy; + } + + inline bool isOneSlotType(const Type* type) const { + return !isTwoSlotType(type); + } + + const Class& getClass(const std::string& className) { + if (className[0] == '[') + return getClassForDesc(className); + else + return getClassForDesc('L' + className + ';'); + } + const Class& getClass(const Field& field) { + return getClassForDesc(field.getDescriptor()->str()); + } + const Class& getClass(JType type); + const Class& getArrayClass(JType type); + + unsigned getNextInterfaceIndex() { return nextInterfaceIndex_++; } + Module& getModule() { return module_; } + + }; + + } } // namespace llvm::Java + + #endif//LLVM_JAVA_RESOLVER_H Index: llvm-java/lib/Compiler/Resolver.cpp diff -c /dev/null llvm-java/lib/Compiler/Resolver.cpp:1.1 *** /dev/null Wed Mar 23 22:47:58 2005 --- llvm-java/lib/Compiler/Resolver.cpp Wed Mar 23 22:47:47 2005 *************** *** 0 **** --- 1,177 ---- + //===-- Resolver.cpp - Class resolver for Java classes ----------*- 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 implementation of the Java class resolver. + // + //===----------------------------------------------------------------------===// + + #define DEBUG_TYPE "javaresolver" + + #include "Resolver.h" + #include + #include + #include + + using namespace llvm; + using namespace llvm::Java; + + Resolver::Resolver(Module& module) + : module_(module), + nextInterfaceIndex_(0), + objectBaseType_(OpaqueType::get()), + objectBaseRefType_(PointerType::get(objectBaseType_)) + { + classMap_.insert(std::make_pair("B", Class(*this, Type::SByteTy))); + classMap_.insert(std::make_pair("C", Class(*this, Type::UShortTy))); + classMap_.insert(std::make_pair("D", Class(*this, Type::DoubleTy))); + classMap_.insert(std::make_pair("F", Class(*this, Type::FloatTy))); + classMap_.insert(std::make_pair("I", Class(*this, Type::IntTy))); + classMap_.insert(std::make_pair("J", Class(*this, Type::LongTy))); + classMap_.insert(std::make_pair("S", Class(*this, Type::ShortTy))); + classMap_.insert(std::make_pair("Z", Class(*this, Type::BoolTy))); + classMap_.insert(std::make_pair("V", Class(*this, Type::VoidTy))); + + module_.addTypeName("struct.llvm_java_object_base", objectBaseType_); + } + + const Type* Resolver::getType(const std::string& descriptor, + bool memberMethod) const + { + unsigned i = 0; + return getTypeHelper(descriptor, i, memberMethod); + } + + const Type* Resolver::getTypeHelper(const std::string& descr, + unsigned& i, + bool memberMethod) const + { + assert(i < descr.size()); + switch (descr[i++]) { + case 'B': return Type::SByteTy; + case 'C': return Type::UShortTy; + case 'D': return Type::DoubleTy; + case 'F': return Type::FloatTy; + case 'I': return Type::IntTy; + case 'J': return Type::LongTy; + case 'S': return Type::ShortTy; + case 'Z': return Type::BoolTy; + case 'V': return Type::VoidTy; + case 'L': { + unsigned e = descr.find(';', i); + i = e + 1; + return objectBaseRefType_; + } + case '[': + // Skip '['s. + if (descr[i] == '[') + do { ++i; } while (descr[i] == '['); + // Consume the element type + getTypeHelper(descr, i); + return objectBaseRefType_; + case '(': { + std::vector params; + if (memberMethod) + params.push_back(objectBaseRefType_); + while (descr[i] != ')') + params.push_back(getTypeHelper(descr, i)); + return FunctionType::get(getTypeHelper(descr, ++i), params, false); + } + // FIXME: Throw something + default: assert(0 && "Cannot parse type descriptor!"); + } + return 0; // not reached + } + + const Class& Resolver::getClassForDesc(const std::string& descriptor) + { + ClassMap::iterator it = classMap_.lower_bound(descriptor); + if (it == classMap_.end() || it->first != descriptor) { + DEBUG(std::cerr << "Building Class for: " << descriptor << '\n'); + // Insert dummy class to the map. + it = classMap_.insert(it, std::make_pair(descriptor, Class(*this))); + switch (descriptor[0]) { + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + case 'Z': + case 'V': + assert(0 && "Primitive classes should already be in the map!"); + abort(); + case 'L': { + unsigned pos = descriptor.find(';', 1); + const std::string& className = descriptor.substr(1, pos - 1); + it->second.buildClass(className); + break; + } + case '[': { + const std::string& componentDescriptor = descriptor.substr(1); + it->second.buildArrayClass(getClassForDesc(componentDescriptor)); + break; + } + default: + assert(0 && "Cannot parse type descriptor!"); + abort(); + } + module_.addTypeName(descriptor, it->second.getStructType()); + DEBUG(std::cerr << "Built Class for: " << descriptor << '\n'); + } + + return it->second; + } + + const Class& Resolver::getClass(JType type) + { + switch (type) { + case BOOLEAN: return getClassForDesc("Z"); + case CHAR: return getClassForDesc("C"); + case FLOAT: return getClassForDesc("F"); + case DOUBLE: return getClassForDesc("D"); + case BYTE: return getClassForDesc("B"); + case SHORT: return getClassForDesc("S"); + case INT: return getClassForDesc("I"); + case LONG: return getClassForDesc("J"); + default: assert(0 && "Unhandled JType!"); abort(); + } + } + + const Class& Resolver::getArrayClass(JType type) + { + switch (type) { + case BOOLEAN: return getClassForDesc("[Z"); + case CHAR: return getClassForDesc("[C"); + case FLOAT: return getClassForDesc("[F"); + case DOUBLE: return getClassForDesc("[D"); + case BYTE: return getClassForDesc("[B"); + case SHORT: return getClassForDesc("[S"); + case INT: return getClassForDesc("[I"); + case LONG: return getClassForDesc("[J"); + default: assert(0 && "Unhandled JType!"); abort(); + } + } + + const Type* Resolver::getStorageType(const Type* type) const + { + if (isa(type)) + return objectBaseRefType_; + else if (type == Type::BoolTy || + type == Type::UByteTy || + type == Type::SByteTy || + type == Type::UShortTy || + type == Type::ShortTy || + type == Type::UIntTy) + return Type::IntTy; + else if (type == Type::ULongTy) + return Type::LongTy; + else + return type; + } Index: llvm-java/lib/Compiler/Class.h diff -c /dev/null llvm-java/lib/Compiler/Class.h:1.1 *** /dev/null Wed Mar 23 22:47:58 2005 --- llvm-java/lib/Compiler/Class.h Wed Mar 23 22:47:47 2005 *************** *** 0 **** --- 1,67 ---- + //===-- Class.h - Compiler representation of a Java class -------*- 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 declaration of the Class class that represents a + // compile time representation of a Java class (java.lang.Class). + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_JAVA_CLASS_H + #define LLVM_JAVA_CLASS_H + + #include + #include + #include + #include + + namespace llvm { namespace Java { + + class Resolver; + + class Class { + static const unsigned INVALID_INTERFACE_INDEX = 0xFFFFFFFF; + + Resolver* resolver_; + const Class* componentClass_; + Type* structType_; + const Type* type_; + unsigned interfaceIndex_; + typedef std::map Field2IndexMap; + Field2IndexMap f2iMap_; + typedef std::vector ElementTypes; + ElementTypes elementTypes; + + void addField(const std::string& name, const Type* type); + void resolveType(); + + // Creates a dummy class. + explicit Class(Resolver& resolver); + + // Creates primitive class for type. + Class(Resolver& resolver, const Type* type); + + // Builds the class object for the named class. + void buildClass(const std::string& className); + // Builds the array class object of component type componentClass. + void buildArrayClass(const Class& componentClass); + + friend class Resolver; + + public: + const Type* getStructType() const { return structType_; } + const Type* getType() const { return type_; } + const Class* getComponentClass() const { return componentClass_; } + bool isArray() const { return componentClass_; } + unsigned getInterfaceIndex() const { return interfaceIndex_; } + int getFieldIndex(const std::string& name) const; + }; + + } } // namespace llvm::Java + + #endif//LLVM_JAVA_CLASS_H Index: llvm-java/lib/Compiler/Class.cpp diff -c /dev/null llvm-java/lib/Compiler/Class.cpp:1.1 *** /dev/null Wed Mar 23 22:47:58 2005 --- llvm-java/lib/Compiler/Class.cpp Wed Mar 23 22:47:47 2005 *************** *** 0 **** --- 1,108 ---- + //===-- Class.cpp - Compiler representation of a Java class -----*- 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 declaration of the Class class that represents a + // compile time representation of a Java class (java.lang.Class). This unlike + // a classfile representation, it resolves the constant pool, creates global + // variables for the static members of this class and also creates the class + // record (vtable) of this class. + // + //===----------------------------------------------------------------------===// + + #include "Class.h" + #include "Resolver.h" + #include + #include + + #define LLVM_JAVA_OBJECT_BASE "struct.llvm_java_object_base" + + using namespace llvm; + using namespace llvm::Java; + + Class::Class(Resolver& resolver) + : resolver_(&resolver), + componentClass_(NULL), + structType_(OpaqueType::get()), + type_(PointerType::get(structType_)), + interfaceIndex_(INVALID_INTERFACE_INDEX) + { + + } + + Class::Class(Resolver& resolver, const Type* type) + : resolver_(&resolver), + componentClass_(NULL), + structType_(0), + type_(type), + interfaceIndex_(INVALID_INTERFACE_INDEX) + { + + } + + void Class::addField(const std::string& name, const Type* type) + { + f2iMap_.insert(std::make_pair(name, elementTypes.size())); + elementTypes.push_back(type); + } + + int Class::getFieldIndex(const std::string& name) const { + Field2IndexMap::const_iterator it = f2iMap_.find(name); + return it == f2iMap_.end() ? -1 : it->second; + } + + void Class::resolveType() { + PATypeHolder holder = structType_; + Type* resolvedType = StructType::get(elementTypes); + cast(structType_)->refineAbstractTypeTo(resolvedType); + structType_ = holder.get(); + type_ = PointerType::get(structType_); + } + + void Class::buildClass(const std::string& className) + { + const ClassFile* cf = ClassFile::get(className); + + if (cf->isInterface()) + interfaceIndex_ = resolver_->getNextInterfaceIndex(); + + // This is any class but java/lang/Object. + if (cf->getSuperClass()) { + const Class& superClass = + resolver_->getClass(cf->getSuperClass()->getName()->str()); + + // We first add the struct of the super class. + addField("super", superClass.getStructType()); + } + // This is java/lang/Object. + else + addField("base", resolver_->getObjectBaseType()); + + // Then we add the rest of the fields. + const Fields& fields = cf->getFields(); + for (unsigned i = 0, e = fields.size(); i != e; ++i) { + Field& field = *fields[i]; + if (!field.isStatic()) + addField(field.getName()->str(), resolver_->getClass(field).getType()); + } + + resolveType(); + + assert(!isa(getStructType()) &&"Class not initialized properly!"); + } + + void Class::buildArrayClass(const Class& componentClass) + { + componentClass_ = &componentClass; + addField("super", resolver_->getClass("java/lang/Object").getStructType()); + addField("", Type::UIntTy); + addField("", ArrayType::get(componentClass_->getType(), 0)); + + resolveType(); + } + Index: llvm-java/lib/Compiler/OperandStack.h diff -u llvm-java/lib/Compiler/OperandStack.h:1.3 llvm-java/lib/Compiler/OperandStack.h:1.4 --- llvm-java/lib/Compiler/OperandStack.h:1.3 Fri Jan 21 19:30:12 2005 +++ llvm-java/lib/Compiler/OperandStack.h Wed Mar 23 22:47:47 2005 @@ -15,34 +15,39 @@ #ifndef LLVM_JAVA_OPERANDSTACK_H #define LLVM_JAVA_OPERANDSTACK_H +#include "Resolver.h" #include #include -#include #include #include namespace llvm { class AllocaInst; + class Instruction; + class Value; } // namespace llvm namespace llvm { namespace Java { class OperandStack { - unsigned currentDepth; + const Resolver* resolver_; + unsigned currentDepth_; typedef std::map SlotMap; - std::vector TheStack; + std::vector stack_; public: - explicit OperandStack(unsigned maxDepth) - : currentDepth(0), TheStack(maxDepth) { } + explicit OperandStack(const Resolver& resolver, unsigned maxDepth) + : resolver_(&resolver), + currentDepth_(0), + stack_(maxDepth) { } - unsigned getDepth() const { return currentDepth; } + unsigned getDepth() const { return currentDepth_; } void setDepth(unsigned newDepth) { - assert(newDepth < TheStack.size() && + assert(newDepth < stack_.size() && "Cannot set depth greater than the max depth!"); - currentDepth = newDepth; + currentDepth_ = newDepth; } /// @brief - Pushes the value \c value on the virtual operand Index: llvm-java/lib/Compiler/OperandStack.cpp diff -u llvm-java/lib/Compiler/OperandStack.cpp:1.12 llvm-java/lib/Compiler/OperandStack.cpp:1.13 --- llvm-java/lib/Compiler/OperandStack.cpp:1.12 Thu Feb 3 16:37:32 2005 +++ llvm-java/lib/Compiler/OperandStack.cpp Wed Mar 23 22:47:47 2005 @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #include "OperandStack.h" -#include "Support.h" #include #include #include @@ -57,33 +56,33 @@ void OperandStack::push(Value* value, BasicBlock* insertAtEnd) { - assert(currentDepth < TheStack.size() && "Pushing to a full stack!"); + assert(currentDepth_ < stack_.size() && "Pushing to a full stack!"); const Type* valueTy = value->getType(); // std::cerr << "PUSH(" << insertAtEnd << "/" -// << insertAtEnd->getParent()->getName() << " " << TheStack.size() -// << ") Depth: " << currentDepth << " type: " << *valueTy << '\n'; - const Type* storageTy = getStorageType(valueTy); +// << insertAtEnd->getParent()->getName() << " " << stack_.size() +// << ") Depth: " << currentDepth_ << " type: " << *valueTy << '\n'; + const Type* storageTy = resolver_->getStorageType(valueTy); if (valueTy != storageTy) value = new CastInst(value, storageTy, "to-storage-type", insertAtEnd); - SlotMap& slotMap = TheStack[currentDepth]; + SlotMap& slotMap = stack_[currentDepth_]; AllocaInst* slot = getOrCreateSlot(slotMap, storageTy, insertAtEnd); new StoreInst(value, slot, insertAtEnd); - currentDepth += 1 + isTwoSlotType(storageTy); - assert(currentDepth < TheStack.size() && "Pushed more than max stack depth!"); + currentDepth_ += 1 + resolver_->isTwoSlotType(storageTy); + assert(currentDepth_ < stack_.size() && "Pushed more than max stack depth!"); } llvm::Value* OperandStack::pop(const Type* valueTy, BasicBlock* insertAtEnd) { - const Type* storageTy = getStorageType(valueTy); + const Type* storageTy = resolver_->getStorageType(valueTy); - assert(currentDepth != 0 && "Popping from an empty stack!"); - currentDepth -= 1 + isTwoSlotType(storageTy); + assert(currentDepth_ != 0 && "Popping from an empty stack!"); + currentDepth_ -= 1 + resolver_->isTwoSlotType(storageTy); // std::cerr << "POP(" << insertAtEnd->getName() << "/" -// << insertAtEnd->getParent()->getName() << " " << TheStack.size() -// << ") Depth: " << currentDepth << " type: " << *valueTy << '\n'; +// << insertAtEnd->getParent()->getName() << " " << stack_.size() +// << ") Depth: " << currentDepth_ << " type: " << *valueTy << '\n'; - SlotMap& slotMap = TheStack[currentDepth]; + SlotMap& slotMap = stack_[currentDepth_]; SlotMap::iterator it = slotMap.find(storageTy); assert(it != slotMap.end() && "Type mismatch on operand stack!"); @@ -96,8 +95,8 @@ /// ..., value -> ... void OperandStack::do_pop(BasicBlock* insertAtEnd) { - assert(currentDepth != 0 && "Popping from an empty stack!"); - --currentDepth; + assert(currentDepth_ != 0 && "Popping from an empty stack!"); + --currentDepth_; } /// ..., value2, value1 -> ... @@ -111,49 +110,49 @@ /// ..., value -> ..., value, value void OperandStack::do_dup(BasicBlock* insertAtEnd) { - assert(currentDepth != 0 && "Popping from an empty stack!"); - copySlots(TheStack[currentDepth-1], TheStack[currentDepth], insertAtEnd); - ++currentDepth; + assert(currentDepth_ != 0 && "Popping from an empty stack!"); + copySlots(stack_[currentDepth_-1], stack_[currentDepth_], insertAtEnd); + ++currentDepth_; } /// ..., value2, value1 -> ..., value1, value2, value1 void OperandStack::do_dup_x1(BasicBlock* insertAtEnd) { - copySlots(TheStack[currentDepth-1], TheStack[currentDepth], insertAtEnd); - copySlots(TheStack[currentDepth-2], TheStack[currentDepth-1], insertAtEnd); - copySlots(TheStack[currentDepth], TheStack[currentDepth-2], insertAtEnd); - ++currentDepth; + copySlots(stack_[currentDepth_-1], stack_[currentDepth_], insertAtEnd); + copySlots(stack_[currentDepth_-2], stack_[currentDepth_-1], insertAtEnd); + copySlots(stack_[currentDepth_], stack_[currentDepth_-2], insertAtEnd); + ++currentDepth_; } /// ..., value3, value2, value1 -> ..., value1, value3, value2, value1 /// ..., value2, value1 -> ..., value1, value2, value1 void OperandStack::do_dup_x2(BasicBlock* insertAtEnd) { - copySlots(TheStack[currentDepth-1], TheStack[currentDepth], insertAtEnd); - copySlots(TheStack[currentDepth-2], TheStack[currentDepth-1], insertAtEnd); - copySlots(TheStack[currentDepth-3], TheStack[currentDepth-2], insertAtEnd); - copySlots(TheStack[currentDepth], TheStack[currentDepth-3], insertAtEnd); - ++currentDepth; + copySlots(stack_[currentDepth_-1], stack_[currentDepth_], insertAtEnd); + copySlots(stack_[currentDepth_-2], stack_[currentDepth_-1], insertAtEnd); + copySlots(stack_[currentDepth_-3], stack_[currentDepth_-2], insertAtEnd); + copySlots(stack_[currentDepth_], stack_[currentDepth_-3], insertAtEnd); + ++currentDepth_; } /// ..., value2, value1 -> ..., value2, value1, value2, value1 void OperandStack::do_dup2(BasicBlock* insertAtEnd) { - copySlots(TheStack[currentDepth-2], TheStack[currentDepth], insertAtEnd); - copySlots(TheStack[currentDepth-1], TheStack[currentDepth+1], insertAtEnd); - currentDepth += 2; + copySlots(stack_[currentDepth_-2], stack_[currentDepth_], insertAtEnd); + copySlots(stack_[currentDepth_-1], stack_[currentDepth_+1], insertAtEnd); + currentDepth_ += 2; } /// ..., value3, value2, value1 -> ..., value2, value1, value3, value2, value1 /// ..., value2, value1 -> ..., value1, value2, value1 void OperandStack::do_dup2_x1(BasicBlock* insertAtEnd) { - copySlots(TheStack[currentDepth-1], TheStack[currentDepth+1], insertAtEnd); - copySlots(TheStack[currentDepth-2], TheStack[currentDepth], insertAtEnd); - copySlots(TheStack[currentDepth-3], TheStack[currentDepth-1], insertAtEnd); - copySlots(TheStack[currentDepth+1], TheStack[currentDepth-2], insertAtEnd); - copySlots(TheStack[currentDepth], TheStack[currentDepth-3], insertAtEnd); - currentDepth += 2; + copySlots(stack_[currentDepth_-1], stack_[currentDepth_+1], insertAtEnd); + copySlots(stack_[currentDepth_-2], stack_[currentDepth_], insertAtEnd); + copySlots(stack_[currentDepth_-3], stack_[currentDepth_-1], insertAtEnd); + copySlots(stack_[currentDepth_+1], stack_[currentDepth_-2], insertAtEnd); + copySlots(stack_[currentDepth_], stack_[currentDepth_-3], insertAtEnd); + currentDepth_ += 2; } /// ..., value4, value3, value2, value1 -> ..., value2, value1, value4, value3, value2, value1 @@ -162,19 +161,19 @@ /// ..., value2, value1 -> ..., value1, value2, value1 void OperandStack::do_dup2_x2(BasicBlock* insertAtEnd) { - copySlots(TheStack[currentDepth-1], TheStack[currentDepth+1], insertAtEnd); - copySlots(TheStack[currentDepth-2], TheStack[currentDepth], insertAtEnd); - copySlots(TheStack[currentDepth-3], TheStack[currentDepth-1], insertAtEnd); - copySlots(TheStack[currentDepth-4], TheStack[currentDepth-2], insertAtEnd); - copySlots(TheStack[currentDepth+1], TheStack[currentDepth-3], insertAtEnd); - copySlots(TheStack[currentDepth], TheStack[currentDepth-4], insertAtEnd); - currentDepth += 2; + copySlots(stack_[currentDepth_-1], stack_[currentDepth_+1], insertAtEnd); + copySlots(stack_[currentDepth_-2], stack_[currentDepth_], insertAtEnd); + copySlots(stack_[currentDepth_-3], stack_[currentDepth_-1], insertAtEnd); + copySlots(stack_[currentDepth_-4], stack_[currentDepth_-2], insertAtEnd); + copySlots(stack_[currentDepth_+1], stack_[currentDepth_-3], insertAtEnd); + copySlots(stack_[currentDepth_], stack_[currentDepth_-4], insertAtEnd); + currentDepth_ += 2; } void OperandStack::do_swap(BasicBlock* insertAtEnd) { SlotMap tmp; - copySlots(TheStack[currentDepth-1], tmp, insertAtEnd); - copySlots(TheStack[currentDepth-2], TheStack[currentDepth-1], insertAtEnd); - copySlots(tmp, TheStack[currentDepth-2], insertAtEnd); + copySlots(stack_[currentDepth_-1], tmp, insertAtEnd); + copySlots(stack_[currentDepth_-2], stack_[currentDepth_-1], insertAtEnd); + copySlots(tmp, stack_[currentDepth_-2], insertAtEnd); } Index: llvm-java/lib/Compiler/Locals.h diff -u llvm-java/lib/Compiler/Locals.h:1.5 llvm-java/lib/Compiler/Locals.h:1.6 --- llvm-java/lib/Compiler/Locals.h:1.5 Thu Feb 3 16:37:32 2005 +++ llvm-java/lib/Compiler/Locals.h Wed Mar 23 22:47:47 2005 @@ -15,7 +15,7 @@ #ifndef LLVM_JAVA_LOCALS_H #define LLVM_JAVA_LOCALS_H -#include +#include "Resolver.h" #include #include @@ -32,11 +32,12 @@ namespace llvm { namespace Java { class Locals { + const Resolver* resolver_; typedef std::map SlotMap; - std::vector TheLocals; + std::vector locals_; public: - explicit Locals(unsigned maxLocals); + Locals(const Resolver& resolver, unsigned maxLocals); /// @brief - Stores the value \c value on the \c i'th local /// variable and appends any instructions to implement this to \c Index: llvm-java/lib/Compiler/Locals.cpp diff -u llvm-java/lib/Compiler/Locals.cpp:1.10 llvm-java/lib/Compiler/Locals.cpp:1.11 --- llvm-java/lib/Compiler/Locals.cpp:1.10 Thu Feb 3 16:37:32 2005 +++ llvm-java/lib/Compiler/Locals.cpp Wed Mar 23 22:47:47 2005 @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #include "Locals.h" -#include "Support.h" #include #include #include @@ -24,8 +23,9 @@ using namespace llvm; using namespace llvm::Java; -Locals::Locals(unsigned maxLocals) - : TheLocals(maxLocals) +Locals::Locals(const Resolver& resolver, unsigned maxLocals) + : resolver_(&resolver), + locals_(maxLocals) { } @@ -33,11 +33,11 @@ void Locals::store(unsigned i, Value* value, BasicBlock* insertAtEnd) { const Type* valueTy = value->getType(); - const Type* storageTy = getStorageType(valueTy); + const Type* storageTy = resolver_->getStorageType(valueTy); if (valueTy != storageTy) value = new CastInst(value, storageTy, "to-storage-type", insertAtEnd); - SlotMap& slotMap = TheLocals[i]; + SlotMap& slotMap = locals_[i]; SlotMap::iterator it = slotMap.find(storageTy); if (it == slotMap.end()) { @@ -54,9 +54,9 @@ llvm::Value* Locals::load(unsigned i, const Type* valueTy, BasicBlock* insertAtEnd) { - const Type* storageTy = getStorageType(valueTy); + const Type* storageTy = resolver_->getStorageType(valueTy); - SlotMap& slotMap = TheLocals[i]; + SlotMap& slotMap = locals_[i]; SlotMap::iterator it = slotMap.find(storageTy); assert(it != slotMap.end() && "Attempt to load a non initialized global!"); Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.241 llvm-java/lib/Compiler/Compiler.cpp:1.242 --- llvm-java/lib/Compiler/Compiler.cpp:1.241 Wed Mar 23 22:24:24 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Wed Mar 23 22:47:47 2005 @@ -17,7 +17,7 @@ #include "BasicBlockBuilder.h" #include "Locals.h" #include "OperandStack.h" -#include "Support.h" +#include "Resolver.h" #include #include #include @@ -43,8 +43,6 @@ using namespace llvm; using namespace llvm::Java; -Type* llvm::Java::ObjectBaseTy = OpaqueType::get(); -Type* llvm::Java::ObjectBaseRefTy = PointerType::get(ObjectBaseTy); Type* llvm::Java::VTableBaseTy = OpaqueType::get(); Type* llvm::Java::VTableBaseRefTy = PointerType::get(VTableBaseTy); @@ -61,6 +59,7 @@ class Compiler : public BytecodeParser { Module& module_; + std::auto_ptr resolver_; GlobalVariable* JNIEnvPtr_; const ClassFile* cf_; std::auto_ptr bbBuilder_; @@ -78,46 +77,6 @@ typedef SetVector FunctionSet; FunctionSet toCompileFunctions_; - /// This class containts the LLVM type that a class maps to and - /// the max interface index of the interfaces this class - /// implements or the interface index of this interface if this - /// represents an interface. It also contains a map from fields to - /// struct indices for this class (used to index into the class - /// object). - class ClassInfo { - Type* type_; - unsigned interfaceIdx_; - typedef std::map Field2IndexMap; - Field2IndexMap f2iMap_; - typedef std::vector ElementTypes; - ElementTypes elementTypes; - - static unsigned InterfaceCount; - - public: - ClassInfo() : type_(OpaqueType::get()), interfaceIdx_(0) { } - Type* getType() { return type_; } - const Type* getType() const { return type_; } - void addField(const std::string& name, const Type* type) { - f2iMap_.insert(std::make_pair(name, elementTypes.size())); - elementTypes.push_back(type); - } - int getFieldIndex(const std::string& name) const { - Field2IndexMap::const_iterator it = f2iMap_.find(name); - return it == f2iMap_.end() ? -1 : it->second; - } - void resolveType() { - PATypeHolder holder = type_; - Type* resolvedType = StructType::get(elementTypes); - cast(type_)->refineAbstractTypeTo(resolvedType); - type_ = holder.get(); - } - unsigned getInterfaceIndex() const { return interfaceIdx_; } - void setNextInterfaceIndex() { interfaceIdx_ = InterfaceCount++; } - }; - typedef std::map Class2ClassInfoMap; - Class2ClassInfoMap c2ciMap_; - /// This class contains the vtable of a class, a vector with the /// vtables of its super classes (with the class higher in the /// hierarchy first). It also contains a map from methods to @@ -140,7 +99,10 @@ public: Compiler(Module& m) - : module_(m), locals_(0), opStack_(0) { + : module_(m), + resolver_(new Resolver(module_)), + locals_(*resolver_, 0), + opStack_(*resolver_, 0) { Type* JNIEnvTy = OpaqueType::get(); module_.addTypeName("JNIEnv", JNIEnvTy); JNIEnvPtr_ = new GlobalVariable(JNIEnvTy, @@ -149,20 +111,19 @@ NULL, "llvm_java_JNIEnv", &module_); - module_.addTypeName("llvm_java_object_base", ObjectBaseTy); module_.addTypeName("llvm_java_object_vtable", VTableBaseTy); getVtable_ = module_.getOrInsertFunction( "llvm_java_get_vtable", VTableBaseRefTy, - ObjectBaseRefTy, NULL); + resolver_->getObjectBaseRefType(), NULL); setVtable_ = module_.getOrInsertFunction( "llvm_java_set_vtable", Type::VoidTy, - ObjectBaseRefTy, VTableBaseRefTy, NULL); + resolver_->getObjectBaseRefType(), VTableBaseRefTy, NULL); throw_ = module_.getOrInsertFunction( "llvm_java_throw", Type::IntTy, - ObjectBaseRefTy, NULL); + resolver_->getObjectBaseRefType(), NULL); isInstanceOf_ = module_.getOrInsertFunction( "llvm_java_is_instance_of", Type::IntTy, - ObjectBaseRefTy, VTableBaseRefTy, NULL); + resolver_->getObjectBaseRefType(), VTableBaseRefTy, NULL); memcpy_ = module_.getOrInsertFunction( "llvm.memcpy", Type::VoidTy, PointerType::get(Type::SByteTy), @@ -199,8 +160,7 @@ // Create a new byte[] object and initialize it with the // contents of this string constant. Value* count = ConstantUInt::get(Type::UIntTy, str.size()); - Value* arrayRef = allocateArray(getPrimitiveArrayInfo(BYTE), - Type::SByteTy, + Value* arrayRef = allocateArray(resolver_->getClass("[B"), getPrimitiveArrayVTableInfo(BYTE), count, ip); @@ -231,7 +191,7 @@ // Get class information for java/lang/String. const ClassFile* cf = ClassFile::get("java/lang/String"); - const ClassInfo& ci = getClassInfo(cf); + const Class& ci = resolver_->getClass("java/lang/String"); const VTableInfo& vi = getVTableInfo(cf); // Create a new java/lang/String object. @@ -244,8 +204,8 @@ params.reserve(3); params.clear(); - params.push_back(new CastInst(objRef, ObjectBaseRefTy, TMP, ip)); - params.push_back(new CastInst(arrayRef, ObjectBaseRefTy, TMP, ip)); + params.push_back(new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, ip)); + params.push_back(new CastInst(arrayRef, resolver_->getObjectBaseRefType(), TMP, ip)); params.push_back(ConstantSInt::get(Type::IntTy, 0)); new CallInst(function, params, "", ip); @@ -257,13 +217,12 @@ StringMap::iterator it = stringMap_.find(str); if (it == stringMap_.end()) { // Create the global variable for the string. - const Type* StringRefTy = PointerType::get( - getClassInfo(ClassFile::get("java/lang/String")).getType()); + const Class& stringClass = resolver_->getClass("java/lang/String"); GlobalVariable* stringGlobal = new GlobalVariable( - StringRefTy, + stringClass.getType(), false, GlobalVariable::ExternalLinkage, - llvm::Constant::getNullValue(StringRefTy), + llvm::Constant::getNullValue(stringClass.getType()), str + ".java/lang/String", &module_); @@ -304,76 +263,13 @@ return 0; // not reached } - /// Given a JType returns the appropriate llvm::Type. - Type* getType(JType type) { - switch (type) { - case BOOLEAN: return Type::BoolTy; - case CHAR: return Type::UShortTy; - case FLOAT: return Type::FloatTy; - case DOUBLE: return Type::DoubleTy; - case BYTE: return Type::SByteTy; - case SHORT: return Type::ShortTy; - case INT: return Type::IntTy; - case LONG: return Type::LongTy; - default: assert(0 && "Invalid JType to Type conversion!"); - } - - return NULL; - } - - /// Returns the type of the Java string descriptor. If the - /// Type* self is not NULL then that type is used as the first - /// type in function types - Type* getType(ConstantUtf8* descr, Type* self = NULL) { - unsigned i = 0; - return getTypeHelper(descr->str(), i, self); - } - - Type* getTypeHelper(const std::string& descr, unsigned& i, Type* self) { - assert(i < descr.size()); - switch (descr[i++]) { - case 'B': return Type::SByteTy; - case 'C': return Type::UShortTy; - case 'D': return Type::DoubleTy; - case 'F': return Type::FloatTy; - case 'I': return Type::IntTy; - case 'J': return Type::LongTy; - case 'S': return Type::ShortTy; - case 'Z': return Type::BoolTy; - case 'V': return Type::VoidTy; - case 'L': { - unsigned e = descr.find(';', i); - i = e + 1; - return ObjectBaseRefTy; - } - case '[': - // Skip '['s. - if (descr[i] == '[') - do { ++i; } while (descr[i] == '['); - // Consume the element type - getTypeHelper(descr, i, NULL); - return ObjectBaseRefTy; - case '(': { - std::vector params; - if (self) - params.push_back(PointerType::get(self)); - while (descr[i] != ')') - params.push_back(getTypeHelper(descr, i, NULL)); - return FunctionType::get(getTypeHelper(descr, ++i, NULL),params, false); - } - // FIXME: Throw something - default: assert(0 && "Cannot parse type descriptor!"); - } - return 0; // not reached - } - /// Returns the type of the Java string descriptor for JNI. - Type* getJNIType(ConstantUtf8* descr) { + const Type* getJNIType(ConstantUtf8* descr) { unsigned i = 0; return getJNITypeHelper(descr->str(), i); } - Type* getJNITypeHelper(const std::string& descr, unsigned& i) { + const Type* getJNITypeHelper(const std::string& descr, unsigned& i) { assert(i < descr.size()); switch (descr[i++]) { case 'B': return Type::SByteTy; @@ -389,20 +285,20 @@ case 'L': { unsigned e = descr.find(';', i); i = e + 1; - return ObjectBaseRefTy; + return resolver_->getObjectBaseRefType(); } case '[': // Skip '['s. if (descr[i] == '[') do { ++i; } while (descr[i] == '['); // Consume the element type - getTypeHelper(descr, i, NULL); - return ObjectBaseRefTy; + getJNITypeHelper(descr, i); + return resolver_->getObjectBaseRefType(); case '(': { std::vector params; // JNIEnv* params.push_back(JNIEnvPtr_->getType()); - params.push_back(ObjectBaseRefTy); + params.push_back(resolver_->getObjectBaseRefType()); while (descr[i] != ')') params.push_back(getJNITypeHelper(descr, i)); return FunctionType::get(getJNITypeHelper(descr, ++i), params, false); @@ -413,42 +309,6 @@ return 0; // not reached } - /// Initializes the class info map; in other words it adds the - /// class info of java.lang.Object. - bool initializeClassInfoMap() { - DEBUG(std::cerr << "Building ClassInfo for: java/lang/Object\n"); - const ClassFile* cf = ClassFile::get("java/lang/Object"); - ClassInfo& ci = c2ciMap_[cf]; - - module_.addTypeName(LLVM_JAVA_OBJECT_BASE, ObjectBaseTy); - - assert(isa(ci.getType()) && - "java/lang/Object ClassInfo should not be initialized!"); - - // Because this is java/lang/Object, we add the opaque - // llvm_java_object_base type first. - ci.addField(LLVM_JAVA_OBJECT_BASE, ObjectBaseTy); - - const Fields& fields = cf->getFields(); - for (unsigned i = 0, e = fields.size(); i != e; ++i) { - Field* field = fields[i]; - if (!field->isStatic()) - ci.addField(field->getName()->str(), getType(field->getDescriptor())); - } - - ci.resolveType(); - - DEBUG(std::cerr << "Adding java/lang/Object = " - << *ci.getType() << " to type map\n"); - module_.addTypeName("java/lang/Object", ci.getType()); - - assert(!isa(ci.getType()) && - "ClassInfo not initialized properly!"); - emitStaticInitializers(cf); - DEBUG(std::cerr << "Built ClassInfo for: java/lang/Object\n"); - return true; - } - /// Initializes the VTableInfo map; in other words it adds the /// VTableInfo for java.lang.Object. bool initializeVTableInfoMap() { @@ -502,7 +362,7 @@ const Methods& methods = cf->getMethods(); - const ClassInfo& ci = getClassInfo(cf); + const Class& ci = resolver_->getClass("java/lang/Object"); // Add member functions to the vtable. for (unsigned i = 0, e = methods.size(); i != e; ++i) { @@ -518,7 +378,7 @@ std::string funcName = "java/lang/Object/" + methodDescr; const FunctionType* funcTy = cast( - getType(method->getDescriptor(), ObjectBaseTy)); + resolver_->getType(method->getDescriptor()->str(), true)); Function* vfun = module_.getOrInsertFunction(funcName, funcTy); scheduleFunction(vfun); @@ -549,128 +409,6 @@ return true; } - /// Returns the ClassInfo object associated with this classfile. - const ClassInfo& getClassInfo(const ClassFile* cf) { - static bool initialized = initializeClassInfoMap(); - - Class2ClassInfoMap::iterator it = c2ciMap_.lower_bound(cf); - if (it != c2ciMap_.end() && it->first == cf) - return it->second; - - const std::string& className = cf->getThisClass()->getName()->str(); - DEBUG(std::cerr << "Building ClassInfo for: " << className << '\n'); - ClassInfo& ci = c2ciMap_[cf]; - - assert(isa(ci.getType()) && - "got already initialized ClassInfo!"); - - // Get the interface id. - if (cf->isInterface()) - ci.setNextInterfaceIndex(); - - ConstantClass* super = cf->getSuperClass(); - assert(super && "Class does not have superclass!"); - const ClassInfo& superCI = - getClassInfo(ClassFile::get(super->getName()->str())); - ci.addField("super", superCI.getType()); - - const Fields& fields = cf->getFields(); - for (unsigned i = 0, e = fields.size(); i != e; ++i) { - Field* field = fields[i]; - if (!field->isStatic()) - ci.addField(field->getName()->str(), getType(field->getDescriptor())); - } - - ci.resolveType(); - - assert(!isa(ci.getType()) && - "ClassInfo not initialized properly!"); - DEBUG(std::cerr << "Adding " << className << " = " - << *ci.getType() << " to type map\n"); - module_.addTypeName(className, ci.getType()); - emitStaticInitializers(cf); - DEBUG(std::cerr << "Built ClassInfo for: " << className << '\n'); - return ci; - } - - /// Creates a ClassInfo object for an array of the specified - /// element type. - ClassInfo buildArrayClassInfo(Type* elementTy) { - ClassInfo arrayInfo; - - arrayInfo.addField("super", ObjectBaseTy); - arrayInfo.addField("", Type::UIntTy); - arrayInfo.addField("", ArrayType::get(elementTy, 0)); - - arrayInfo.resolveType(); - - return arrayInfo; - } - - const ClassInfo& getArrayInfo(const Type* type) { - if (Type::BoolTy == type) return getPrimitiveArrayInfo(BOOLEAN); - else if (Type::UShortTy == type) return getPrimitiveArrayInfo(CHAR); - else if (Type::FloatTy == type) return getPrimitiveArrayInfo(FLOAT); - else if (Type::DoubleTy == type) return getPrimitiveArrayInfo(DOUBLE); - else if (Type::SByteTy == type) return getPrimitiveArrayInfo(BYTE); - else if (Type::ShortTy == type) return getPrimitiveArrayInfo(SHORT); - else if (Type::IntTy == type) return getPrimitiveArrayInfo(INT); - else if (Type::LongTy == type) return getPrimitiveArrayInfo(LONG); - else if (ObjectBaseRefTy == type) return getObjectArrayInfo(); - else abort(); - } - - /// Returns the ClassInfo object associated with an array of the - /// specified element type. - const ClassInfo& getPrimitiveArrayInfo(JType type) { - switch (type) { - case BOOLEAN: { - // Because baload/bastore is used to load/store to both byte - // arrays and boolean arrays we use sbyte for java boolean - // arrays as well. - static ClassInfo arrayInfo = buildArrayClassInfo(Type::SByteTy); - return arrayInfo; - } - case CHAR: { - static ClassInfo arrayInfo = buildArrayClassInfo(Type::UShortTy); - return arrayInfo; - } - case FLOAT: { - static ClassInfo arrayInfo = buildArrayClassInfo(Type::FloatTy); - return arrayInfo; - } - case DOUBLE: { - static ClassInfo arrayInfo = buildArrayClassInfo(Type::DoubleTy); - return arrayInfo; - } - case BYTE: { - static ClassInfo arrayInfo = buildArrayClassInfo(Type::SByteTy); - return arrayInfo; - } - case SHORT: { - static ClassInfo arrayInfo = buildArrayClassInfo(Type::ShortTy); - return arrayInfo; - } - case INT: { - static ClassInfo arrayInfo = buildArrayClassInfo(Type::IntTy); - return arrayInfo; - } - case LONG: { - static ClassInfo arrayInfo = buildArrayClassInfo(Type::LongTy); - return arrayInfo; - } - } - abort(); - } - - /// Returns the ClassInfo object associated with an array of the - /// specified element type. - const ClassInfo& getObjectArrayInfo() { - static ClassInfo arrayInfo = - buildArrayClassInfo(ObjectBaseRefTy); - return arrayInfo; - } - /// Builds the super classes' vtable array for this classfile and /// its corresponding VTable. The most generic class goes first in /// the array. @@ -756,22 +494,23 @@ void insertVtablesForInterface(std::vector& vtables, const ClassFile* cf, - const ClassFile* ifaceCf) { + const ClassFile* interfaceCf) { static llvm::Constant* nullVTable = llvm::Constant::getNullValue(PointerType::get(VTableInfo::VTableTy)); - assert(ifaceCf->isInterface() && "Classfile must be an interface!"); - const ClassInfo& ifaceCi = getClassInfo(ifaceCf); - if (ifaceCi.getInterfaceIndex() >= vtables.size()) - vtables.resize(ifaceCi.getInterfaceIndex()+1, nullVTable); + assert(interfaceCf->isInterface() && "Classfile must be an interface!"); + const Class& interface = resolver_->getClass(interfaceCf->getThisClass()->getName()->str()); + unsigned index = interface.getInterfaceIndex(); + if (index >= vtables.size()) + vtables.resize(index+1, nullVTable); // Add this interface's vtable if it was not added before. - if (vtables[ifaceCi.getInterfaceIndex()] == nullVTable) { - vtables[ifaceCi.getInterfaceIndex()] = buildInterfaceVTable(cf, ifaceCf); - const Classes& interfaces = ifaceCf->getInterfaces(); + if (vtables[index] == nullVTable) { + vtables[index] = buildInterfaceVTable(cf, interfaceCf); + const Classes& interfaces = interfaceCf->getInterfaces(); for (unsigned i = 0, e = interfaces.size(); i != e; ++i) { - const ClassFile* otherCf = + const ClassFile* superInterface = ClassFile::get(interfaces[i]->getName()->str()); - insertVtablesForInterface(vtables, cf, otherCf); + insertVtablesForInterface(vtables, cf, superInterface); } } } @@ -787,7 +526,7 @@ // value. if (cf->isInterface()) return std::make_pair( - getClassInfo(cf).getInterfaceIndex(), + resolver_->getClass(cf->getThisClass()->getName()->str()).getInterfaceIndex(), ConstantExpr::getCast( ConstantIntegral::getAllOnesValue(Type::LongTy), PointerType::get(PointerType::get(VTableInfo::VTableTy)))); @@ -949,7 +688,7 @@ std::string funcName = className + '/' + methodDescr; const FunctionType* funcTy = cast( - getType(method->getDescriptor(), ObjectBaseTy)); + resolver_->getType(method->getDescriptor()->str(), true)); llvm::Constant* vfun = NULL; if (cf->isInterface() || method->isAbstract()) vfun = llvm::Constant::getNullValue(PointerType::get(funcTy)); @@ -1164,7 +903,7 @@ PointerType::get(PointerType::get(VTableInfo::VTableTy)))); // the element size init.push_back(ConstantExpr::getCast( - ConstantExpr::getSizeOf(ObjectBaseRefTy), Type::IntTy)); + ConstantExpr::getSizeOf(resolver_->getObjectBaseRefType()), Type::IntTy)); llvm::Constant* typeInfoInit = ConstantStruct::get(VTableInfo::TypeInfoTy, init); @@ -1283,7 +1022,7 @@ // the element size typeInfoInit.push_back( ConstantExpr::getCast( - ConstantExpr::getSizeOf(ObjectBaseRefTy), Type::IntTy)); + ConstantExpr::getSizeOf(resolver_->getObjectBaseRefType()), Type::IntTy)); init[0] = ConstantStruct::get(VTableInfo::TypeInfoTy, typeInfoInit); vi.vtable->setInitializer(ConstantStruct::get(init)); @@ -1303,7 +1042,7 @@ GlobalVariable* global = getStaticField(ClassFile::get(className), nameAndType->getName()->str(), - getType(nameAndType->getDescriptor())); + resolver_->getType(nameAndType->getDescriptor()->str())); assert(global && "Cannot find global for static field!"); @@ -1348,27 +1087,28 @@ Value* getField(unsigned index, Value* ptr) { ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); - const ClassFile* cf = - ClassFile::get(fieldRef->getClass()->getName()->str()); - return getField(cf, nameAndType->getName()->str(), ptr); + return getField(fieldRef->getClass()->getName()->str(), + nameAndType->getName()->str(), + ptr); } /// Emits the necessary code to get a field from the passed /// pointer to an object. - Value* getField(const ClassFile* cf, + Value* getField(std::string className, const std::string& fieldName, Value* ptr) { // Cast ptr to correct type. - ptr = new CastInst(ptr, PointerType::get(getClassInfo(cf).getType()), + ptr = new CastInst(ptr, resolver_->getClass(className).getType(), TMP, currentBB_); // Deref pointer. std::vector indices(1, ConstantUInt::get(Type::UIntTy, 0)); while (true) { - const ClassInfo& info = getClassInfo(cf); - int slot = info.getFieldIndex(fieldName); + const Class& clazz = resolver_->getClass(className); + int slot = clazz.getFieldIndex(fieldName); if (slot == -1) { - cf = ClassFile::get(cf->getSuperClass()->getName()->str()); + className = + ClassFile::get(className)->getSuperClass()->getName()->str(); indices.push_back(ConstantUInt::get(Type::UIntTy, 0)); } else { @@ -1413,7 +1153,7 @@ if (method->isNative()) { DEBUG(std::cerr << "Adding stub for natively implemented method: " << classMethodDesc << '\n'); - FunctionType* jniFuncTy = + const FunctionType* jniFuncTy = cast(getJNIType(method->getDescriptor())); std::string funcName = @@ -1435,7 +1175,7 @@ std::vector params; params.push_back(JNIEnvPtr_); if (method->isStatic()) - params.push_back(llvm::Constant::getNullValue(ObjectBaseRefTy)); + params.push_back(llvm::Constant::getNullValue(resolver_->getObjectBaseRefType())); for (Function::arg_iterator A = function->arg_begin(), E = function->arg_end(); A != E; ++A) { params.push_back( @@ -1491,13 +1231,13 @@ bbBuilder_.reset(new BasicBlockBuilder(function, codeAttr)); // Put arguments into locals. - locals_ = Locals(codeAttr->getMaxLocals()); + locals_ = Locals(*resolver_, codeAttr->getMaxLocals()); unsigned index = 0; for (Function::arg_iterator a = function->arg_begin(), ae = function->arg_end(); a != ae; ++a) { locals_.store(index, a, &function->getEntryBlock()); - index += isTwoSlotType(a->getType()) ? 2 : 1; + index += resolver_->isTwoSlotType(a->getType()) ? 2 : 1; } BasicBlock* bb0 = bbBuilder_->getBasicBlock(0); @@ -1508,7 +1248,7 @@ // NOTE: We create an operand stack one size too big because we // push extra values on the stack to simplify code generation // (see implementation of ifne). - opStack_ = OperandStack(codeAttr->getMaxStack()+2); + opStack_ = OperandStack(*resolver_, codeAttr->getMaxStack()+2); opStackDepthMap_.insert(std::make_pair(bb0, 0)); // Insert bb0 in the work list. @@ -1583,12 +1323,17 @@ static ClassFileSet toInitClasses; if (toInitClasses.insert(classfile)) { + // If this class has a super class, initialize that first. + if (classfile->getSuperClass()) + emitStaticInitializers( + ClassFile::get(classfile->getSuperClass()->getName()->str())); + // Create the global variables of this class. const Fields& fields = classfile->getFields(); for (unsigned i = 0, e = fields.size(); i != e; ++i) { Field* field = fields[i]; if (field->isStatic()) { - Type* globalTy = getType(field->getDescriptor()); + const Type* globalTy = resolver_->getType(field->getDescriptor()->str()); // A java field can be final/constant even if it has a // dynamic initializer. Because LLVM does not currently // support these semantics, we consider constants only @@ -1645,9 +1390,9 @@ Function* getFunction(Method* method) { const ClassFile* clazz = method->getParent(); - FunctionType* funcTy = cast( - getType(method->getDescriptor(), - method->isStatic() ? NULL : ObjectBaseTy)); + const FunctionType* funcTy = cast( + resolver_->getType(method->getDescriptor()->str(), + !method->isStatic())); std::string funcName = clazz->getThisClass()->getName()->str() + '/' + method->getName()->str() + method->getDescriptor()->str(); @@ -1716,7 +1461,7 @@ } void do_aconst_null() { - push(llvm::Constant::getNullValue(ObjectBaseRefTy)); + push(llvm::Constant::getNullValue(resolver_->getObjectBaseRefType())); } void do_iconst(int value) { @@ -1749,27 +1494,27 @@ void do_lload(unsigned index) { do_load_common(index, Type::LongTy); } void do_fload(unsigned index) { do_load_common(index, Type::FloatTy); } void do_dload(unsigned index) { do_load_common(index, Type::DoubleTy); } - void do_aload(unsigned index) { do_load_common(index, ObjectBaseRefTy); } + void do_aload(unsigned index) { do_load_common(index, resolver_->getObjectBaseRefType()); } - void do_load_common(unsigned index, Type* type) { + void do_load_common(unsigned index, const Type* type) { Value* val = locals_.load(index, type, currentBB_); push(val); } - void do_iaload() { do_aload_common(Type::IntTy); } - void do_laload() { do_aload_common(Type::LongTy); } - void do_faload() { do_aload_common(Type::FloatTy); } - void do_daload() { do_aload_common(Type::DoubleTy); } - void do_aaload() { do_aload_common(ObjectBaseRefTy); } - void do_baload() { do_aload_common(Type::SByteTy); } - void do_caload() { do_aload_common(Type::UShortTy); } - void do_saload() { do_aload_common(Type::ShortTy); } - - void do_aload_common(const Type* elementTy) { + void do_iaload() { do_aload_common("[I"); } + void do_laload() { do_aload_common("[J"); } + void do_faload() { do_aload_common("[F"); } + void do_daload() { do_aload_common("[D"); } + void do_aaload() { do_aload_common("[Ljava/lang/Object;"); } + void do_baload() { do_aload_common("[B"); } + void do_caload() { do_aload_common("[C"); } + void do_saload() { do_aload_common("[S"); } + + void do_aload_common(const std::string& className) { + const Class& arrayClass = resolver_->getClass(className); + assert(arrayClass.isArray() && "Not an array class!"); Value* index = pop(Type::IntTy); - const Type* arrayTy = getArrayInfo(elementTy).getType(); - const Type* arrayRefTy = PointerType::get(arrayTy); - Value* arrayRef = pop(arrayRefTy); + Value* arrayRef = pop(arrayClass.getType()); std::vector indices; indices.reserve(3); @@ -1786,28 +1531,29 @@ void do_lstore(unsigned index) { do_store_common(index, Type::LongTy); } void do_fstore(unsigned index) { do_store_common(index, Type::FloatTy); } void do_dstore(unsigned index) { do_store_common(index, Type::DoubleTy); } - void do_astore(unsigned index) { do_store_common(index, ObjectBaseRefTy); } + void do_astore(unsigned index) { do_store_common(index, resolver_->getObjectBaseRefType()); } void do_store_common(unsigned index, const Type* type) { Value* val = pop(type); locals_.store(index, val, currentBB_); } - void do_iastore() { do_astore_common(Type::IntTy); } - void do_lastore() { do_astore_common(Type::LongTy); } - void do_fastore() { do_astore_common(Type::FloatTy); } - void do_dastore() { do_astore_common(Type::DoubleTy); } - void do_aastore() { do_astore_common(ObjectBaseRefTy); } - void do_bastore() { do_astore_common(Type::SByteTy); } - void do_castore() { do_astore_common(Type::UShortTy); } - void do_sastore() { do_astore_common(Type::ShortTy); } - - void do_astore_common(const Type* elementTy) { - Value* value = pop(elementTy); + void do_iastore() { do_astore_common("[I"); } + void do_lastore() { do_astore_common("[J"); } + void do_fastore() { do_astore_common("[F"); } + void do_dastore() { do_astore_common("[D"); } + void do_aastore() { do_astore_common("[Ljava/lang/Object;"); } + void do_bastore() { do_astore_common("[B"); } + void do_castore() { do_astore_common("[C"); } + void do_sastore() { do_astore_common("[S"); } + + void do_astore_common(const std::string& className) { + const Class& arrayClass = resolver_->getClass(className); + assert(arrayClass.isArray() && "Not an array class!"); + const Class& componentClass = *arrayClass.getComponentClass(); + Value* value = pop(componentClass.getType()); Value* index = pop(Type::IntTy); - const Type* arrayTy = getArrayInfo(elementTy).getType(); - const Type* arrayRefTy = PointerType::get(arrayTy); - Value* arrayRef = pop(arrayRefTy); + Value* arrayRef = pop(arrayClass.getType()); std::vector indices; indices.reserve(3); @@ -2025,18 +1771,18 @@ do_if_common(Instruction::SetLE, Type::IntTy, t, f); } void do_if_acmpeq(unsigned t, unsigned f) { - do_if_common(Instruction::SetEQ, ObjectBaseRefTy, t, f); + do_if_common(Instruction::SetEQ, resolver_->getObjectBaseRefType(), t, f); } void do_if_acmpne(unsigned t, unsigned f) { - do_if_common(Instruction::SetNE, ObjectBaseRefTy, t, f); + do_if_common(Instruction::SetNE, resolver_->getObjectBaseRefType(), t, f); } void do_ifnull(unsigned t, unsigned f) { do_aconst_null(); - do_if_common(Instruction::SetEQ, ObjectBaseRefTy, t, f); + do_if_common(Instruction::SetEQ, resolver_->getObjectBaseRefType(), t, f); } void do_ifnonnull(unsigned t, unsigned f) { do_aconst_null(); - do_if_common(Instruction::SetNE, ObjectBaseRefTy, t, f); + do_if_common(Instruction::SetNE, resolver_->getObjectBaseRefType(), t, f); } void do_if_common(Instruction::BinaryOps cc, const Type* type, @@ -2057,7 +1803,7 @@ void do_lreturn() { do_return_common(Type::LongTy); } void do_freturn() { do_return_common(Type::FloatTy); } void do_dreturn() { do_return_common(Type::DoubleTy); } - void do_areturn() { do_return_common(ObjectBaseRefTy); } + void do_areturn() { do_return_common(resolver_->getObjectBaseRefType()); } void do_return_common(const Type* type) { Value* r = pop(type); @@ -2111,16 +1857,17 @@ void do_getfield(unsigned index) { ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); const std::string& name = fieldRef->getNameAndType()->getName()->str(); - Value* p = pop(ObjectBaseRefTy); + Value* p = pop(resolver_->getObjectBaseRefType()); Value* v = new LoadInst(getField(index, p), name, currentBB_); push(v); } void do_putfield(unsigned index) { ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); - const Type* type = getType(fieldRef->getNameAndType()->getDescriptor()); + const Type* type = + resolver_->getType(fieldRef->getNameAndType()->getDescriptor()->str()); Value* v = pop(type); - Value* p = pop(ObjectBaseRefTy); + Value* p = pop(resolver_->getObjectBaseRefType()); Value* fp = getField(index, p); const Type* ft = cast(fp->getType())->getElementType(); v = new CastInst(v, ft, TMP, currentBB_); @@ -2149,58 +1896,45 @@ return params; } - std::pair - getInfo(const std::string& className) { - const ClassInfo* ci = NULL; + const VTableInfo* getVTableInfoGeneric(const std::string& className) { const VTableInfo* vi = NULL; if (className[0] == '[') { - if (className[1] == '[' || className[1] == 'L') { + if (className[1] == '[' || className[1] == 'L') vi = &getObjectArrayVTableInfo(ClassFile::get("java/lang/Object")); - ci = &getObjectArrayInfo(); - } else switch (className[1]) { case 'B': vi = &getPrimitiveArrayVTableInfo(Type::SByteTy); - ci = &getArrayInfo(Type::SByteTy); break; case 'C': vi = &getPrimitiveArrayVTableInfo(Type::UShortTy); - ci = &getArrayInfo(Type::UShortTy); break; case 'D': vi = &getPrimitiveArrayVTableInfo(Type::DoubleTy); - ci = &getArrayInfo(Type::DoubleTy); break; case 'F': vi = &getPrimitiveArrayVTableInfo(Type::FloatTy); - ci = &getArrayInfo(Type::FloatTy); break; case 'I': vi = &getPrimitiveArrayVTableInfo(Type::IntTy); - ci = &getArrayInfo(Type::IntTy); break; case 'J': vi = &getPrimitiveArrayVTableInfo(Type::LongTy); - ci = &getArrayInfo(Type::LongTy); break; case 'S': vi = &getPrimitiveArrayVTableInfo(Type::ShortTy); - ci = &getArrayInfo(Type::ShortTy); break; case 'Z': vi = &getPrimitiveArrayVTableInfo(Type::BoolTy); - ci = &getArrayInfo(Type::BoolTy); break; } } else { const ClassFile* cf = ClassFile::get(className); vi = &getVTableInfo(cf); - ci = &getClassInfo(cf); } - return std::make_pair(ci, vi); + return vi; } void do_invokevirtual(unsigned index) { @@ -2209,25 +1943,22 @@ const std::string& className = methodRef->getClass()->getName()->str(); - const ClassInfo* ci = NULL; - const VTableInfo* vi = NULL; - tie(ci, vi) = getInfo(className); + const Class* ci = &resolver_->getClass(className); + const VTableInfo* vi = getVTableInfoGeneric(className); const std::string& methodDescr = nameAndType->getName()->str() + nameAndType->getDescriptor()->str(); - FunctionType* funTy = - cast(getType(nameAndType->getDescriptor(), - ObjectBaseTy)); + const FunctionType* funTy = cast( + resolver_->getType(nameAndType->getDescriptor()->str(), true)); std::vector params(getParams(funTy)); Value* objRef = params.front(); - objRef = new CastInst(objRef, PointerType::get(ci->getType()), - "this", currentBB_); + objRef = new CastInst(objRef, ci->getType(), "this", currentBB_); Value* objBase = - new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); + new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, currentBB_); Value* vtable = new CallInst(getVtable_, objBase, TMP, currentBB_); vtable = new CastInst(vtable, vi->vtable->getType(), className + ".vtable", currentBB_); @@ -2253,18 +1984,20 @@ const std::string& methodDescr = methodName + nameAndType->getDescriptor()->str(); std::string funcName = className + '/' + methodDescr; - const ClassInfo& ci = getClassInfo(ClassFile::get(className)); + const Class& ci = resolver_->getClass(className); - FunctionType* funcTy = - cast(getType(nameAndType->getDescriptor(), - ObjectBaseTy)); + const FunctionType* funcTy = cast( + resolver_->getType(nameAndType->getDescriptor()->str(), true)); Function* function = module_.getOrInsertFunction(funcName, funcTy); scheduleFunction(function); makeCall(function, getParams(funcTy)); } void do_invokestatic(unsigned index) { - Method* method = getMethod(cf_->getConstantMethodRef(index)); + ConstantMethodRef* methodRef = cf_->getConstantMethodRef(index); + emitStaticInitializers( + ClassFile::get(methodRef->getClass()->getName()->str())); + Method* method = getMethod(methodRef); Function* function = getFunction(method); // Intercept java/lang/System/loadLibrary() calls and add // library deps to the module @@ -2289,25 +2022,22 @@ const std::string& className = methodRef->getClass()->getName()->str(); - const ClassInfo* ci = NULL; - const VTableInfo* vi = NULL; - tie(ci, vi) = getInfo(className); + const Class* ci = &resolver_->getClass(className); + const VTableInfo* vi = getVTableInfoGeneric(className); const std::string& methodDescr = nameAndType->getName()->str() + nameAndType->getDescriptor()->str(); - FunctionType* funTy = - cast(getType(nameAndType->getDescriptor(), - ObjectBaseTy)); + const FunctionType* funTy = cast( + resolver_->getType(nameAndType->getDescriptor()->str(), true)); std::vector params(getParams(funTy)); Value* objRef = params.front(); - objRef = new CastInst(objRef, PointerType::get(ci->getType()), - "this", currentBB_); + objRef = new CastInst(objRef, ci->getType(), "this", currentBB_); Value* objBase = - new CastInst(objRef, ObjectBaseRefTy, TMP, currentBB_); + new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, currentBB_); Value* vtable = new CallInst(getVtable_, objBase, TMP, currentBB_); vtable = new CastInst(vtable, PointerType::get(VTableInfo::VTableTy), TMP, currentBB_); @@ -2342,21 +2072,21 @@ } template - Value* allocateObject(const ClassInfo& ci, + Value* allocateObject(const Class& clazz, const VTableInfo& vi, InsertionPointTy* ip) { static std::vector params(4); - Value* objRef = new MallocInst(ci.getType(), NULL, TMP, ip); + Value* objRef = new MallocInst(clazz.getStructType(), NULL, TMP, ip); params[0] = new CastInst(objRef, PointerType::get(Type::SByteTy), TMP, ip); // dest params[1] = ConstantUInt::get(Type::UByteTy, 0); // value - params[2] = ConstantExpr::getSizeOf(ci.getType()); // size + params[2] = ConstantExpr::getSizeOf(clazz.getStructType()); // size params[3] = ConstantUInt::get(Type::UIntTy, 0); // alignment new CallInst(memset_, params, "", ip); // Install the vtable pointer. - Value* objBase = new CastInst(objRef, ObjectBaseRefTy, TMP, ip); + Value* objBase = new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, ip); Value* vtable = new CastInst(vi.vtable, VTableBaseRefTy, TMP, ip); new CallInst(setVtable_, objBase, vtable, "", ip); @@ -2366,7 +2096,8 @@ void do_new(unsigned index) { ConstantClass* classRef = cf_->getConstantClass(index); const ClassFile* cf = ClassFile::get(classRef->getName()->str()); - const ClassInfo& ci = getClassInfo(cf); + emitStaticInitializers(cf); + const Class& ci = resolver_->getClass(classRef->getName()->str()); const VTableInfo& vi = getVTableInfo(cf); push(allocateObject(ci, vi, currentBB_)); @@ -2393,13 +2124,16 @@ } template - Value* allocateArray(const ClassInfo& ci, - const Type* elementTy, + Value* allocateArray(const Class& clazz, const VTableInfo& vi, Value* count, InsertionPointTy* ip) { static std::vector params(4); + assert(clazz.isArray() && "Not an array class!"); + const Class& componentClass = *clazz.getComponentClass(); + const Type* elementTy = componentClass.getType(); + // The size of the element. llvm::Constant* elementSize = ConstantExpr::getCast(ConstantExpr::getSizeOf(elementTy), Type::UIntTy); @@ -2409,7 +2143,7 @@ Instruction::Mul, count, elementSize, TMP, ip); // The size of the rest of the array object. llvm::Constant* arrayObjectSize = - ConstantExpr::getCast(ConstantExpr::getSizeOf(ci.getType()), + ConstantExpr::getCast(ConstantExpr::getSizeOf(clazz.getStructType()), Type::UIntTy); // Add the array part plus the object part together. @@ -2424,14 +2158,14 @@ new CallInst(memset_, params, "", ip); // Cast back to array type. - objRef = new CastInst(objRef, PointerType::get(ci.getType()), TMP, ip); + objRef = new CastInst(objRef, clazz.getType(), TMP, ip); // Store the size. Value* lengthPtr = getArrayLengthPtr(objRef, ip); new StoreInst(count, lengthPtr, ip); // Install the vtable pointer. - Value* objBase = new CastInst(objRef, ObjectBaseRefTy, TMP, ip); + Value* objBase = new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, ip); Value* vtable = new CastInst(vi.vtable, VTableBaseRefTy, TMP, ip); new CallInst(setVtable_, objBase, vtable, "", ip); @@ -2441,35 +2175,35 @@ void do_newarray(JType type) { Value* count = pop(Type::UIntTy); - const ClassInfo& ci = getPrimitiveArrayInfo(type); + const Class& clazz = resolver_->getArrayClass(type); const VTableInfo& vi = getPrimitiveArrayVTableInfo(type); - push(allocateArray(ci, getType(type), vi, count, currentBB_)); + push(allocateArray(clazz, vi, count, currentBB_)); } void do_anewarray(unsigned index) { Value* count = pop(Type::UIntTy); - const ClassInfo& ci = getObjectArrayInfo(); // FIXME: Need to do handle different element types. This now // assumes that all arrays of references are arrays of // java/lang/Object's. + const Class& clazz = resolver_->getClass("[Ljava/lang/Object;"); const VTableInfo& vi = getObjectArrayVTableInfo(ClassFile::get("java/lang/Object")); - push(allocateArray(ci, ObjectBaseRefTy, vi, count, currentBB_)); + push(allocateArray(clazz, vi, count, currentBB_)); } void do_arraylength() { - const ClassInfo& ci = getObjectArrayInfo(); - Value* arrayRef = pop(PointerType::get(ci.getType())); + const Class& clazz = resolver_->getClass("[Ljava/lang/Object;"); + Value* arrayRef = pop(clazz.getType()); Value* lengthPtr = getArrayLengthPtr(arrayRef, currentBB_); Value* length = new LoadInst(lengthPtr, TMP, currentBB_); push(length); } void do_athrow() { - Value* objRef = pop(ObjectBaseRefTy); + Value* objRef = pop(resolver_->getObjectBaseRefType()); new CallInst(throw_, objRef, "", currentBB_); new UnreachableInst(currentBB_); } @@ -2477,11 +2211,10 @@ void do_checkcast(unsigned index) { ConstantClass* classRef = cf_->getConstantClass(index); - const ClassInfo* ci = NULL; - const VTableInfo* vi = NULL; - tie(ci, vi) = getInfo(classRef->getName()->str()); + const Class* ci = &resolver_->getClass(classRef->getName()->str()); + const VTableInfo* vi = getVTableInfoGeneric(classRef->getName()->str()); - Value* objRef = pop(ObjectBaseRefTy); + Value* objRef = pop(resolver_->getObjectBaseRefType()); Value* vtable = new CastInst(vi->vtable, VTableBaseRefTy, TMP, currentBB_); @@ -2497,11 +2230,10 @@ void do_instanceof(unsigned index) { ConstantClass* classRef = cf_->getConstantClass(index); - const ClassInfo* ci = NULL; - const VTableInfo* vi = NULL; - tie(ci, vi) = getInfo(classRef->getName()->str()); + const Class* ci = &resolver_->getClass(classRef->getName()->str()); + const VTableInfo* vi = getVTableInfoGeneric(classRef->getName()->str()); - Value* objRef = pop(ObjectBaseRefTy); + Value* objRef = pop(resolver_->getObjectBaseRefType()); Value* vtable = new CastInst(vi->vtable, VTableBaseRefTy, TMP, currentBB_); Value* r = new CallInst(isInstanceOf_, objRef, vtable, TMP, currentBB_); @@ -2510,12 +2242,12 @@ void do_monitorenter() { // FIXME: This is currently a noop. - pop(ObjectBaseRefTy); + pop(resolver_->getObjectBaseRefType()); } void do_monitorexit() { // FIXME: This is currently a noop. - pop(ObjectBaseRefTy); + pop(resolver_->getObjectBaseRefType()); } void do_multianewarray(unsigned index, unsigned dims) { @@ -2523,7 +2255,6 @@ } }; - unsigned Compiler::ClassInfo::InterfaceCount = 0; StructType* Compiler::VTableInfo::VTableTy; StructType* Compiler::VTableInfo::TypeInfoTy; From lattner at cs.uiuc.edu Wed Mar 23 23:13:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 23:13:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64AsmPrinter.cpp Message-ID: <200503240513.j2O5D5mI027504@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64AsmPrinter.cpp updated: 1.2 -> 1.3 --- Log message: fix a compilation error, patch contributed by Bill Wendling! --- Diffs of the changes: (+1 -0) IA64AsmPrinter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/IA64/IA64AsmPrinter.cpp diff -u llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.2 llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.3 --- llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.2 Sat Mar 19 03:22:17 2005 +++ llvm/lib/Target/IA64/IA64AsmPrinter.cpp Wed Mar 23 23:12:48 2005 @@ -19,6 +19,7 @@ #include "IA64.h" #include "IA64TargetMachine.h" #include "llvm/Module.h" +#include "llvm/Type.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineConstantPool.h" From lattner at cs.uiuc.edu Wed Mar 23 23:14:06 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 23 Mar 2005 23:14:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp Message-ID: <200503240514.j2O5E6OE027705@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/ModuloScheduling: MSchedGraph.cpp updated: 1.14 -> 1.15 --- Log message: Fix compilation errors, patch contributed by the fabulous Bill Wendling! --- Diffs of the changes: (+1 -0) MSchedGraph.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp diff -u llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.14 llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.15 --- llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp:1.14 Tue Mar 22 19:47:20 2005 +++ llvm/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp Wed Mar 23 23:13:53 2005 @@ -20,6 +20,7 @@ #include "../MachineCodeForInstruction.h" #include "llvm/BasicBlock.h" #include "llvm/Instructions.h" +#include "llvm/Type.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Debug.h" From lattner at cs.uiuc.edu Thu Mar 24 00:16:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 00:16:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200503240616.j2O6GV8v002725@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.1 -> 1.2 --- Log message: Fix silly "no newline at end of file" warning --- Diffs of the changes: (+2 -1) PPC32ISelPattern.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.1 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.2 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.1 Wed Mar 23 22:41:43 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Thu Mar 24 00:16:18 2005 @@ -753,4 +753,5 @@ /// FunctionPass *llvm::createPPC32ISelPattern(TargetMachine &TM) { return new ISel(TM); -} \ No newline at end of file +} + From natebegeman at mac.com Thu Mar 24 00:28:53 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 24 Mar 2005 00:28:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp PPC32ISelSimple.cpp PowerPCTargetMachine.cpp Message-ID: <200503240628.AAA13426@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.2 -> 1.3 PPC32ISelSimple.cpp updated: 1.124 -> 1.125 PowerPCTargetMachine.cpp updated: 1.47 -> 1.48 --- Log message: Implement more of the PPC32 Pattern ISel: 1) dynamic stack alloc 2) loads 3) shifts 4) subtract 5) immediate form of add, and, or, xor 6) change flag from -pattern-isel to -enable-ppc-pattern-isel Remove dead arguments from getGlobalBaseReg in the simple ISel --- Diffs of the changes: (+124 -35) PPC32ISelPattern.cpp | 145 ++++++++++++++++++++++++++++++++++++++--------- PPC32ISelSimple.cpp | 10 +-- PowerPCTargetMachine.cpp | 4 - 3 files changed, 124 insertions(+), 35 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.2 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.3 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.2 Thu Mar 24 00:16:18 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Thu Mar 24 00:28:42 2005 @@ -2,7 +2,7 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under +// This file was developed by Nate Begeman and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// @@ -396,6 +396,7 @@ return dyn_cast(Node)->getReg(); case ISD::LOAD: + case ISD::EXTLOAD: abort(); case ISD::ConstantFP: @@ -417,9 +418,6 @@ BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); return Result; - case ISD::EXTLOAD: - abort(); - case ISD::UINT_TO_FP: case ISD::SINT_TO_FP: abort(); @@ -455,7 +453,28 @@ assert(0 && "Node not handled!\n"); case ISD::DYNAMIC_STACKALLOC: - abort(); + // Generate both result values. FIXME: Need a better commment here? + if (Result != 1) + ExprMap[N.getValue(1)] = 1; + else + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + + // FIXME: We are currently ignoring the requested alignment for handling + // greater than the stack alignment. This will need to be revisited at some + // point. Align = N.getOperand(2); + if (!isa(N.getOperand(2)) || + cast(N.getOperand(2))->getValue() != 0) { + std::cerr << "Cannot allocate stack object with greater alignment than" + << " the stack alignment yet!"; + abort(); + } + Select(N.getOperand(0)); + Tmp1 = SelectExpr(N.getOperand(1)); + // Subtract size from stack pointer, thereby allocating some space. + BuildMI(BB, PPC::SUBF, 2, PPC::R1).addReg(Tmp1).addReg(PPC::R1); + // Put a pointer to the space into the result register by copying the SP + BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R1).addReg(PPC::R1); + return Result; case ISD::ConstantPool: abort(); @@ -463,10 +482,50 @@ case ISD::FrameIndex: abort(); + case ISD::LOAD: case ISD::EXTLOAD: case ISD::ZEXTLOAD: + { + // Make sure we generate both values. + if (Result != 1) + ExprMap[N.getValue(1)] = 1; // Generate the token + else + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + + SDOperand Chain = N.getOperand(0); + SDOperand Address = N.getOperand(1); + Select(Chain); + + switch (Node->getValueType(0)) { + default: assert(0 && "Cannot load this type!"); + case MVT::i1: + case MVT::i8: Opc = PPC::LBZ; break; + case MVT::i16: Opc = PPC::LHZ; break; + case MVT::i32: Opc = PPC::LWZ; break; + } + + if (Address.getOpcode() == ISD::GlobalAddress) { // FIXME + BuildMI(BB, Opc, 2, Result) + .addGlobalAddress(cast(Address)->getGlobal()) + .addReg(PPC::R1); + } + else if (ConstantPoolSDNode *CP = dyn_cast(Address)) { + BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CP->getIndex()) + .addReg(PPC::R1); + } + else if(Address.getOpcode() == ISD::FrameIndex) { + BuildMI(BB, Opc, 2, Result) + .addFrameIndex(cast(Address)->getIndex()) + .addReg(PPC::R1); + } else { + int offset; + SelectAddr(Address, Tmp1, offset); + BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1); + } + return Result; + } + case ISD::SEXTLOAD: - case ISD::LOAD: case ISD::GlobalAddress: case ISD::CALL: abort(); @@ -503,11 +562,40 @@ return Result; case ISD::SHL: + Tmp1 = SelectExpr(N.getOperand(0)); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue() & 0x1F; + BuildMI(BB, PPC::RLWINM, 5, Result).addReg(Tmp1).addImm(Tmp2).addImm(0) + .addImm(31-Tmp2); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::SLW, 2, Result).addReg(Tmp1).addReg(Tmp2); + } + return Result; + case ISD::SRL: - case ISD::SRA: - case ISD::MUL: - abort(); + Tmp1 = SelectExpr(N.getOperand(0)); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue() & 0x1F; + BuildMI(BB, PPC::RLWINM, 5, Result).addReg(Tmp1).addImm(32-Tmp2) + .addImm(Tmp2).addImm(31); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::SRW, 2, Result).addReg(Tmp1).addReg(Tmp2); + } + return Result; + case ISD::SRA: + Tmp1 = SelectExpr(N.getOperand(0)); + if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { + Tmp2 = CN->getValue() & 0x1F; + BuildMI(BB, PPC::SRAWI, 2, Result).addReg(Tmp1).addImm(Tmp2); + } else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::SRAW, 2, Result).addReg(Tmp1).addReg(Tmp2); + } + return Result; + case ISD::ADD: assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); Tmp1 = SelectExpr(N.getOperand(0)); @@ -527,7 +615,11 @@ return Result; case ISD::SUB: - abort(); + assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1); + return Result; case ISD::AND: case ISD::OR: @@ -539,31 +631,32 @@ case 0: // No immediate Tmp2 = SelectExpr(N.getOperand(1)); switch (opcode) { - case ISD::AND: Tmp3 = PPC::AND; break; - case ISD::OR: Tmp3 = PPC::OR; break; - case ISD::XOR: Tmp3 = PPC::XOR; break; + case ISD::AND: Opc = PPC::AND; break; + case ISD::OR: Opc = PPC::OR; break; + case ISD::XOR: Opc = PPC::XOR; break; } - BuildMI(BB, Tmp3, 2, Result).addReg(Tmp1).addReg(Tmp2); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); break; case 1: // Low immediate switch (opcode) { - case ISD::AND: Tmp3 = PPC::ANDIo; break; - case ISD::OR: Tmp3 = PPC::ORI; break; - case ISD::XOR: Tmp3 = PPC::XORI; break; + case ISD::AND: Opc = PPC::ANDIo; break; + case ISD::OR: Opc = PPC::ORI; break; + case ISD::XOR: Opc = PPC::XORI; break; } - BuildMI(BB, Tmp3, 2, Result).addReg(Tmp1).addImm(Tmp2); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); break; case 2: // Shifted immediate switch (opcode) { - case ISD::AND: Tmp3 = PPC::ANDISo; break; - case ISD::OR: Tmp3 = PPC::ORIS; break; - case ISD::XOR: Tmp3 = PPC::XORIS; break; + case ISD::AND: Opc = PPC::ANDISo; break; + case ISD::OR: Opc = PPC::ORIS; break; + case ISD::XOR: Opc = PPC::XORIS; break; } - BuildMI(BB, Tmp3, 2, Result).addReg(Tmp1).addImm(Tmp2); + BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); break; } return Result; + case ISD::MUL: case ISD::UREM: case ISD::SREM: case ISD::SDIV: @@ -590,9 +683,9 @@ if (v < 32768 && v >= -32768) { BuildMI(BB, PPC::LI, 1, Result).addSImm(v); } else { - unsigned Temp = MakeReg(MVT::i32); - BuildMI(BB, PPC::LIS, 1, Temp).addSImm(v >> 16); - BuildMI(BB, PPC::ORI, 2, Result).addReg(Temp).addImm(v & 0xFFFF); + Tmp1 = MakeReg(MVT::i32); + BuildMI(BB, PPC::LIS, 1, Tmp1).addSImm(v >> 16); + BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(v & 0xFFFF); } } } @@ -631,7 +724,6 @@ case ISD::BR: { MachineBasicBlock *Dest = cast(N.getOperand(1))->getBasicBlock(); - Select(N.getOperand(0)); BuildMI(BB, PPC::B, 1).addMBB(Dest); return; @@ -687,7 +779,6 @@ } BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction return; - case ISD::TRUNCSTORE: case ISD::STORE: { Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.124 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.125 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.124 Mon Mar 21 13:22:14 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Thu Mar 24 00:28:42 2005 @@ -421,8 +421,7 @@ /// base address to use for accessing globals into a register. Returns the /// register containing the base address. /// - unsigned getGlobalBaseReg(MachineBasicBlock *MBB, - MachineBasicBlock::iterator IP); + unsigned getGlobalBaseReg(); /// copyConstantToRegister - Output the instructions required to put the /// specified constant into the specified register. @@ -590,8 +589,7 @@ /// getGlobalBaseReg - Output the instructions required to put the /// base address to use for accessing globals into a register. /// -unsigned PPC32ISel::getGlobalBaseReg(MachineBasicBlock *MBB, - MachineBasicBlock::iterator IP) { +unsigned PPC32ISel::getGlobalBaseReg() { if (!GlobalBaseInitialized) { // Insert the set of GlobalBaseReg into the first MBB of the function MachineBasicBlock &FirstMBB = F->front(); @@ -690,7 +688,7 @@ unsigned Opcode = (Ty == Type::FloatTy) ? PPC::LFS : PPC::LFD; // Move value at base + distance into return reg BuildMI(*MBB, IP, PPC::LOADHiAddr, 2, Reg1) - .addReg(getGlobalBaseReg(MBB, IP)).addConstantPoolIndex(CPI); + .addReg(getGlobalBaseReg()).addConstantPoolIndex(CPI); BuildMI(*MBB, IP, Opcode, 2, R).addConstantPoolIndex(CPI).addReg(Reg1); } else if (isa(C)) { // Copy zero (null pointer) to the register. @@ -703,7 +701,7 @@ // Move value at base + distance into return reg BuildMI(*MBB, IP, PPC::LOADHiAddr, 2, TmpReg) - .addReg(getGlobalBaseReg(MBB, IP)).addGlobalAddress(GV); + .addReg(getGlobalBaseReg()).addGlobalAddress(GV); if (GV->hasWeakLinkage() || GV->isExternal()) { BuildMI(*MBB, IP, PPC::LWZ, 2, R).addGlobalAddress(GV).addReg(TmpReg); Index: llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.47 llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.48 --- llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp:1.47 Wed Mar 23 22:41:43 2005 +++ llvm/lib/Target/PowerPC/PowerPCTargetMachine.cpp Thu Mar 24 00:28:42 2005 @@ -37,8 +37,8 @@ cl::opt EnablePPCLSR("enable-lsr-for-ppc", cl::desc("Enable LSR for PPC (beta option!)"), cl::Hidden); - cl::opt EnablePatternISel("pattern-isel", cl::Hidden, - cl::desc("Enable the pattern isel XXX FIXME")); + cl::opt EnablePatternISel("enable-ppc-pattern-isel", cl::Hidden, + cl::desc("Enable the pattern isel")); } namespace { From alkis at cs.uiuc.edu Thu Mar 24 07:38:43 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu, 24 Mar 2005 07:38:43 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Class.h Class.cpp Message-ID: <200503241338.HAA16931@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.242 -> 1.243 Class.h updated: 1.1 -> 1.2 Class.cpp updated: 1.1 -> 1.2 --- Log message: Add superclass pointer to each Class object. --- Diffs of the changes: (+28 -21) Class.cpp | 19 ++++++++++++++----- Class.h | 2 ++ Compiler.cpp | 28 ++++++++++++---------------- 3 files changed, 28 insertions(+), 21 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.242 llvm-java/lib/Compiler/Compiler.cpp:1.243 --- llvm-java/lib/Compiler/Compiler.cpp:1.242 Wed Mar 23 22:47:47 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Thu Mar 24 07:38:30 2005 @@ -65,7 +65,7 @@ std::auto_ptr bbBuilder_; std::list bbWorkList_; typedef std::map OpStackDepthMap; - OpStackDepthMap opStackDepthMap_; + OpStackDepthMap opStackDepthMap_; typedef std::map StringMap; StringMap stringMap_; BasicBlock* currentBB_; @@ -179,7 +179,7 @@ init, str + ".str", &module_); - + std::vector params; params.reserve(4); params.clear(); @@ -196,7 +196,7 @@ // Create a new java/lang/String object. Value* objRef = allocateObject(ci, vi, ip); - + // Initialize it: call java/lang/String/(byte[],int) Method* method = getMethod("java/lang/String/([BI)V"); Function* function = getFunction(method); @@ -210,7 +210,7 @@ new CallInst(function, params, "", ip); return objRef; - } + } Value* getConstantString(ConstantString* s) { const std::string& str = s->getValue()->str(); @@ -362,8 +362,6 @@ const Methods& methods = cf->getMethods(); - const Class& ci = resolver_->getClass("java/lang/Object"); - // Add member functions to the vtable. for (unsigned i = 0, e = methods.size(); i != e; ++i) { Method* method = methods[i]; @@ -1087,29 +1085,27 @@ Value* getField(unsigned index, Value* ptr) { ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); - return getField(fieldRef->getClass()->getName()->str(), - nameAndType->getName()->str(), - ptr); + return getField( + &resolver_->getClass(fieldRef->getClass()->getName()->str()), + nameAndType->getName()->str(), + ptr); } /// Emits the necessary code to get a field from the passed /// pointer to an object. - Value* getField(std::string className, + Value* getField(const Class* clazz, const std::string& fieldName, Value* ptr) { // Cast ptr to correct type. - ptr = new CastInst(ptr, resolver_->getClass(className).getType(), - TMP, currentBB_); + ptr = new CastInst(ptr, clazz->getType(), TMP, currentBB_); // Deref pointer. std::vector indices(1, ConstantUInt::get(Type::UIntTy, 0)); while (true) { - const Class& clazz = resolver_->getClass(className); - int slot = clazz.getFieldIndex(fieldName); + int slot = clazz->getFieldIndex(fieldName); if (slot == -1) { - className = - ClassFile::get(className)->getSuperClass()->getName()->str(); indices.push_back(ConstantUInt::get(Type::UIntTy, 0)); + clazz = clazz->getSuperClass(); } else { indices.push_back(ConstantUInt::get(Type::UIntTy, slot)); Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.1 llvm-java/lib/Compiler/Class.h:1.2 --- llvm-java/lib/Compiler/Class.h:1.1 Wed Mar 23 22:47:47 2005 +++ llvm-java/lib/Compiler/Class.h Thu Mar 24 07:38:30 2005 @@ -28,6 +28,7 @@ static const unsigned INVALID_INTERFACE_INDEX = 0xFFFFFFFF; Resolver* resolver_; + const Class* superClass_; const Class* componentClass_; Type* structType_; const Type* type_; @@ -56,6 +57,7 @@ public: const Type* getStructType() const { return structType_; } const Type* getType() const { return type_; } + const Class* getSuperClass() const { return superClass_; } const Class* getComponentClass() const { return componentClass_; } bool isArray() const { return componentClass_; } unsigned getInterfaceIndex() const { return interfaceIndex_; } Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.1 llvm-java/lib/Compiler/Class.cpp:1.2 --- llvm-java/lib/Compiler/Class.cpp:1.1 Wed Mar 23 22:47:47 2005 +++ llvm-java/lib/Compiler/Class.cpp Thu Mar 24 07:38:30 2005 @@ -27,6 +27,7 @@ Class::Class(Resolver& resolver) : resolver_(&resolver), + superClass_(NULL), componentClass_(NULL), structType_(OpaqueType::get()), type_(PointerType::get(structType_)), @@ -37,6 +38,7 @@ Class::Class(Resolver& resolver, const Type* type) : resolver_(&resolver), + superClass_(NULL), componentClass_(NULL), structType_(0), type_(type), @@ -68,9 +70,6 @@ { const ClassFile* cf = ClassFile::get(className); - if (cf->isInterface()) - interfaceIndex_ = resolver_->getNextInterfaceIndex(); - // This is any class but java/lang/Object. if (cf->getSuperClass()) { const Class& superClass = @@ -78,6 +77,16 @@ // We first add the struct of the super class. addField("super", superClass.getStructType()); + + // Although we can safely assume that all interfaces inherits from + // java/lang/Object, java/lang/Class.getSuperclass() returns null + // on interface types. So we only set the superClass_ field when + // the class is not an interface type, but we model the LLVM type + // of the interface to be as if it inherits java/lang/Object. + if (cf->isInterface()) + interfaceIndex_ = resolver_->getNextInterfaceIndex(); + else + superClass_ = &superClass; } // This is java/lang/Object. else @@ -98,11 +107,11 @@ void Class::buildArrayClass(const Class& componentClass) { + superClass_ = &resolver_->getClass("java/lang/Object"); componentClass_ = &componentClass; - addField("super", resolver_->getClass("java/lang/Object").getStructType()); + addField("super", superClass_->getStructType()); addField("", Type::UIntTy); addField("", ArrayType::get(componentClass_->getType(), 0)); resolveType(); } - From lattner at cs.uiuc.edu Thu Mar 24 11:32:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 11:32:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelSimple.cpp Message-ID: <200503241732.j2OHWRS4006109@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelSimple.cpp updated: 1.309 -> 1.310 --- Log message: eliminate dead variables, patch contributed by Gabor Greif! --- Diffs of the changes: (+0 -2) X86ISelSimple.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelSimple.cpp diff -u llvm/lib/Target/X86/X86ISelSimple.cpp:1.309 llvm/lib/Target/X86/X86ISelSimple.cpp:1.310 --- llvm/lib/Target/X86/X86ISelSimple.cpp:1.309 Mon Mar 14 22:54:20 2005 +++ llvm/lib/Target/X86/X86ISelSimple.cpp Thu Mar 24 11:32:10 2005 @@ -1762,7 +1762,6 @@ case Intrinsic::readio: { // On X86, memory operations are in-order. Lower this intrinsic // into a volatile load. - Instruction *Before = CI->getPrev(); LoadInst * LI = new LoadInst(CI->getOperand(1), "", true, CI); CI->replaceAllUsesWith(LI); BB->getInstList().erase(CI); @@ -1771,7 +1770,6 @@ case Intrinsic::writeio: { // On X86, memory operations are in-order. Lower this intrinsic // into a volatile store. - Instruction *Before = CI->getPrev(); StoreInst *LI = new StoreInst(CI->getOperand(1), CI->getOperand(2), true, CI); CI->replaceAllUsesWith(LI); From lattner at cs.uiuc.edu Thu Mar 24 11:32:33 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 11:32:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp PPC64ISelSimple.cpp Message-ID: <200503241732.j2OHWXHp006120@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.125 -> 1.126 PPC64ISelSimple.cpp updated: 1.17 -> 1.18 --- Log message: eliminate dead variables, patch contributed by Gabor Greif! --- Diffs of the changes: (+0 -4) PPC32ISelSimple.cpp | 2 -- PPC64ISelSimple.cpp | 2 -- 2 files changed, 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.125 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.126 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.125 Thu Mar 24 00:28:42 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Thu Mar 24 11:32:19 2005 @@ -1914,7 +1914,6 @@ case Intrinsic::readio: { // On PPC, memory operations are in-order. Lower this intrinsic // into a volatile load. - Instruction *Before = CI->getPrev(); LoadInst * LI = new LoadInst(CI->getOperand(1), "", true, CI); CI->replaceAllUsesWith(LI); BB->getInstList().erase(CI); @@ -1923,7 +1922,6 @@ case Intrinsic::writeio: { // On PPC, memory operations are in-order. Lower this intrinsic // into a volatile store. - Instruction *Before = CI->getPrev(); StoreInst *SI = new StoreInst(CI->getOperand(1), CI->getOperand(2), true, CI); CI->replaceAllUsesWith(SI); Index: llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp:1.17 llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp:1.18 --- llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp:1.17 Mon Mar 14 22:54:19 2005 +++ llvm/lib/Target/PowerPC/PPC64ISelSimple.cpp Thu Mar 24 11:32:20 2005 @@ -1519,7 +1519,6 @@ case Intrinsic::readio: { // On PPC, memory operations are in-order. Lower this intrinsic // into a volatile load. - Instruction *Before = CI->getPrev(); LoadInst * LI = new LoadInst(CI->getOperand(1), "", true, CI); CI->replaceAllUsesWith(LI); BB->getInstList().erase(CI); @@ -1528,7 +1527,6 @@ case Intrinsic::writeio: { // On PPC, memory operations are in-order. Lower this intrinsic // into a volatile store. - Instruction *Before = CI->getPrev(); StoreInst *SI = new StoreInst(CI->getOperand(1), CI->getOperand(2), true, CI); CI->replaceAllUsesWith(SI); From lattner at cs.uiuc.edu Thu Mar 24 11:57:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 11:57:59 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll Message-ID: <200503241757.j2OHvxwP006211@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: 2005-03-24-Global-Arg-Alias.ll added (r1.1) --- Log message: new testcase that DS-AA is causing to be miscompiled. --- Diffs of the changes: (+26 -0) 2005-03-24-Global-Arg-Alias.ll | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+) Index: llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll diff -c /dev/null llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll:1.1 *** /dev/null Thu Mar 24 11:57:53 2005 --- llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll Thu Mar 24 11:57:43 2005 *************** *** 0 **** --- 1,26 ---- + ; RUN: llvm-as < %s | opt -ds-aa -load-vn -gcse | llvm-dis | grep 'load int* %L' + + %G = internal global int* null + + int %caller(bool %P) { + %L = alloca int + call void %callee(bool %P, int* %L) + + ;; At this point, G could point to L, so we can't eliminate these operations. + %GP = load int** %G + store int 17, int* %L + store int 18, int* %GP ;; might clober L + + %A = load int* %L ;; is not necessarily 17! + ret int %A + } + + internal void %callee(bool %Cond, int* %P) { + br bool %Cond, label %T, label %F + T: + store int* %P, int** %G + ret void + F: + ret void + } + From lattner at cs.uiuc.edu Thu Mar 24 12:42:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 12:42:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200503241842.j2OIgiqB006343@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.55 -> 1.56 --- Log message: be more aggressive about incompleteness marking --- Diffs of the changes: (+2 -3) Steensgaard.cpp | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.55 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.56 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.55 Tue Mar 22 19:48:09 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Thu Mar 24 12:42:28 2005 @@ -117,7 +117,6 @@ ResultGraph = new DSGraph(GlobalECs, getTargetData()); GlobalsGraph = new DSGraph(GlobalECs, getTargetData()); ResultGraph->setGlobalsGraph(GlobalsGraph); - ResultGraph->setPrintAuxCalls(); // Loop over the rest of the module, merging graphs for non-external functions // into this graph. @@ -173,7 +172,8 @@ // Update the "incomplete" markers on the nodes, ignoring unknownness due to // incoming arguments... ResultGraph->maskIncompleteMarkers(); - ResultGraph->markIncompleteNodes(DSGraph::IgnoreFormalArgs); + ResultGraph->markIncompleteNodes(DSGraph::IgnoreFormalArgs | + DSGraph::IgnoreGlobals); // Remove any nodes that are dead after all of the merging we have done... // FIXME: We should be able to disable the globals graph for steens! @@ -186,7 +186,6 @@ // alias - This is the only method here that does anything interesting... AliasAnalysis::AliasResult Steens::alias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size) { - // FIXME: HANDLE Size argument! assert(ResultGraph && "Result graph has not been computed yet!"); DSGraph::ScalarMapTy &GSM = ResultGraph->getScalarMap(); From lattner at cs.uiuc.edu Thu Mar 24 12:43:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 12:43:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp BottomUpClosure.cpp CompleteBottomUp.cpp Message-ID: <200503241843.j2OIh47R006359@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: EquivClassGraphs.cpp updated: 1.39 -> 1.40 BottomUpClosure.cpp updated: 1.108 -> 1.109 CompleteBottomUp.cpp updated: 1.28 -> 1.29 --- Log message: don't bother |'ing in 0's --- Diffs of the changes: (+2 -4) BottomUpClosure.cpp | 2 -- CompleteBottomUp.cpp | 2 +- EquivClassGraphs.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) Index: llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp diff -u llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.39 llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.40 --- llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp:1.39 Mon Mar 21 18:36:51 2005 +++ llvm/lib/Analysis/DataStructure/EquivClassGraphs.cpp Thu Mar 24 12:42:51 2005 @@ -436,7 +436,7 @@ if (CalleeGraph != &G) { ++NumFoldGraphInlines; G.mergeInGraph(CS, *CalleeFunc, *CalleeGraph, - DSGraph::KeepModRefBits | DSGraph::StripAllocaBit | + DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes | DSGraph::DontCloneAuxCallNodes); DEBUG(std::cerr << " Inlining graph [" << i << "/" Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.108 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.109 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.108 Wed Mar 23 22:22:04 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Thu Mar 24 12:42:51 2005 @@ -369,7 +369,6 @@ << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+" << Graph.getAuxFunctionCalls().size() << "]\n"); Graph.mergeInGraph(CS, *Callee, *GI, - DSGraph::KeepModRefBits | DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes); ++NumBUInlines; } else { @@ -444,7 +443,6 @@ << Graph.getAuxFunctionCalls().size() << "]\n"); Graph.mergeInGraph(CS, IndCallGraph.second, *GI, - DSGraph::KeepModRefBits | DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes); ++NumBUInlines; Index: llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp diff -u llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.28 llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.29 --- llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp:1.28 Mon Mar 21 18:36:51 2005 +++ llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp Thu Mar 24 12:42:51 2005 @@ -235,7 +235,7 @@ // calls or for self recursion within an SCC. DSGraph &GI = getOrCreateGraph(*CalleeFunc); ++NumCBUInlines; - G.mergeInGraph(CS, *CalleeFunc, GI, DSGraph::KeepModRefBits | + G.mergeInGraph(CS, *CalleeFunc, GI, DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes | DSGraph::DontCloneAuxCallNodes); DEBUG(std::cerr << " Inlining graph [" << i << "/" From natebegeman at mac.com Thu Mar 24 14:07:27 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 24 Mar 2005 14:07:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <200503242007.OAA19895@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.126 -> 1.127 --- Log message: Commit Gabor Greif's patch to use iterators in lowering intrinsics. --- Diffs of the changes: (+8 -7) PPC32ISelSimple.cpp | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.126 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.127 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.126 Thu Mar 24 11:32:19 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Thu Mar 24 14:07:16 2005 @@ -1928,15 +1928,16 @@ BB->getInstList().erase(CI); break; } - default: + default: { // All other intrinsic calls we must lower. - Instruction *Before = CI->getPrev(); + BasicBlock::iterator me(CI); + bool atBegin(BB->begin() == me); + if (!atBegin) + --me; TM.getIntrinsicLowering().LowerIntrinsicCall(CI); - if (Before) { // Move iterator to instruction after call - I = Before; ++I; - } else { - I = BB->begin(); - } + // Move iterator to instruction after call + I = atBegin ? BB->begin() : ++me; + } } } From lattner at cs.uiuc.edu Thu Mar 24 15:08:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 15:08:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503242108.j2OL83oJ008686@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.230 -> 1.231 --- Log message: Unfortunately, a previous patch was not safe. Revert it, reimplement something correct. Unfortunately this takes 176.gcc's BU phase back up to 29s from 1.5. This fixes DSGraph/2005-03-24-Global-Arg-Alias.ll --- Diffs of the changes: (+93 -40) DataStructure.cpp | 133 +++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 93 insertions(+), 40 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.230 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.231 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.230 Wed Mar 23 14:12:08 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Thu Mar 24 15:07:47 2005 @@ -23,6 +23,7 @@ #include "llvm/Support/Debug.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SCCIterator.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Timer.h" #include @@ -1303,24 +1304,6 @@ } } -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; -} - /// getFunctionArgumentsForCall - Given a function that is currently in this /// graph, return the DSNodeHandles that correspond to the pointer-compatible /// function arguments. The vector is filled in with the return value (or @@ -1337,6 +1320,66 @@ } } +/// PathExistsToClonedNode - Return true if there is a path from this node to a +/// node cloned by RC that does not go through another global node. Use the +/// NodeInfo map to cache information so this is an efficient depth first +/// traversal. +static bool PathExistsToClonedNode(const DSNode *N, ReachabilityCloner &RC, + std::map &NodeInfo) { + std::map::iterator I = NodeInfo.find(N); + if (I != NodeInfo.end()) + return I->second; + + // FIXME: we are potentially re-scc'ing chunks of the graph for all of the + // roots! We need an SCC iterator that supports multiple roots. + // + // FIXME: This should stop traversal of SCCs when we find something in RC! + scc_iterator SCCI = scc_begin(N), SCCE = scc_end(N); + for (; SCCI != SCCE; ++SCCI) { + std::vector &SCC = *SCCI; + assert(!SCC.empty() && "empty scc??"); + + if (NodeInfo.count(SCC[0])) + continue; // already processed. + + bool SCCReachesClonedNode = false; + + for (unsigned i = 0, e = SCC.size(); i != e; ++i) { + const DSNode *N = SCC[i]; + + if (RC.hasClonedNode(N)) { + SCCReachesClonedNode = true; + goto OutOfLoop; + } + + for (DSNode::const_edge_iterator EI = N->edge_begin(), E = N->edge_end(); + EI != E; ++EI) + if (const DSNode *Succ = EI->getNode()) + if (NodeInfo[Succ]) { + SCCReachesClonedNode = true; + goto OutOfLoop; + } + } + + OutOfLoop: + for (unsigned i = 0, e = SCC.size(); i != e; ++i) + NodeInfo[SCC[i]] = SCCReachesClonedNode; + } + + return NodeInfo[N]; +} + +static bool PathExistsToClonedNode(const DSCallSite &CS, ReachabilityCloner &RC, + std::map &NodeInfo) { + if (PathExistsToClonedNode(CS.getRetVal().getNode(), RC, NodeInfo)) + return true; + for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) + if (PathExistsToClonedNode(CS.getPtrArg(i).getNode(), RC, NodeInfo)) + return true; + return false; +} + + /// mergeInCallFromOtherGraph - This graph merges in the minimal number of /// nodes from G2 into 'this' graph, merging the bindings specified by the /// call site (in this graph) with the bindings specified by the vector in G2. @@ -1384,29 +1427,39 @@ RC.merge(CS.getPtrArg(i), Args[i+1]); } - // 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::set CopiedAuxCall; - - // 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; - if (!(CloneFlags & DontCloneAuxCallNodes)) - while (MadeChange) { - MadeChange = false; + // We generally don't want to copy global nodes or aux calls from the callee + // graph to the caller graph. However, we have to copy them if there is a + // path from the node to a node we have already copied which does not go + // through another global. Compute the set of node that can reach globals and + // aux call nodes to copy over, then do it. + std::vector AuxCallToCopy; + std::vector GlobalsToCopy; + + // NodesReachCopiedNodes - Memoize results for efficiency. Contains a + // true/false value for every visited node that reaches a copied node without + // going through a global. + std::map NodesReachCopiedNodes; + NodesReachCopiedNodes[0] = false; // Initialize null. - // If requested, copy any aux calls that can reach copied nodes. - for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I) - if (!CopiedAuxCall.count(&*I) && PathExistsToClonedNode(*I, RC)) { - AuxFunctionCalls.push_back(DSCallSite(*I, RC)); - MadeChange = true; - CopiedAuxCall.insert(&*I); - } - } + if (!(CloneFlags & DontCloneAuxCallNodes)) + for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I) + if (PathExistsToClonedNode(*I, RC, NodesReachCopiedNodes)) + AuxCallToCopy.push_back(&*I); + + DSScalarMap GSM = Graph.getScalarMap(); + for (DSScalarMap::global_iterator GI = GSM.global_begin(), + E = GSM.global_end(); GI != E; ++GI) + if (PathExistsToClonedNode(Graph.getNodeForValue(*GI).getNode(), RC, + NodesReachCopiedNodes)) + GlobalsToCopy.push_back(*GI); + + // Copy aux calls that are needed. + for (unsigned i = 0, e = AuxCallToCopy.size(); i != e; ++i) + AuxFunctionCalls.push_back(DSCallSite(*AuxCallToCopy[i], RC)); + + // Copy globals that are needed. + for (unsigned i = 0, e = GlobalsToCopy.size(); i != e; ++i) + RC.getClonedNH(Graph.getNodeForValue(GlobalsToCopy[i])); } From lattner at cs.uiuc.edu Thu Mar 24 15:17:43 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 15:17:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503242117.j2OLHhTr009097@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.231 -> 1.232 --- Log message: only look at successors of globals. This gets us down to "only" 22s in the bu pass for 176.gcc --- Diffs of the changes: (+9 -4) DataStructure.cpp | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.231 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.232 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.231 Thu Mar 24 15:07:47 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Thu Mar 24 15:17:27 2005 @@ -1448,10 +1448,15 @@ DSScalarMap GSM = Graph.getScalarMap(); for (DSScalarMap::global_iterator GI = GSM.global_begin(), - E = GSM.global_end(); GI != E; ++GI) - if (PathExistsToClonedNode(Graph.getNodeForValue(*GI).getNode(), RC, - NodesReachCopiedNodes)) - GlobalsToCopy.push_back(*GI); + E = GSM.global_end(); GI != E; ++GI) { + DSNode *GlobalNode = Graph.getNodeForValue(*GI).getNode(); + for (DSNode::edge_iterator EI = GlobalNode->edge_begin(), + EE = GlobalNode->edge_end(); EI != EE; ++EI) + if (PathExistsToClonedNode(EI->getNode(), RC, NodesReachCopiedNodes)) { + GlobalsToCopy.push_back(*GI); + break; + } + } // Copy aux calls that are needed. for (unsigned i = 0, e = AuxCallToCopy.size(); i != e; ++i) From alkis at cs.uiuc.edu Thu Mar 24 16:35:47 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu, 24 Mar 2005 16:35:47 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Class.h Class.cpp Message-ID: <200503242235.QAA21471@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.243 -> 1.244 Class.h updated: 1.2 -> 1.3 Class.cpp updated: 1.2 -> 1.3 --- Log message: Add a reference to the classfile object representing each Class object if this exists (this only exists for interfaces and classes, but not for arrays or primitive classes). --- Diffs of the changes: (+14 -9) Class.cpp | 12 +++++++----- Class.h | 4 ++++ Compiler.cpp | 7 +++---- 3 files changed, 14 insertions(+), 9 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.243 llvm-java/lib/Compiler/Compiler.cpp:1.244 --- llvm-java/lib/Compiler/Compiler.cpp:1.243 Thu Mar 24 07:38:30 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Thu Mar 24 16:35:36 2005 @@ -2091,10 +2091,9 @@ void do_new(unsigned index) { ConstantClass* classRef = cf_->getConstantClass(index); - const ClassFile* cf = ClassFile::get(classRef->getName()->str()); - emitStaticInitializers(cf); const Class& ci = resolver_->getClass(classRef->getName()->str()); - const VTableInfo& vi = getVTableInfo(cf); + emitStaticInitializers(ci.getClassFile()); + const VTableInfo& vi = getVTableInfo(ci.getClassFile()); push(allocateObject(ci, vi, currentBB_)); } @@ -2185,7 +2184,7 @@ // java/lang/Object's. const Class& clazz = resolver_->getClass("[Ljava/lang/Object;"); const VTableInfo& vi = - getObjectArrayVTableInfo(ClassFile::get("java/lang/Object")); + getObjectArrayVTableInfo(clazz.getClassFile()); push(allocateArray(clazz, vi, count, currentBB_)); } Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.2 llvm-java/lib/Compiler/Class.h:1.3 --- llvm-java/lib/Compiler/Class.h:1.2 Thu Mar 24 07:38:30 2005 +++ llvm-java/lib/Compiler/Class.h Thu Mar 24 16:35:36 2005 @@ -22,12 +22,14 @@ namespace llvm { namespace Java { + class ClassFile; class Resolver; class Class { static const unsigned INVALID_INTERFACE_INDEX = 0xFFFFFFFF; Resolver* resolver_; + const ClassFile* classFile_; const Class* superClass_; const Class* componentClass_; Type* structType_; @@ -57,9 +59,11 @@ public: const Type* getStructType() const { return structType_; } const Type* getType() const { return type_; } + const ClassFile* getClassFile() const { return classFile_; } const Class* getSuperClass() const { return superClass_; } const Class* getComponentClass() const { return componentClass_; } bool isArray() const { return componentClass_; } + bool isPrimitive() const { return !structType_; } unsigned getInterfaceIndex() const { return interfaceIndex_; } int getFieldIndex(const std::string& name) const; }; Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.2 llvm-java/lib/Compiler/Class.cpp:1.3 --- llvm-java/lib/Compiler/Class.cpp:1.2 Thu Mar 24 07:38:30 2005 +++ llvm-java/lib/Compiler/Class.cpp Thu Mar 24 16:35:36 2005 @@ -27,6 +27,7 @@ Class::Class(Resolver& resolver) : resolver_(&resolver), + classFile_(NULL), superClass_(NULL), componentClass_(NULL), structType_(OpaqueType::get()), @@ -38,6 +39,7 @@ Class::Class(Resolver& resolver, const Type* type) : resolver_(&resolver), + classFile_(NULL), superClass_(NULL), componentClass_(NULL), structType_(0), @@ -68,12 +70,12 @@ void Class::buildClass(const std::string& className) { - const ClassFile* cf = ClassFile::get(className); + classFile_ = ClassFile::get(className); // This is any class but java/lang/Object. - if (cf->getSuperClass()) { + if (classFile_->getSuperClass()) { const Class& superClass = - resolver_->getClass(cf->getSuperClass()->getName()->str()); + resolver_->getClass(classFile_->getSuperClass()->getName()->str()); // We first add the struct of the super class. addField("super", superClass.getStructType()); @@ -83,7 +85,7 @@ // on interface types. So we only set the superClass_ field when // the class is not an interface type, but we model the LLVM type // of the interface to be as if it inherits java/lang/Object. - if (cf->isInterface()) + if (classFile_->isInterface()) interfaceIndex_ = resolver_->getNextInterfaceIndex(); else superClass_ = &superClass; @@ -93,7 +95,7 @@ addField("base", resolver_->getObjectBaseType()); // Then we add the rest of the fields. - const Fields& fields = cf->getFields(); + const Fields& fields = classFile_->getFields(); for (unsigned i = 0, e = fields.size(); i != e; ++i) { Field& field = *fields[i]; if (!field.isStatic()) From lattner at cs.uiuc.edu Thu Mar 24 17:06:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 17:06:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503242306.j2ON6JXs011453@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.232 -> 1.233 --- Log message: This replaces the correct but slow code with a more aggressive scc-finder based approach to find globals and call sites that need to be copied. This speeds up the BU pass on 176.gcc from 22s back up to 2.3s. Not as good as 1.5s, but at least it's correct :) --- Diffs of the changes: (+99 -56) DataStructure.cpp | 155 ++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 99 insertions(+), 56 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.232 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.233 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.232 Thu Mar 24 15:17:27 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Thu Mar 24 17:06:02 2005 @@ -1320,65 +1320,109 @@ } } -/// PathExistsToClonedNode - Return true if there is a path from this node to a -/// node cloned by RC that does not go through another global node. Use the -/// NodeInfo map to cache information so this is an efficient depth first -/// traversal. -static bool PathExistsToClonedNode(const DSNode *N, ReachabilityCloner &RC, - std::map &NodeInfo) { - std::map::iterator I = NodeInfo.find(N); - if (I != NodeInfo.end()) - return I->second; +namespace { + // HackedGraphSCCFinder - This is used to find nodes that have a path from the + // node to a node cloned by the ReachabilityCloner object contained. To be + // extra obnoxious it ignores edges from nodes that are globals, and truncates + // search at RC marked nodes. This is designed as an object so that + // intermediate results can be memoized across invocations of + // PathExistsToClonedNode. + struct HackedGraphSCCFinder { + ReachabilityCloner &RC; + unsigned CurNodeId; + std::vector SCCStack; + std::map > NodeInfo; + + HackedGraphSCCFinder(ReachabilityCloner &rc) : RC(rc), CurNodeId(1) { + // Remove null pointer as a special case. + NodeInfo[0] = std::make_pair(0, false); + } - // FIXME: we are potentially re-scc'ing chunks of the graph for all of the - // roots! We need an SCC iterator that supports multiple roots. - // - // FIXME: This should stop traversal of SCCs when we find something in RC! - scc_iterator SCCI = scc_begin(N), SCCE = scc_end(N); - for (; SCCI != SCCE; ++SCCI) { - std::vector &SCC = *SCCI; - assert(!SCC.empty() && "empty scc??"); - - if (NodeInfo.count(SCC[0])) - continue; // already processed. - - bool SCCReachesClonedNode = false; - - for (unsigned i = 0, e = SCC.size(); i != e; ++i) { - const DSNode *N = SCC[i]; - - if (RC.hasClonedNode(N)) { - SCCReachesClonedNode = true; - goto OutOfLoop; - } + std::pair &VisitForSCCs(const DSNode *N); - for (DSNode::const_edge_iterator EI = N->edge_begin(), E = N->edge_end(); - EI != E; ++EI) - if (const DSNode *Succ = EI->getNode()) - if (NodeInfo[Succ]) { - SCCReachesClonedNode = true; - goto OutOfLoop; - } + bool PathExistsToClonedNode(const DSNode *N) { + return VisitForSCCs(N).second; } - OutOfLoop: - for (unsigned i = 0, e = SCC.size(); i != e; ++i) - NodeInfo[SCC[i]] = SCCReachesClonedNode; + bool PathExistsToClonedNode(const DSCallSite &CS) { + if (PathExistsToClonedNode(CS.getRetVal().getNode())) + return true; + for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) + if (PathExistsToClonedNode(CS.getPtrArg(i).getNode())) + return true; + return false; + } + }; +} + +std::pair &HackedGraphSCCFinder:: +VisitForSCCs(const DSNode *N) { + std::map >::iterator + NodeInfoIt = NodeInfo.lower_bound(N); + if (NodeInfoIt != NodeInfo.end() && NodeInfoIt->first == N) + return NodeInfoIt->second; + + unsigned Min = CurNodeId++; + unsigned MyId = Min; + std::pair &ThisNodeInfo = + NodeInfo.insert(NodeInfoIt, + std::make_pair(N, std::make_pair(MyId, false)))->second; + + // Base case: if we find a global, this doesn't reach the cloned graph + // portion. + if (N->isGlobalNode()) { + ThisNodeInfo.second = false; + return ThisNodeInfo; } - return NodeInfo[N]; -} + // Base case: if this does reach the cloned graph portion... it does. :) + if (RC.hasClonedNode(N)) { + ThisNodeInfo.second = true; + return ThisNodeInfo; + } -static bool PathExistsToClonedNode(const DSCallSite &CS, ReachabilityCloner &RC, - std::map &NodeInfo) { - if (PathExistsToClonedNode(CS.getRetVal().getNode(), RC, NodeInfo)) - return true; - for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) - if (PathExistsToClonedNode(CS.getPtrArg(i).getNode(), RC, NodeInfo)) - return true; - return false; -} + SCCStack.push_back(N); + + // Otherwise, check all successors. + bool AnyDirectSuccessorsReachClonedNodes = false; + for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end(); + EI != EE; ++EI) { + std::pair &SuccInfo = VisitForSCCs(EI->getNode()); + if (SuccInfo.first < Min) Min = SuccInfo.first; + AnyDirectSuccessorsReachClonedNodes |= SuccInfo.second; + } + if (Min != MyId) + return ThisNodeInfo; // Part of a large SCC. Leave self on stack. + + if (SCCStack.back() == N) { // Special case single node SCC. + SCCStack.pop_back(); + ThisNodeInfo.second = AnyDirectSuccessorsReachClonedNodes; + return ThisNodeInfo; + } + + // Find out if any direct successors of any node reach cloned nodes. + if (!AnyDirectSuccessorsReachClonedNodes) + for (unsigned i = SCCStack.size()-1; SCCStack[i] != N; --i) + for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end(); + EI != EE; ++EI) + if (DSNode *N = EI->getNode()) + if (NodeInfo[N].second) { + AnyDirectSuccessorsReachClonedNodes = true; + goto OutOfLoop; + } +OutOfLoop: + // If any successor reaches a cloned node, mark all nodes in this SCC as + // reaching the cloned node. + if (AnyDirectSuccessorsReachClonedNodes) + while (SCCStack.back() != N) { + NodeInfo[SCCStack.back()].second = true; + SCCStack.pop_back(); + } + SCCStack.pop_back(); + ThisNodeInfo.second = true; + return ThisNodeInfo; +} /// mergeInCallFromOtherGraph - This graph merges in the minimal number of /// nodes from G2 into 'this' graph, merging the bindings specified by the @@ -1438,21 +1482,20 @@ // NodesReachCopiedNodes - Memoize results for efficiency. Contains a // true/false value for every visited node that reaches a copied node without // going through a global. - std::map NodesReachCopiedNodes; - NodesReachCopiedNodes[0] = false; // Initialize null. + HackedGraphSCCFinder SCCFinder(RC); if (!(CloneFlags & DontCloneAuxCallNodes)) for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I) - if (PathExistsToClonedNode(*I, RC, NodesReachCopiedNodes)) + if (SCCFinder.PathExistsToClonedNode(*I)) AuxCallToCopy.push_back(&*I); - DSScalarMap GSM = Graph.getScalarMap(); + const DSScalarMap &GSM = Graph.getScalarMap(); for (DSScalarMap::global_iterator GI = GSM.global_begin(), E = GSM.global_end(); GI != E; ++GI) { DSNode *GlobalNode = Graph.getNodeForValue(*GI).getNode(); for (DSNode::edge_iterator EI = GlobalNode->edge_begin(), EE = GlobalNode->edge_end(); EI != EE; ++EI) - if (PathExistsToClonedNode(EI->getNode(), RC, NodesReachCopiedNodes)) { + if (SCCFinder.PathExistsToClonedNode(EI->getNode())) { GlobalsToCopy.push_back(*GI); break; } From natebegeman at mac.com Thu Mar 24 17:34:49 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 24 Mar 2005 17:34:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <200503242334.RAA21980@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.127 -> 1.128 --- Log message: Fix an incorrect argument being passed to BuildMI for indirect calls. --- Diffs of the changes: (+1 -1) PPC32ISelSimple.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.127 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.128 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.127 Thu Mar 24 14:07:16 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Thu Mar 24 17:34:38 2005 @@ -1849,7 +1849,7 @@ unsigned Reg = getReg(CI.getCalledValue()); BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Reg).addReg(Reg); BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12); - TheCall = BuildMI(PPC::CALLindirect, 2).addZImm(20).addZImm(0) + TheCall = BuildMI(PPC::CALLindirect, 3).addZImm(20).addZImm(0) .addReg(PPC::R12); } From natebegeman at mac.com Thu Mar 24 17:35:41 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 24 Mar 2005 17:35:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200503242335.RAA21995@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.3 -> 1.4 --- Log message: Implement next round of Pattern ISel fixes 1. void returns 2. multiplies 3. calls --- Diffs of the changes: (+162 -38) PPC32ISelPattern.cpp | 200 +++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 162 insertions(+), 38 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.3 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.4 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.3 Thu Mar 24 00:28:42 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Thu Mar 24 17:35:30 2005 @@ -221,10 +221,16 @@ case MVT::i1: case MVT::i8: case MVT::i16: + // Promote the integer to 32 bits. If the input type is signed use a + // sign extend, otherwise use a zero extend. + if (Args[i].second->isSigned()) + Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); + else + Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); + break; case MVT::i32: - case MVT::i64: - case MVT::f64: case MVT::f32: + case MVT::f64: break; } args_to_use.push_back(Args[i].first); @@ -438,14 +444,33 @@ unsigned &Reg = ExprMap[N]; if (Reg) return Reg; - if (DestType == MVT::f64 || DestType == MVT::f32) - return SelectExprFP(N, Result); - - if (N.getOpcode() != ISD::CALL) + if (N.getOpcode() != ISD::CALL && N.getOpcode() != ISD::ADD_PARTS && + N.getOpcode() != ISD::SUB_PARTS) Reg = Result = (N.getValueType() != MVT::Other) ? MakeReg(N.getValueType()) : 1; - else - abort(); // FIXME: Implement Call + else { + // If this is a call instruction, make sure to prepare ALL of the result + // values as well as the chain. + if (N.getOpcode() == ISD::CALL) { + if (Node->getNumValues() == 1) + Reg = Result = 1; // Void call, just a chain. + else { + Result = MakeReg(Node->getValueType(0)); + ExprMap[N.getValue(0)] = Result; + for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i) + ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i)); + ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1; + } + } else { + Result = MakeReg(Node->getValueType(0)); + ExprMap[N.getValue(0)] = Result; + for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i) + ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i)); + } + } + + if (DestType == MVT::f64 || DestType == MVT::f32) + return SelectExprFP(N, Result); switch (opcode) { default: @@ -482,10 +507,24 @@ case ISD::FrameIndex: abort(); + case ISD::GlobalAddress: { + GlobalValue *GV = cast(N)->getGlobal(); + unsigned Tmp1 = MakeReg(MVT::i32); + // FIXME: R1 is incorrect, we need the getGlobalBaseReg() functionality + // from the simple isel + BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(PPC::R1).addGlobalAddress(GV); + if (GV->hasWeakLinkage() || GV->isExternal()) { + BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1); + } else { + BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp1).addGlobalAddress(GV); + } + return Result; + } + case ISD::LOAD: case ISD::EXTLOAD: case ISD::ZEXTLOAD: - { + case ISD::SEXTLOAD: { // Make sure we generate both values. if (Result != 1) ExprMap[N.getValue(1)] = 1; // Generate the token @@ -498,22 +537,13 @@ switch (Node->getValueType(0)) { default: assert(0 && "Cannot load this type!"); - case MVT::i1: - case MVT::i8: Opc = PPC::LBZ; break; - case MVT::i16: Opc = PPC::LHZ; break; - case MVT::i32: Opc = PPC::LWZ; break; + case MVT::i1: Opc = PPC::LBZ; Tmp3 = 0; break; + case MVT::i8: Opc = PPC::LBZ; Tmp3 = 1; break; + case MVT::i16: Opc = PPC::LHZ; Tmp3 = 0; break; + case MVT::i32: Opc = PPC::LWZ; Tmp3 = 0; break; } - if (Address.getOpcode() == ISD::GlobalAddress) { // FIXME - BuildMI(BB, Opc, 2, Result) - .addGlobalAddress(cast(Address)->getGlobal()) - .addReg(PPC::R1); - } - else if (ConstantPoolSDNode *CP = dyn_cast(Address)) { - BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CP->getIndex()) - .addReg(PPC::R1); - } - else if(Address.getOpcode() == ISD::FrameIndex) { + if(Address.getOpcode() == ISD::FrameIndex) { BuildMI(BB, Opc, 2, Result) .addFrameIndex(cast(Address)->getIndex()) .addReg(PPC::R1); @@ -525,10 +555,93 @@ return Result; } - case ISD::SEXTLOAD: - case ISD::GlobalAddress: - case ISD::CALL: - abort(); + case ISD::CALL: { + // Lower the chain for this call. + Select(N.getOperand(0)); + ExprMap[N.getValue(Node->getNumValues()-1)] = 1; + + // get the virtual reg for each argument + std::vector VRegs; + for(int i = 2, e = Node->getNumOperands(); i < e; ++i) + VRegs.push_back(SelectExpr(N.getOperand(i))); + + // The ABI specifies that the first 32 bytes of args may be passed in GPRs, + // and that 13 FPRs may also be used for passing any floating point args. + int GPR_remaining = 8, FPR_remaining = 13; + unsigned GPR_idx = 0, FPR_idx = 0; + static const unsigned GPR[] = { + PPC::R3, PPC::R4, PPC::R5, PPC::R6, + PPC::R7, PPC::R8, PPC::R9, PPC::R10, + }; + static const unsigned FPR[] = { + PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, + PPC::F7, PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, + PPC::F13 + }; + + // move the vregs into the appropriate architected register or stack slot + for(int i = 0, e = VRegs.size(); i < e; ++i) { + unsigned OperandType = N.getOperand(i+2).getValueType(); + switch(OperandType) { + default: + Node->dump(); + N.getOperand(i).Val->dump(); + std::cerr << "Type for " << i << " is: " << + N.getOperand(i+2).getValueType() << "\n"; + assert(0 && "Unknown value type for call"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + if (GPR_remaining > 0) + BuildMI(BB, PPC::OR, 2, GPR[GPR_idx]).addReg(VRegs[i]) + .addReg(VRegs[i]); + break; + case MVT::f32: + case MVT::f64: + if (FPR_remaining > 0) { + BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(VRegs[i]); + --FPR_remaining; + } + break; + } + // All arguments consume GPRs available for argument passing + if (GPR_remaining > 0) --GPR_remaining; + if (MVT::f64 == OperandType && GPR_remaining > 0) --GPR_remaining; + } + + // Emit the correct call instruction based on the type of symbol called. + if (GlobalAddressSDNode *GASD = + dyn_cast(N.getOperand(1))) { + BuildMI(BB, PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(), true); + } else if (ExternalSymbolSDNode *ESSDN = + dyn_cast(N.getOperand(1))) { + BuildMI(BB, PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(), true); + } else { + Tmp1 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1); + BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12); + BuildMI(BB, PPC::CALLindirect, 3).addImm(20).addImm(0).addReg(PPC::R12); + } + + switch (Node->getValueType(0)) { + default: assert(0 && "Unknown value type for call result!"); + case MVT::Other: return 1; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3); + if (Node->getValueType(1) == MVT::i32) + BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4); + break; + case MVT::f32: + case MVT::f64: + BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1); + break; + } + return Result+N.ResNo; + } case ISD::SIGN_EXTEND: case ISD::SIGN_EXTEND_INREG: @@ -551,9 +664,6 @@ .addImm(Tmp2).addImm(31); return Result; - case ISD::SETCC: - abort(); - case ISD::CopyFromReg: if (Result == 1) Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); @@ -613,14 +723,7 @@ break; } return Result; - - case ISD::SUB: - assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1); - return Result; - + case ISD::AND: case ISD::OR: case ISD::XOR: @@ -655,8 +758,23 @@ break; } return Result; + + case ISD::SUB: + assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1); + return Result; case ISD::MUL: + assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); + Tmp1 = SelectExpr(N.getOperand(0)); + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp2).addReg(Tmp1); + return Result; + + case ISD::ADD_PARTS: + case ISD::SUB_PARTS: case ISD::UREM: case ISD::SREM: case ISD::SDIV: @@ -667,6 +785,9 @@ case ISD::FP_TO_SINT: abort(); + case ISD::SETCC: + abort(); + case ISD::SELECT: abort(); @@ -776,6 +897,9 @@ BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1); break; } + case 1: + Select(N.getOperand(0)); + break; } BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction return; From lattner at cs.uiuc.edu Thu Mar 24 17:45:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 17:45:36 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure/DSGraph.h Message-ID: <200503242345.j2ONjaiU016071@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DSGraph.h updated: 1.107 -> 1.108 --- Log message: add new spliceFrom methods. --- Diffs of the changes: (+10 -0) DSGraph.h | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/include/llvm/Analysis/DataStructure/DSGraph.h diff -u llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.107 llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.108 --- llvm/include/llvm/Analysis/DataStructure/DSGraph.h:1.107 Tue Mar 22 13:44:11 2005 +++ llvm/include/llvm/Analysis/DataStructure/DSGraph.h Thu Mar 24 17:45:20 2005 @@ -154,6 +154,10 @@ GlobalSet.clear(); } + /// spliceFrom - Copy all entries from RHS, then clear RHS. + /// + void spliceFrom(DSScalarMap &RHS); + // Access to the global set: the set of all globals currently in the // scalar map. typedef GlobalSetTy::const_iterator global_iterator; @@ -455,6 +459,12 @@ void computeCalleeCallerMapping(DSCallSite CS, const Function &Callee, DSGraph &CalleeGraph, NodeMapTy &NodeMap); + /// spliceFrom - Logically perform the operation of cloning the RHS graph into + /// this graph, then clearing the RHS graph. Instead of performing this as + /// two seperate operations, do it as a single, much faster, one. + /// + void spliceFrom(DSGraph &RHS); + /// cloneInto - Clone the specified DSGraph into the current graph. /// /// The CloneFlags member controls various aspects of the cloning process. From lattner at cs.uiuc.edu Thu Mar 24 17:46:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 17:46:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503242346.j2ONkHsi016110@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.233 -> 1.234 --- Log message: add a new DSGraph::spliceFrom method, which violently takes the content of one graph and plops it into another, without breaking a sweat. --- Diffs of the changes: (+41 -0) DataStructure.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.233 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.234 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.233 Thu Mar 24 17:06:02 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Thu Mar 24 17:46:04 2005 @@ -1304,6 +1304,47 @@ } } +/// spliceFrom - Logically perform the operation of cloning the RHS graph into +/// this graph, then clearing the RHS graph. Instead of performing this as +/// two seperate operations, do it as a single, much faster, one. +/// +void DSGraph::spliceFrom(DSGraph &RHS) { + // Change all of the nodes in RHS to think we are their parent. + for (NodeListTy::iterator I = RHS.Nodes.begin(), E = RHS.Nodes.end(); + I != E; ++I) + I->setParentGraph(this); + // Take all of the nodes. + Nodes.splice(Nodes.end(), RHS.Nodes); + + // Take all of the calls. + FunctionCalls.splice(FunctionCalls.end(), RHS.FunctionCalls); + AuxFunctionCalls.splice(AuxFunctionCalls.end(), RHS.AuxFunctionCalls); + + // Take all of the return nodes. + ReturnNodes.insert(RHS.ReturnNodes.begin(), RHS.ReturnNodes.end()); + RHS.ReturnNodes.clear(); + + // Merge the scalar map in. + ScalarMap.spliceFrom(RHS.ScalarMap); +} + +/// spliceFrom - Copy all entries from RHS, then clear RHS. +/// +void DSScalarMap::spliceFrom(DSScalarMap &RHS) { + // Special case if this is empty. + if (ValueMap.empty()) { + ValueMap.swap(RHS.ValueMap); + GlobalSet.swap(RHS.GlobalSet); + } else { + GlobalSet.insert(RHS.GlobalSet.begin(), RHS.GlobalSet.end()); + for (ValueMapTy::iterator I = RHS.ValueMap.begin(), E = RHS.ValueMap.end(); + I != E; ++I) + ValueMap[I->first].mergeWith(I->second); + RHS.ValueMap.clear(); + } +} + + /// getFunctionArgumentsForCall - Given a function that is currently in this /// graph, return the DSNodeHandles that correspond to the pointer-compatible /// function arguments. The vector is filled in with the return value (or From lattner at cs.uiuc.edu Thu Mar 24 18:02:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 18:02:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503250002.j2P02v57017589@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.234 -> 1.235 --- Log message: Make the spliceFrom case where one graph is completely empty be constant time. --- Diffs of the changes: (+6 -2) DataStructure.cpp | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.234 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.235 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.234 Thu Mar 24 17:46:04 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Thu Mar 24 18:02:41 2005 @@ -1321,8 +1321,12 @@ AuxFunctionCalls.splice(AuxFunctionCalls.end(), RHS.AuxFunctionCalls); // Take all of the return nodes. - ReturnNodes.insert(RHS.ReturnNodes.begin(), RHS.ReturnNodes.end()); - RHS.ReturnNodes.clear(); + if (ReturnNodes.empty()) { + ReturnNodes.swap(RHS.ReturnNodes); + } else { + ReturnNodes.insert(RHS.ReturnNodes.begin(), RHS.ReturnNodes.end()); + RHS.ReturnNodes.clear(); + } // Merge the scalar map in. ScalarMap.spliceFrom(RHS.ScalarMap); From lattner at cs.uiuc.edu Thu Mar 24 18:05:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 18:05:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Message-ID: <200503250005.j2P05Hal017606@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.109 -> 1.110 --- Log message: Two changes here: 1. Instead of copying Local graphs to the BU graphs to start with, use spliceFrom to do the job (which is constant time in this case). On 176.gcc, this chops off .17s from the bu pass. 2. When building SCC graphs, simplify the logic and use spliceFrom to do the heavy lifting, instead of cloneInto/delete. This slices another .14s off 176.gcc. --- Diffs of the changes: (+41 -47) BottomUpClosure.cpp | 88 ++++++++++++++++++++++++---------------------------- 1 files changed, 41 insertions(+), 47 deletions(-) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.109 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.110 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.109 Thu Mar 24 12:42:51 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Thu Mar 24 18:05:04 2005 @@ -19,6 +19,7 @@ #include "llvm/Module.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Timer.h" using namespace llvm; namespace { @@ -114,9 +115,11 @@ DSGraph *&Graph = DSInfo[F]; if (Graph) return *Graph; - // Copy the local version into DSInfo... - Graph = new DSGraph(getAnalysis().getDSGraph(*F), - GlobalECs); + DSGraph &LocGraph = getAnalysis().getDSGraph(*F); + + // Steal the local graph. + Graph = new DSGraph(GlobalECs, LocGraph.getTargetData()); + Graph->spliceFrom(LocGraph); Graph->setGlobalsGraph(GlobalsGraph); Graph->setPrintAuxCalls(); @@ -235,66 +238,57 @@ } else { // SCCFunctions - Keep track of the functions in the current SCC // - hash_set SCCGraphs; + std::vector SCCGraphs; + + unsigned SCCSize = 1; + Function *NF = Stack.back(); + ValMap[NF] = ~0U; + DSGraph &SCCGraph = getDSGraph(*NF); - Function *NF; - std::vector::iterator FirstInSCC = Stack.end(); - DSGraph *SCCGraph = 0; - do { - NF = *--FirstInSCC; + { NamedRegionTimer XX("asldkfjasdf"); + + // First thing first, collapse all of the DSGraphs into a single graph for + // the entire SCC. Splice all of the graphs into one and discard all of the + // old graphs. + // + while (NF != F) { + Stack.pop_back(); + NF = Stack.back(); ValMap[NF] = ~0U; - // Figure out which graph is the largest one, in order to speed things up - // a bit in situations where functions in the SCC have widely different - // 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); + DSGraph &NFG = getDSGraph(*NF); - std::cerr << "Calculating graph for SCC #: " << MyID << " of size: " - << SCCGraphs.size() << "\n"; + // Update the Function -> DSG map. + for (DSGraph::retnodes_iterator I = NFG.retnodes_begin(), + E = NFG.retnodes_end(); I != E; ++I) + DSInfo[I->first] = &SCCGraph; - // Compute the Max SCC Size... - if (MaxSCC < SCCGraphs.size()) - MaxSCC = SCCGraphs.size(); + SCCGraph.spliceFrom(NFG); + delete &NFG; - // First thing first, collapse all of the DSGraphs into a single graph for - // the entire SCC. We computed the largest graph, so clone all of the other - // (smaller) graphs into it. Discard all of the old graphs. - // - for (hash_set::iterator I = SCCGraphs.begin(), - E = SCCGraphs.end(); I != E; ++I) { - DSGraph &G = **I; - if (&G != SCCGraph) { - SCCGraph->cloneInto(G); - - // Update the DSInfo map and delete the old graph... - for (DSGraph::retnodes_iterator I = G.retnodes_begin(), - E = G.retnodes_end(); I != E; ++I) - DSInfo[I->first] = SCCGraph; - delete &G; - } + ++SCCSize; + } + Stack.pop_back(); } + std::cerr << "Calculating graph for SCC #: " << MyID << " of size: " + << SCCSize << "\n"; + + // Compute the Max SCC Size. + if (MaxSCC < SCCSize) + MaxSCC = SCCSize; // Clean up the graph before we start inlining a bunch again... - SCCGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals); + SCCGraph.removeDeadNodes(DSGraph::KeepUnreachableGlobals); // Now that we have one big happy family, resolve all of the call sites in // the graph... - calculateGraph(*SCCGraph); - DEBUG(std::cerr << " [BU] Done inlining SCC [" << SCCGraph->getGraphSize() - << "+" << SCCGraph->getAuxFunctionCalls().size() << "]\n"); + calculateGraph(SCCGraph); + DEBUG(std::cerr << " [BU] Done inlining SCC [" << SCCGraph.getGraphSize() + << "+" << SCCGraph.getAuxFunctionCalls().size() << "]\n"); std::cerr << "DONE with SCC #: " << MyID << "\n"; // We never have to revisit "SCC" processed functions... - - // Drop the stuff we don't need from the end of the stack - Stack.erase(FirstInSCC, Stack.end()); return MyID; } From lattner at cs.uiuc.edu Thu Mar 24 18:06:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 18:06:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Message-ID: <200503250006.j2P06ND1017716@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.110 -> 1.111 --- Log message: remove a debugging timer. --- Diffs of the changes: (+1 -4) BottomUpClosure.cpp | 5 +---- 1 files changed, 1 insertion(+), 4 deletions(-) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.110 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.111 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.110 Thu Mar 24 18:05:04 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Thu Mar 24 18:06:09 2005 @@ -19,7 +19,6 @@ #include "llvm/Module.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Timer.h" using namespace llvm; namespace { @@ -245,8 +244,6 @@ ValMap[NF] = ~0U; DSGraph &SCCGraph = getDSGraph(*NF); - { NamedRegionTimer XX("asldkfjasdf"); - // First thing first, collapse all of the DSGraphs into a single graph for // the entire SCC. Splice all of the graphs into one and discard all of the // old graphs. @@ -269,7 +266,7 @@ ++SCCSize; } Stack.pop_back(); - } + std::cerr << "Calculating graph for SCC #: " << MyID << " of size: " << SCCSize << "\n"; From lattner at cs.uiuc.edu Thu Mar 24 18:22:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 18:22:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp Message-ID: <200503250022.j2P0MqMr019043@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LICM.cpp updated: 1.71 -> 1.72 --- Log message: Fix a bug where LICM was not updating AA information properly when sinking a pointer value out of a loop causing it to be duplicated. --- Diffs of the changes: (+2 -1) LICM.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/LICM.cpp diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.71 llvm/lib/Transforms/Scalar/LICM.cpp:1.72 --- llvm/lib/Transforms/Scalar/LICM.cpp:1.71 Wed Mar 23 15:00:12 2005 +++ llvm/lib/Transforms/Scalar/LICM.cpp Thu Mar 24 18:22:36 2005 @@ -302,7 +302,7 @@ // outside of the loop. In this case, it doesn't even matter if the // operands of the instruction are loop invariant. // - if (canSinkOrHoistInst(I) && isNotUsedInLoop(I)) { + if (isNotUsedInLoop(I) && canSinkOrHoistInst(I)) { ++II; sink(I); } @@ -530,6 +530,7 @@ New = &I; } else { New = I.clone(); + CurAST->copyValue(&I, New); if (!I.getName().empty()) New->setName(I.getName()+".le"); ExitBlock->getInstList().insert(InsertPt, New); From lattner at cs.uiuc.edu Thu Mar 24 22:52:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 22:52:17 -0600 Subject: [llvm-commits] CVS: llvm-www/testresults/index.html Message-ID: <200503250452.j2P4qHBd024996@apoc.cs.uiuc.edu> Changes in directory llvm-www/testresults: index.html updated: 1.32 -> 1.33 --- Log message: Add Al's tester --- Diffs of the changes: (+4 -0) index.html | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm-www/testresults/index.html diff -u llvm-www/testresults/index.html:1.32 llvm-www/testresults/index.html:1.33 --- llvm-www/testresults/index.html:1.32 Thu Mar 10 09:58:43 2005 +++ llvm-www/testresults/index.html Thu Mar 24 22:52:01 2005 @@ -36,6 +36,10 @@
  • FreeBSD-CURRENT (Single Pentium M @ 2.3GHz) -- release build
  • + +
  • Debian GNU/Linux +unstable, dual Xeon(TM) 3.20GHz -- debug build
  • +

    PowerPC

    From lattner at cs.uiuc.edu Thu Mar 24 23:49:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 23:49:29 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LICM/2005-03-24-LICM-Aggregate-Crash.ll Message-ID: <200503250549.j2P5nT6a028039@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LICM: 2005-03-24-LICM-Aggregate-Crash.ll added (r1.1) --- Log message: New testcase that crashes licm. --- Diffs of the changes: (+10 -0) 2005-03-24-LICM-Aggregate-Crash.ll | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/test/Regression/Transforms/LICM/2005-03-24-LICM-Aggregate-Crash.ll diff -c /dev/null llvm/test/Regression/Transforms/LICM/2005-03-24-LICM-Aggregate-Crash.ll:1.1 *** /dev/null Thu Mar 24 23:49:23 2005 --- llvm/test/Regression/Transforms/LICM/2005-03-24-LICM-Aggregate-Crash.ll Thu Mar 24 23:49:13 2005 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | opt -licm -disable-output + + void %test({int}* %P) { + br label %Loop + + Loop: + free {int}* %P + br label %Loop + } + From lattner at cs.uiuc.edu Thu Mar 24 23:49:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 24 Mar 2005 23:49:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasSetTracker.cpp Message-ID: <200503250549.j2P5noCY028052@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasSetTracker.cpp updated: 1.34 -> 1.35 --- Log message: Treat free operations as volatile, since they cannot be moved. This fixes Transforms/LICM/2005-03-24-LICM-Aggregate-Crash.ll --- Diffs of the changes: (+3 -0) AliasSetTracker.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Analysis/AliasSetTracker.cpp diff -u llvm/lib/Analysis/AliasSetTracker.cpp:1.34 llvm/lib/Analysis/AliasSetTracker.cpp:1.35 --- llvm/lib/Analysis/AliasSetTracker.cpp:1.34 Thu Mar 17 09:36:18 2005 +++ llvm/lib/Analysis/AliasSetTracker.cpp Thu Mar 24 23:49:37 2005 @@ -288,6 +288,9 @@ bool NewPtr; AliasSet &AS = addPointer(FI->getOperand(0), ~0, AliasSet::Mods, NewPtr); + + // Free operations are volatile ops (cannot be moved). + AS.setVolatile(); return NewPtr; } From lattner at cs.uiuc.edu Fri Mar 25 00:37:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 25 Mar 2005 00:37:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopSimplify.cpp Message-ID: <200503250637.j2P6bd7r005839@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopSimplify.cpp updated: 1.54 -> 1.55 --- Log message: Enhance loopsimplify to preserve alias analysis instead of clobbering it. This prevents crashes on some programs when using -ds-aa -licm. --- Diffs of the changes: (+15 -2) LoopSimplify.cpp | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopSimplify.cpp diff -u llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.54 llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.55 --- llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.54 Sun Mar 6 15:35:38 2005 +++ llvm/lib/Transforms/Scalar/LoopSimplify.cpp Fri Mar 25 00:37:22 2005 @@ -37,6 +37,7 @@ #include "llvm/Instructions.h" #include "llvm/Function.h" #include "llvm/Type.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" @@ -54,6 +55,10 @@ NumNested("loopsimplify", "Number of nested loops split out"); struct LoopSimplify : public FunctionPass { + // AA - If we have an alias analysis object to update, this is it, otherwise + // this is null. + AliasAnalysis *AA; + virtual bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -96,6 +101,7 @@ bool LoopSimplify::runOnFunction(Function &F) { bool Changed = false; LoopInfo &LI = getAnalysis(); + AA = getAnalysisToUpdate(); for (LoopInfo::iterator I = LI.begin(), E = LI.end(); I != E; ++I) Changed |= ProcessLoop(*I); @@ -130,6 +136,7 @@ (*SI)->removePredecessor(DeadBlock); // Remove PHI node entries // Delete the dead terminator. + if (AA) AA->deleteValue(&DeadBlock->back()); DeadBlock->getInstList().pop_back(); Value *RetVal = 0; @@ -230,6 +237,7 @@ if (InVal == 0) { // Create the new PHI node, insert it into NewBB at the end of the block PHINode *NewPHI = new PHINode(PN->getType(), PN->getName()+".ph", BI); + if (AA) AA->copyValue(PN, NewPHI); // Move all of the edges from blocks outside the loop to the new PHI for (unsigned i = 0, e = Preds.size(); i != e; ++i) { @@ -253,6 +261,7 @@ if (!isa(V) || getAnalysis().dominates(cast(V), PN)) { PN->replaceAllUsesWith(V); + if (AA) AA->deleteValue(PN); BB->getInstList().erase(PN); } } @@ -429,7 +438,8 @@ /// FindPHIToPartitionLoops - The first part of loop-nestification is to find a /// PHI node that tells us how to partition the loops. -static PHINode *FindPHIToPartitionLoops(Loop *L, DominatorSet &DS) { +static PHINode *FindPHIToPartitionLoops(Loop *L, DominatorSet &DS, + AliasAnalysis *AA) { for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ) { PHINode *PN = cast(I); ++I; @@ -437,6 +447,7 @@ if (!isa(V) || DS.dominates(cast(V), PN)) { // This is a degenerate PHI already, don't modify it! PN->replaceAllUsesWith(V); + if (AA) AA->deleteValue(PN); PN->eraseFromParent(); continue; } @@ -469,7 +480,7 @@ /// created. /// Loop *LoopSimplify::SeparateNestedLoop(Loop *L) { - PHINode *PN = FindPHIToPartitionLoops(L, getAnalysis()); + PHINode *PN = FindPHIToPartitionLoops(L, getAnalysis(), AA); if (PN == 0) return 0; // No known way to partition. // Pull out all predecessors that have varying values in the loop. This @@ -576,6 +587,7 @@ PHINode *NewPN = new PHINode(PN->getType(), PN->getName()+".be", BETerminator); NewPN->reserveOperandSpace(BackedgeBlocks.size()); + if (AA) AA->copyValue(PN, NewPN); // Loop over the PHI node, moving all entries except the one for the // preheader over to the new PHI node. @@ -616,6 +628,7 @@ // eliminate the PHI Node. if (HasUniqueIncomingValue) { NewPN->replaceAllUsesWith(UniqueValue); + if (AA) AA->deleteValue(NewPN); BEBlock->getInstList().erase(NewPN); } } From natebegeman at mac.com Fri Mar 25 02:34:36 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 02:34:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200503250834.CAA24936@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.4 -> 1.5 --- Log message: Support global addresses and fix call returns. Varargs still aren't handled correctly for floating point arguments, or more than 8 arguemnts. This does however, allow hello world to run. --- Diffs of the changes: (+50 -6) PPC32ISelPattern.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 50 insertions(+), 6 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.4 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.5 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.4 Thu Mar 24 17:35:30 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Mar 25 02:34:25 2005 @@ -229,6 +229,7 @@ Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); break; case MVT::i32: + case MVT::i64: case MVT::f32: case MVT::f64: break; @@ -259,7 +260,23 @@ std::pair PPC32TargetLowering:: LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG) { - abort(); + MVT::ValueType ArgVT = getValueType(ArgTy); + SDOperand Result; + if (!isVANext) { + Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList); + } else { + unsigned Amt; + if (ArgVT == MVT::i32 || ArgVT == MVT::f32) + Amt = 4; + else { + assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && + "Other types should have been promoted for varargs!"); + Amt = 8; + } + Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, + DAG.getConstant(Amt, VAList.getValueType())); + } + return std::make_pair(Result, Chain); } @@ -284,11 +301,22 @@ /// vreg the value is produced in, so we only emit one copy of each compiled /// tree. std::map ExprMap; + + unsigned GlobalBaseReg; + bool GlobalBaseInitialized; public: ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) {} + /// runOnFunction - Override this function in order to reset our per-function + /// variables. + virtual bool runOnFunction(Function &Fn) { + // Make sure we re-emit a set of the global base reg if necessary + GlobalBaseInitialized = false; + return SelectionDAGISel::runOnFunction(Fn); + } + /// InstructionSelectBasicBlock - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { @@ -300,6 +328,7 @@ ExprMap.clear(); } + unsigned ISel::getGlobalBaseReg(); unsigned SelectExpr(SDOperand N); unsigned SelectExprFP(SDOperand N, unsigned Result); void Select(SDOperand N); @@ -340,6 +369,22 @@ } } +/// getGlobalBaseReg - Output the instructions required to put the +/// base address to use for accessing globals into a register. +/// +unsigned ISel::getGlobalBaseReg() { + if (!GlobalBaseInitialized) { + // Insert the set of GlobalBaseReg into the first MBB of the function + MachineBasicBlock &FirstMBB = BB->getParent()->front(); + MachineBasicBlock::iterator MBBI = FirstMBB.begin(); + GlobalBaseReg = MakeReg(MVT::i32); + BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR); + BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg).addReg(PPC::LR); + GlobalBaseInitialized = true; + } + return GlobalBaseReg; +} + //Check to see if the load is a constant offset from a base register void ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset) { @@ -510,9 +555,8 @@ case ISD::GlobalAddress: { GlobalValue *GV = cast(N)->getGlobal(); unsigned Tmp1 = MakeReg(MVT::i32); - // FIXME: R1 is incorrect, we need the getGlobalBaseReg() functionality - // from the simple isel - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(PPC::R1).addGlobalAddress(GV); + BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) + .addGlobalAddress(GV); if (GV->hasWeakLinkage() || GV->isExternal()) { BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1); } else { @@ -631,9 +675,9 @@ case MVT::i8: case MVT::i16: case MVT::i32: - BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3); + BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3); if (Node->getValueType(1) == MVT::i32) - BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4); + BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4).addReg(PPC::R4); break; case MVT::f32: case MVT::f64: From lattner at cs.uiuc.edu Fri Mar 25 09:36:35 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 25 Mar 2005 09:36:35 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll Message-ID: <200503251536.j2PFaZPO029554@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Analysis/DSGraph: 2005-03-24-Global-Arg-Alias.ll updated: 1.1 -> 1.2 --- Log message: fix the RUN line on this testcase so it passes. --- Diffs of the changes: (+1 -1) 2005-03-24-Global-Arg-Alias.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll diff -u llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll:1.1 llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll:1.2 --- llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll:1.1 Thu Mar 24 11:57:43 2005 +++ llvm/test/Regression/Analysis/DSGraph/2005-03-24-Global-Arg-Alias.ll Fri Mar 25 09:36:19 2005 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -ds-aa -load-vn -gcse | llvm-dis | grep 'load int* %L' +; RUN: llvm-as < %s | opt -ds-aa -load-vn -gcse | llvm-dis | grep 'load int\* %L' %G = internal global int* null From lattner at cs.uiuc.edu Fri Mar 25 10:45:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 25 Mar 2005 10:45:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Message-ID: <200503251645.j2PGjxHO003138@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.111 -> 1.112 --- Log message: Grow the EQ classes for globals at the end of the BU pass. This shrinks memory usage in the TD pass for 254.gap from 31.3MB to 3.9MB. --- Diffs of the changes: (+93 -0) BottomUpClosure.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 93 insertions(+) Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.111 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.112 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.111 Thu Mar 24 18:06:09 2005 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Fri Mar 25 10:45:43 2005 @@ -30,6 +30,88 @@ X("budatastructure", "Bottom-up Data Structure Analysis"); } +/// BuildGlobalECs - Look at all of the nodes in the globals graph. If any node +/// contains multiple globals, DSA will never, ever, be able to tell the globals +/// apart. Instead of maintaining this information in all of the graphs +/// throughout the entire program, store only a single global (the "leader") in +/// the graphs, and build equivalence classes for the rest of the globals. +static void BuildGlobalECs(DSGraph &GG, std::set &ECGlobals) { + DSScalarMap &SM = GG.getScalarMap(); + EquivalenceClasses &GlobalECs = SM.getGlobalECs(); + for (DSGraph::node_iterator I = GG.node_begin(), E = GG.node_end(); + I != E; ++I) { + if (I->getGlobalsList().size() <= 1) continue; + + // First, build up the equivalence set for this block of globals. + const std::vector &GVs = I->getGlobalsList(); + GlobalValue *First = GVs[0]; + for (unsigned i = 1, e = GVs.size(); i != e; ++i) + GlobalECs.unionSets(First, GVs[i]); + + // Next, get the leader element. + assert(First == GlobalECs.getLeaderValue(First) && + "First did not end up being the leader?"); + + // Next, remove all globals from the scalar map that are not the leader. + assert(GVs[0] == First && "First had to be at the front!"); + for (unsigned i = 1, e = GVs.size(); i != e; ++i) { + ECGlobals.insert(GVs[i]); + SM.erase(SM.find(GVs[i])); + } + + // Finally, change the global node to only contain the leader. + I->clearGlobals(); + I->addGlobal(First); + } + + DEBUG(GG.AssertGraphOK()); +} + +/// EliminateUsesOfECGlobals - Once we have determined that some globals are in +/// really just equivalent to some other globals, remove the globals from the +/// specified DSGraph (if present), and merge any nodes with their leader nodes. +static void EliminateUsesOfECGlobals(DSGraph &G, + const std::set &ECGlobals) { + DSScalarMap &SM = G.getScalarMap(); + EquivalenceClasses &GlobalECs = SM.getGlobalECs(); + + bool MadeChange = false; + for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end(); + GI != E; ) { + GlobalValue *GV = *GI++; + if (!ECGlobals.count(GV)) continue; + + const DSNodeHandle &GVNH = SM[GV]; + assert(!GVNH.isNull() && "Global has null NH!?"); + + // Okay, this global is in some equivalence class. Start by finding the + // leader of the class. + GlobalValue *Leader = GlobalECs.getLeaderValue(GV); + + // If the leader isn't already in the graph, insert it into the node + // corresponding to GV. + if (!SM.global_count(Leader)) { + GVNH.getNode()->addGlobal(Leader); + SM[Leader] = GVNH; + } else { + // Otherwise, the leader is in the graph, make sure the nodes are the + // merged in the specified graph. + const DSNodeHandle &LNH = SM[Leader]; + if (LNH.getNode() != GVNH.getNode()) + LNH.mergeWith(GVNH); + } + + // Next step, remove the global from the DSNode. + GVNH.getNode()->removeGlobal(GV); + + // Finally, remove the global from the ScalarMap. + SM.erase(GV); + MadeChange = true; + } + + DEBUG(if(MadeChange) G.AssertGraphOK()); +} + // run - Calculate the bottom up data structure graphs for each function in the // program. // @@ -85,6 +167,17 @@ // Mark external globals incomplete. GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals); + // Grow the equivalence classes for the globals to include anything that we + // now know to be aliased. + std::set ECGlobals; + BuildGlobalECs(*GlobalsGraph, ECGlobals); + if (!ECGlobals.empty()) { + DEBUG(std::cerr << "Eliminating " << ECGlobals.size() << " EC Globals!\n"); + for (hash_map::iterator I = DSInfo.begin(), + E = DSInfo.end(); I != E; ++I) + EliminateUsesOfECGlobals(*I->second, ECGlobals); + } + // Merge the globals variables (not the calls) from the globals graph back // into the main function's graph so that the main function contains all of // the information about global pools and GV usage in the program. From lattner at cs.uiuc.edu Fri Mar 25 14:28:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 25 Mar 2005 14:28:38 -0600 Subject: [llvm-commits] CVS: llvm-test/TEST.dsgraph.report Message-ID: <200503252028.j2PKScgB018103@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsgraph.report updated: 1.12 -> 1.13 --- Log message: update this to emit the happy latex code that I'm using in my thesis. --- Diffs of the changes: (+52 -46) TEST.dsgraph.report | 98 +++++++++++++++++++++++++++------------------------- 1 files changed, 52 insertions(+), 46 deletions(-) Index: llvm-test/TEST.dsgraph.report diff -u llvm-test/TEST.dsgraph.report:1.12 llvm-test/TEST.dsgraph.report:1.13 --- llvm-test/TEST.dsgraph.report:1.12 Tue Mar 22 23:39:15 2005 +++ llvm-test/TEST.dsgraph.report Fri Mar 25 14:28:21 2005 @@ -44,59 +44,65 @@ # For latex output, limit benchmarks and rename as appropriate @LatexRowMapOrder = ( - 'MultiSource/Olden/treeadd/treeadd' => 'Olden-treeadd', - 'MultiSource/Olden/bisort/bisort' => 'Olden-bisort', - 'MultiSource/Olden/mst/mst' => 'Olden-mst', - 'MultiSource/Olden/perimeter/perimeter' => 'Olden-perimeter', - 'MultiSource/Olden/health/health' => 'Olden-health', - 'MultiSource/Olden/tsp/tsp' => 'Olden-tsp', - 'MultiSource/Olden/power/power' => 'Olden-power', - 'MultiSource/Olden/em3d/em3d' => 'Olden-em3d', - 'MultiSource/Olden/voronoi/voronoi' => 'Olden-voronoi', - 'MultiSource/Olden/bh/bh' => 'Olden-bh', '-' => '-', - 'MultiSource/Ptrdist/anagram/anagram' => 'ptrdist-anagram', - 'MultiSource/Ptrdist/ks/ks' => 'ptrdist-ks', - 'MultiSource/Ptrdist/ft/ft' => 'ptrdist-ft', - 'MultiSource/Ptrdist/yacr2/yacr2' => 'ptrdist-yacr2', - 'MultiSource/Ptrdist/bc/bc' => 'ptrdist-bc', + + '181.mcf' => '181.mcf', + '256.bzip2' => '256.bzip2', + '164.gzip' => '164.gzip', + '175.vpr' => '175.vpr', + '197.parser' => '197.parser', + '186.crafty' => '186.crafty', + '300.twolf' => '300.twolf', + '255.vortex' => '255.vortex', + '254.gap' => '254.gap', + '252.eon' => '252.eon', + '253.perlbmk' => '253.perlbmk', + '176.gcc' => '176.gcc', + '-' => '-', + '179.art' => '179.art', + '183.equake' => '183.equake', + '171.swim' => '171.swim', + '172.mgrid' => '172.mgrid', + '168.wupwise' => '168.wupwise', + '173.applu' => '173.applu', + '188.ammp' => '188.ammp', + '177.mesa' => '177.mesa', + '-' => '-', + '129.compress' => '129.compress', + '130.li' => '130.li', + '124.m88ksim' => '124.m88ksim', + '132.ijpeg' => '132.ijpeg', + '099.go' => '099.go', + '134.perl' => '134.perl', + '147.vortex' => '147.vortex', + '126.gcc' => '126.gcc', '-' => '-', - 'External/SPEC/CFP2000/179.art/179.art' => '179.art', - 'External/SPEC/CFP2000/183.equake/183.equake' => '183.equake', - 'External/SPEC/CINT2000/181.mcf/181.mcf' => '181.mcf', - 'External/SPEC/CINT2000/256.bzip2/256.bzip2' => '256.bzip2', - 'External/SPEC/CINT2000/164.gzip/164.gzip' => '164.gzip', - 'External/SPEC/CINT2000/197.parser/197.parser' => '197.parser', - 'External/SPEC/CFP2000/188.ammp/188.ammp' => '188.ammp', - 'External/SPEC/CINT2000/175.vpr/175.vpr' => '175.vpr', - 'External/SPEC/CINT2000/300.twolf/300.twolf' => '300.twolf', - 'External/SPEC/CINT2000/186.crafty/186.crafty' => '186.crafty', - 'External/SPEC/CINT2000/255.vortex/255.vortex' => '255.vortex', - 'External/SPEC/CINT2000/254.gap/254.gap' => '254.gap', + '102.swim' => '102.swim', + '101.tomcatv' => '101.tomcatv', + '107.mgrid' => '107.mgrid', + '145.fpppp' => '145.fpppp', + '104.hydro2d' => '104.hydro2d', + '110.applu' => '110.applu', + '103.su2cor' => '103.su2cor', + '146.wave5' => '146.wave5', '-' => '-', - 'MultiSource/sgefa/sgefa' => 'sgefa', - 'MultiSource/sim/sim' => 'sim', - 'MultiSource/Burg/burg' => 'burg', - 'MultiSource/gnuchess/gnuchess' => 'gnuchess', - 'MultiSource/larn/larn' => 'larn', - 'MultiSource/flex/flex' => 'flex', - 'MultiSource/moria/moria' => 'moria', - 'MultiSource/povray31/povray31' => 'povray31' + 'fpgrowth' => 'fpgrowth', + 'bsim' => 'boxed-sim', + 'namd' => 'NAMD', + 'povray' => 'povray31', ); - at LatexColumns = (1, 27, 19, # LOC, #MemInstrs, MaxSCC - 4, 5, 6, 7, # Execution times - 11, # Memory BU - 12, # Memory TD - 16, 17, # Total, Max Nodes - 15); # NumFolded + at LatexColumns = (1, 2, 19, # LOC, #MemInstrs, MaxSCC + 15,16, # Total/Collapsed nodes + 17, 18); # Max Size, GG Size # Specify how to format columns nicely for printing... %LatexColumnFormat = ( - 11 => \&FormatSize, - 12 => \&FormatSize, - 15 => \&NoStar, - 16 => \&NoCallNodes +# 11 => \&FormatSize, +# 12 => \&FormatSize, + 16 => \&NoStar, + 15 => \&NoCallNodes, + 18 => \&NoCallNodes ); @Graphs = (["scatter", "timeVmem.txt", 27, 7], @@ -128,8 +134,8 @@ ["BUTDSz:" , sub { return SumCols(@_, 2); }], [], # Misc stuff - ["NumFold" , '([0-9]+).*Number of folded nodes '], ["NumNodes", 'Graphs contain \\[([0-9+]+)\\] nodes total'], + ["NumFold" , '([0-9]+).*Number of folded nodes '], ["MaxSz" , '([0-9]+).*Maximum graph size'], ["GlobGr" , '\\.GlobalsGraph\\.dot\'... \\[([0-9+]+)\\]'], ["MaxSCC" , '([0-9]+).*Maximum SCC Size in Call Graph'], From lattner at cs.uiuc.edu Fri Mar 25 14:37:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 25 Mar 2005 14:37:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Printer.cpp Message-ID: <200503252037.j2PKbi9R020669@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Printer.cpp updated: 1.79 -> 1.80 --- Log message: Don't count all of the nodes in the SCC once for each function in the SCC. --- Diffs of the changes: (+9 -4) Printer.cpp | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) Index: llvm/lib/Analysis/DataStructure/Printer.cpp diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.79 llvm/lib/Analysis/DataStructure/Printer.cpp:1.80 --- llvm/lib/Analysis/DataStructure/Printer.cpp:1.79 Sat Mar 19 20:40:11 2005 +++ llvm/lib/Analysis/DataStructure/Printer.cpp Fri Mar 25 14:37:32 2005 @@ -283,20 +283,25 @@ for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) if (C.hasGraph(*I)) { DSGraph &Gr = C.getDSGraph((Function&)*I); - TotalNumNodes += Gr.getGraphSize(); unsigned NumCalls = Gr.shouldPrintAuxCalls() ? Gr.getAuxFunctionCalls().size() : Gr.getFunctionCalls().size(); - TotalCallNodes += NumCalls; if (I->getName() == "main" || !OnlyPrintMain) { Function *SCCFn = Gr.retnodes_begin()->first; - if (&*I == SCCFn) + if (&*I == SCCFn) { + TotalNumNodes += Gr.getGraphSize(); + TotalCallNodes += NumCalls; + Gr.writeGraphToFile(O, Prefix+I->getName()); - else + } else { + // Don't double count node/call nodes. O << "Didn't write '" << Prefix+I->getName() << ".dot' - Graph already emitted to '" << Prefix+SCCFn->getName() << "\n"; + } } else { + TotalNumNodes += Gr.getGraphSize(); + TotalCallNodes += NumCalls; O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... [" << Gr.getGraphSize() << "+" << NumCalls << "]\n"; } From lattner at cs.uiuc.edu Fri Mar 25 14:55:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 25 Mar 2005 14:55:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Printer.cpp Message-ID: <200503252055.j2PKt1sw026446@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Printer.cpp updated: 1.80 -> 1.81 --- Log message: no really, don't double count these nodes either! --- Diffs of the changes: (+19 -14) Printer.cpp | 33 +++++++++++++++++++-------------- 1 files changed, 19 insertions(+), 14 deletions(-) Index: llvm/lib/Analysis/DataStructure/Printer.cpp diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.80 llvm/lib/Analysis/DataStructure/Printer.cpp:1.81 --- llvm/lib/Analysis/DataStructure/Printer.cpp:1.80 Fri Mar 25 14:37:32 2005 +++ llvm/lib/Analysis/DataStructure/Printer.cpp Fri Mar 25 14:54:45 2005 @@ -285,34 +285,39 @@ DSGraph &Gr = C.getDSGraph((Function&)*I); unsigned NumCalls = Gr.shouldPrintAuxCalls() ? Gr.getAuxFunctionCalls().size() : Gr.getFunctionCalls().size(); + bool IsDuplicateGraph = false; if (I->getName() == "main" || !OnlyPrintMain) { Function *SCCFn = Gr.retnodes_begin()->first; if (&*I == SCCFn) { - TotalNumNodes += Gr.getGraphSize(); - TotalCallNodes += NumCalls; - Gr.writeGraphToFile(O, Prefix+I->getName()); } else { - // Don't double count node/call nodes. + IsDuplicateGraph = true; // Don't double count node/call nodes. O << "Didn't write '" << Prefix+I->getName() << ".dot' - Graph already emitted to '" << Prefix+SCCFn->getName() << "\n"; } } else { - TotalNumNodes += Gr.getGraphSize(); - TotalCallNodes += NumCalls; - O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... [" - << Gr.getGraphSize() << "+" << NumCalls << "]\n"; + Function *SCCFn = Gr.retnodes_begin()->first; + if (&*I == SCCFn) { + O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... [" + << Gr.getGraphSize() << "+" << NumCalls << "]\n"; + } else { + IsDuplicateGraph = true; // Don't double count node/call nodes. + } } - unsigned GraphSize = Gr.getGraphSize(); - if (MaxGraphSize < GraphSize) MaxGraphSize = GraphSize; + if (!IsDuplicateGraph) { + unsigned GraphSize = Gr.getGraphSize(); + if (MaxGraphSize < GraphSize) MaxGraphSize = GraphSize; - for (DSGraph::node_iterator NI = Gr.node_begin(), E = Gr.node_end(); - NI != E; ++NI) - if (NI->isNodeCompletelyFolded()) - ++NumFoldedNodes; + TotalNumNodes += Gr.getGraphSize(); + TotalCallNodes += NumCalls; + for (DSGraph::node_iterator NI = Gr.node_begin(), E = Gr.node_end(); + NI != E; ++NI) + if (NI->isNodeCompletelyFolded()) + ++NumFoldedNodes; + } } DSGraph &GG = C.getGlobalsGraph(); From alkis at cs.uiuc.edu Fri Mar 25 17:44:44 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 17:44:44 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503252344.RAA32682@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.244 -> 1.245 --- Log message: Fix bug in previous commit. --- Diffs of the changes: (+1 -1) Compiler.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.244 llvm-java/lib/Compiler/Compiler.cpp:1.245 --- llvm-java/lib/Compiler/Compiler.cpp:1.244 Thu Mar 24 16:35:36 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Mar 25 17:44:33 2005 @@ -2184,7 +2184,7 @@ // java/lang/Object's. const Class& clazz = resolver_->getClass("[Ljava/lang/Object;"); const VTableInfo& vi = - getObjectArrayVTableInfo(clazz.getClassFile()); + getObjectArrayVTableInfo(clazz.getComponentClass()->getClassFile()); push(allocateArray(clazz, vi, count, currentBB_)); } From lattner at cs.uiuc.edu Tue Mar 22 17:55:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 22 Mar 2005 17:55:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200503222355.j2MNt8Z9016529@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.226 -> 1.227 --- Log message: Several changes here: 1. Increase max node size from 64->256 to avoid collapsing an important structure in 181.mcf 2. If we have multiple calls to an indirect call node with an indirect callee, fold these call nodes together, to avoid DSA turning apoc into a flaming fireball of death when analyzing 176.gcc. With this change, 176.gcc now takes ~7s to analyze for loc+bu+td, with 5.7s of that in the BU pass. --- Diffs of the changes: (+42 -19) DataStructure.cpp | 61 +++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 42 insertions(+), 19 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.226 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.227 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.226 Mon Mar 21 19:42:59 2005 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Tue Mar 22 17:54:52 2005 @@ -39,7 +39,7 @@ Statistic<> NumTrivialGlobalDNE("dsa", "Number of globals trivially removed"); }; -#if 1 +#if 0 #define TIME_REGION(VARNAME, DESC) \ NamedRegionTimer VARNAME(DESC) #else @@ -467,7 +467,7 @@ // collapse it. This can occur for fortran common blocks, which have stupid // things like { [100000000 x double], [1000000 x double] }. unsigned NumFields = (NewTySize+DS::PointerSize-1) >> DS::PointerShift; - if (NumFields > 64) { + if (NumFields > 256) { foldNodeCompletely(); return true; } @@ -509,7 +509,7 @@ // collapse it. This can occur for fortran common blocks, which have stupid // things like { [100000000 x double], [1000000 x double] }. unsigned NumFields = (NewTySize+DS::PointerSize-1) >> DS::PointerShift; - if (NumFields > 64) { + if (NumFields > 256) { foldNodeCompletely(); return true; } @@ -1574,22 +1574,20 @@ Edge.setTo(0, 0); // Kill the edge! } -#if 0 static inline bool nodeContainsExternalFunction(const DSNode *N) { - const std::vector &Globals = N->getGlobals(); - for (unsigned i = 0, e = Globals.size(); i != e; ++i) - if (Globals[i]->isExternal() && isa(Globals[i])) - return true; + std::vector Funcs; + N->addFullFunctionList(Funcs); + for (unsigned i = 0, e = Funcs.size(); i != e; ++i) + if (Funcs[i]->isExternal()) return true; return false; } -#endif static void removeIdenticalCalls(std::list &Calls) { // Remove trivially identical function calls Calls.sort(); // Sort by callee as primary key! // Scan the call list cleaning it up as necessary... - DSNode *LastCalleeNode = 0; + DSNodeHandle LastCalleeNode; Function *LastCalleeFunc = 0; unsigned NumDuplicateCalls = 0; bool LastCalleeContainsExternalFunction = false; @@ -1600,17 +1598,41 @@ DSCallSite &CS = *I; std::list::iterator OldIt = I++; - // If the Callee is a useless edge, this must be an unreachable call site, - // eliminate it. - if (CS.isIndirectCall() && CS.getCalleeNode()->getNumReferrers() == 1 && - CS.getCalleeNode()->isComplete() && - CS.getCalleeNode()->getGlobalsList().empty()) { // No useful info? + if (!CS.isIndirectCall()) { + LastCalleeNode = 0; + } else { + DSNode *Callee = CS.getCalleeNode(); + + // If the Callee is a useless edge, this must be an unreachable call site, + // eliminate it. + if (Callee->getNumReferrers() == 1 && Callee->isComplete() && + Callee->getGlobalsList().empty()) { // No useful info? #ifndef NDEBUG - std::cerr << "WARNING: Useless call site found.\n"; + std::cerr << "WARNING: Useless call site found.\n"; #endif - Calls.erase(OldIt); - ++NumDeleted; - continue; + Calls.erase(OldIt); + ++NumDeleted; + continue; + } + + // If the last call site in the list has the same callee as this one, and + // if the callee contains an external function, it will never be + // resolvable, just merge the call sites. + if (!LastCalleeNode.isNull() && LastCalleeNode.getNode() == Callee) { + LastCalleeContainsExternalFunction = + nodeContainsExternalFunction(Callee); + + std::list::iterator PrevIt = OldIt; + --PrevIt; + PrevIt->mergeWith(CS); + + // No need to keep this call anymore. + Calls.erase(OldIt); + ++NumDeleted; + continue; + } else { + LastCalleeNode = Callee; + } } // If the return value or any arguments point to a void node with no @@ -1676,6 +1698,7 @@ #endif if (I != Calls.end() && CS == *I) { + LastCalleeNode = 0; Calls.erase(OldIt); ++NumDeleted; continue; From alkis at cs.uiuc.edu Fri Mar 25 19:18:42 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 19:18:42 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503260118.TAA01179@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.245 -> 1.246 --- Log message: Allocate strings statically. --- Diffs of the changes: (+23 -25) Compiler.cpp | 48 +++++++++++++++++++++++------------------------- 1 files changed, 23 insertions(+), 25 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.245 llvm-java/lib/Compiler/Compiler.cpp:1.246 --- llvm-java/lib/Compiler/Compiler.cpp:1.245 Fri Mar 25 17:44:33 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Mar 25 19:18:31 2005 @@ -156,7 +156,8 @@ } template - Value* createNewString(const std::string& str, InsertionPointTy* ip) { + GlobalVariable* createNewString(const std::string& str, + InsertionPointTy* ip) { // Create a new byte[] object and initialize it with the // contents of this string constant. Value* count = ConstantUInt::get(Type::UIntTy, str.size()); @@ -190,12 +191,22 @@ new CallInst(memcpy_, params, "", ip); // Get class information for java/lang/String. - const ClassFile* cf = ClassFile::get("java/lang/String"); const Class& ci = resolver_->getClass("java/lang/String"); - const VTableInfo& vi = getVTableInfo(cf); + const VTableInfo& vi = getVTableInfo(ci.getClassFile()); - // Create a new java/lang/String object. - Value* objRef = allocateObject(ci, vi, ip); + // Create a zeroinitialized static java/lang/String object. + GlobalVariable* globalString = + new GlobalVariable(ci.getStructType(), + false, + GlobalVariable::LinkOnceLinkage, + llvm::Constant::getNullValue(ci.getStructType()), + str + ".java/lang/String", + &module_); + // Install the vtable pointer. + Value* objBase = + new CastInst(globalString, resolver_->getObjectBaseRefType(), TMP, ip); + Value* vtable = new CastInst(vi.vtable, VTableBaseRefTy, TMP, ip); + new CallInst(setVtable_, objBase, vtable, "", ip); // Initialize it: call java/lang/String/(byte[],int) Method* method = getMethod("java/lang/String/([BI)V"); @@ -204,31 +215,18 @@ params.reserve(3); params.clear(); - params.push_back(new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, ip)); + params.push_back(objBase); params.push_back(new CastInst(arrayRef, resolver_->getObjectBaseRefType(), TMP, ip)); params.push_back(ConstantSInt::get(Type::IntTy, 0)); new CallInst(function, params, "", ip); - return objRef; + return globalString; } - Value* getConstantString(ConstantString* s) { + GlobalVariable* getConstantString(ConstantString* s) { const std::string& str = s->getValue()->str(); StringMap::iterator it = stringMap_.find(str); if (it == stringMap_.end()) { - // Create the global variable for the string. - const Class& stringClass = resolver_->getClass("java/lang/String"); - GlobalVariable* stringGlobal = new GlobalVariable( - stringClass.getType(), - false, - GlobalVariable::ExternalLinkage, - llvm::Constant::getNullValue(stringClass.getType()), - str + ".java/lang/String", - &module_); - - // Insert this new string into the map. - it = stringMap_.insert(it, std::make_pair(str, stringGlobal)); - // Get the static initializer function and get its one and // only basic block to add code to. Function* hook = module_.getOrInsertFunction(LLVM_JAVA_STATIC_INIT, @@ -236,13 +234,13 @@ Instruction* I = hook->front().getTerminator(); assert(I && LLVM_JAVA_STATIC_INIT " should have a terminator!"); - Value* newString = createNewString(str, I); + GlobalVariable* stringGlobal = createNewString(str, I); - // Store the string reference to the global variable. - new StoreInst(newString, stringGlobal, I); + // Insert this new string into the map. + it = stringMap_.insert(it, std::make_pair(str, stringGlobal)); } - return new LoadInst(it->second, TMP, currentBB_); + return it->second; } /// Given a llvm::Java::Constant returns a Value From natebegeman at mac.com Fri Mar 25 19:28:16 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 19:28:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Message-ID: <200503260128.TAA01267@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelSimple.cpp updated: 1.128 -> 1.129 --- Log message: Correct a documention link --- Diffs of the changes: (+2 -2) PPC32ISelSimple.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.128 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.129 --- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.128 Thu Mar 24 17:34:38 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp Fri Mar 25 19:28:05 2005 @@ -1628,7 +1628,7 @@ /// it inserts the specified CallMI instruction into the stream. /// /// FIXME: See Documentation at the following URL for "correct" behavior -/// +/// void PPC32ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI, const std::vector &Args, bool isVarArg) { // Count how many bytes are to be pushed on the stack, including the linkage @@ -1656,7 +1656,7 @@ if (NumBytes < 56) NumBytes = 56; // Adjust the stack pointer for the new arguments... - // These functions are automatically eliminated by the prolog/epilog pass + // These operations are automatically eliminated by the prolog/epilog pass BuildMI(BB, PPC::ADJCALLSTACKDOWN, 1).addImm(NumBytes); // Arguments go on the stack in reverse order, as specified by the ABI. From natebegeman at mac.com Fri Mar 25 19:29:04 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 19:29:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200503260129.TAA01280@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.5 -> 1.6 --- Log message: Next round of pattern isel changes, mostly dealing with calls. --- Diffs of the changes: (+139 -31) PPC32ISelPattern.cpp | 170 +++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 139 insertions(+), 31 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.5 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.6 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.5 Fri Mar 25 02:34:25 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Mar 25 19:28:53 2005 @@ -58,8 +58,8 @@ /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG); + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); virtual std::pair LowerVAStart(SDOperand Chain, SelectionDAG &DAG); @@ -206,35 +206,136 @@ std::pair PPC32TargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { - // FIXME - int NumBytes = 56; - - Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); + const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { + // args_to_use will accumulate outgoing args for the ISD::CALL case in + // SelectExpr to use to put the arguments in the appropriate registers. std::vector args_to_use; - for (unsigned i = 0, e = Args.size(); i != e; ++i) - { - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - // Promote the integer to 32 bits. If the input type is signed use a - // sign extend, otherwise use a zero extend. - if (Args[i].second->isSigned()) - Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); - else - Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); - break; - case MVT::i32: - case MVT::i64: - case MVT::f32: - case MVT::f64: - break; + + // Count how many bytes are to be pushed on the stack, including the linkage + // area, and parameter passing area. + unsigned NumBytes = 24; + + if (Args.empty()) { + NumBytes = 0; // Save zero bytes. + } else { + for (unsigned i = 0, e = Args.size(); i != e; ++i) + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unknown value type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::f32: + NumBytes += 4; + break; + case MVT::i64: + case MVT::f64: + NumBytes += 8; + break; + } + + // Just to be safe, we'll always reserve the full 24 bytes of linkage area + // plus 32 bytes of argument space in case any called code gets funky on us. + if (NumBytes < 56) NumBytes = 56; + + // Adjust the stack pointer for the new arguments... + // These operations are automatically eliminated by the prolog/epilog pass + Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + + // Set up a copy of the stack pointer for use loading and storing any + // arguments that may not fit in the registers available for argument + // passing. + SDOperand StackPtr = DAG.getCopyFromReg(PPC::R1, MVT::i32, + DAG.getEntryNode()); + + // Figure out which arguments are going to go in registers, and which in + // memory. Also, if this is a vararg function, floating point operations + // must be stored to our stack, and loaded into integer regs as well, if + // any integer regs are available for argument passing. + unsigned ArgOffset = 24; + unsigned GPR_remaining = 8; + unsigned FPR_remaining = 13; + std::vector Stores; + for (unsigned i = 0, e = Args.size(); i != e; ++i) { + // PtrOff will be used to store the current argument to the stack if a + // register cannot be found for it. + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + // Promote the integer to 32 bits. If the input type is signed use a + // sign extend, otherwise use a zero extend. + if (Args[i].second->isSigned()) + Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); + else + Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); + // FALL THROUGH + case MVT::i32: + if (GPR_remaining > 0) { + args_to_use.push_back(Args[i].first); + --GPR_remaining; + } else { + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); + } + ArgOffset += 4; + break; + case MVT::i64: + // If we have 2 or more GPRs, we won't do anything and let the ISD::CALL + // functionality in SelectExpr move pieces for us. + if (GPR_remaining > 1) { + args_to_use.push_back(Args[i].first); + GPR_remaining -= 2; + } else if (GPR_remaining > 0) { + args_to_use.push_back(Args[i].first); + SDOperand LowPart = + DAG.getNode(ISD::TRUNCATE, MVT::i32, Args[i].first); + SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + LowPart, PtrOff)); + --GPR_remaining; + } else { + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); + } + ArgOffset += 8; + break; + case MVT::f32: + if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) { + --FPR_remaining; + ArgOffset += 4; + } else if (FPR_remaining > 0) { + --FPR_remaining; + if (GPR_remaining > 0) --GPR_remaining; + } else { + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); + } + ArgOffset += 4; + break; + case MVT::f64: + if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) { + --FPR_remaining; + } else if (FPR_remaining > 0) { + --FPR_remaining; + if (GPR_remaining > 0) --GPR_remaining; + if (GPR_remaining > 0) --GPR_remaining; + } else { + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); + } + ArgOffset += 8; + break; + } } - args_to_use.push_back(Args[i].first); + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); } std::vector RetVals; @@ -364,6 +465,9 @@ if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; } if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; } break; + case ISD::MUL: + if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; } + break; } return 0; } @@ -813,8 +917,12 @@ case ISD::MUL: assert (DestType == MVT::i32 && "Only do arithmetic on i32s!"); Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp2).addReg(Tmp1); + if (1 == canUseAsImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) + BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2); + else { + Tmp2 = SelectExpr(N.getOperand(1)); + BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp1).addReg(Tmp2); + } return Result; case ISD::ADD_PARTS: From natebegeman at mac.com Fri Mar 25 19:29:35 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 19:29:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelPattern.cpp Message-ID: <200503260129.TAA01307@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelPattern.cpp updated: 1.4 -> 1.5 --- Log message: Change interface to LowerCallTo to take a boolean isVarArg argument. --- Diffs of the changes: (+4 -4) IA64ISelPattern.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.4 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.5 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.4 Wed Mar 23 22:39:54 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Fri Mar 25 19:29:23 2005 @@ -97,8 +97,8 @@ /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG); + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); virtual std::pair LowerVAStart(SDOperand Chain, SelectionDAG &DAG); @@ -248,8 +248,8 @@ std::pair IA64TargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { + const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { MachineFunction &MF = DAG.getMachineFunction(); From natebegeman at mac.com Fri Mar 25 19:29:35 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 19:29:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelPattern.cpp Message-ID: <200503260129.TAA01311@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelPattern.cpp updated: 1.67 -> 1.68 --- Log message: Change interface to LowerCallTo to take a boolean isVarArg argument. --- Diffs of the changes: (+4 -4) AlphaISelPattern.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.67 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.68 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.67 Wed Mar 23 22:39:54 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Fri Mar 25 19:29:23 2005 @@ -82,8 +82,8 @@ /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG); + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); virtual std::pair LowerVAStart(SDOperand Chain, SelectionDAG &DAG); @@ -210,8 +210,8 @@ std::pair AlphaTargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { + const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { int NumBytes = 0; if (Args.size() > 6) NumBytes = (Args.size() - 6) * 8; From natebegeman at mac.com Fri Mar 25 19:29:35 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 19:29:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200503260129.TAA01313@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.93 -> 1.94 --- Log message: Change interface to LowerCallTo to take a boolean isVarArg argument. --- Diffs of the changes: (+4 -4) X86ISelPattern.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.93 llvm/lib/Target/X86/X86ISelPattern.cpp:1.94 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.93 Wed Mar 23 22:39:54 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Fri Mar 25 19:29:23 2005 @@ -84,8 +84,8 @@ /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG); + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); virtual std::pair LowerVAStart(SDOperand Chain, SelectionDAG &DAG); @@ -163,8 +163,8 @@ std::pair X86TargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { + const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { // Count how many bytes are to be pushed on the stack. unsigned NumBytes = 0; From natebegeman at mac.com Fri Mar 25 19:29:35 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 19:29:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAGISel.cpp Message-ID: <200503260129.TAA01321@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.61 -> 1.62 SelectionDAGISel.cpp updated: 1.33 -> 1.34 --- Log message: Change interface to LowerCallTo to take a boolean isVarArg argument. --- Diffs of the changes: (+9 -6) LegalizeDAG.cpp | 6 +++--- SelectionDAGISel.cpp | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.61 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.62 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.61 Tue Feb 22 01:23:39 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Mar 25 19:29:23 2005 @@ -786,7 +786,7 @@ assert(0 && "Unknown op!"); } std::pair CallResult = - TLI.LowerCallTo(Tmp1, Type::VoidTy, + TLI.LowerCallTo(Tmp1, Type::VoidTy, false, DAG.getExternalSymbol(FnName, IntPtr), Args, DAG); Result = LegalizeOp(CallResult.second); break; @@ -1473,7 +1473,7 @@ // node as our input and ignore the output chain. This allows us to place // calls wherever we need them to satisfy data dependences. const Type *RetTy = MVT::getTypeForValueType(Node->getValueType(0)); - SDOperand Result = TLI.LowerCallTo(InChain, RetTy, Callee, + SDOperand Result = TLI.LowerCallTo(InChain, RetTy, false, Callee, Args, DAG).first; switch (getTypeAction(Result.getValueType())) { default: assert(0 && "Unknown thing"); @@ -1527,7 +1527,7 @@ // node as our input and ignore the output chain. This allows us to place // calls wherever we need them to satisfy data dependences. const Type *RetTy = MVT::getTypeForValueType(DestTy); - return TLI.LowerCallTo(InChain, RetTy, Callee, Args, DAG).first; + return TLI.LowerCallTo(InChain, RetTy, false, Callee, Args, DAG).first; } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.33 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.34 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.33 Mon Mar 14 22:54:19 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Mar 25 19:29:23 2005 @@ -670,8 +670,11 @@ Args.push_back(std::make_pair(ArgNode, Arg->getType())); } + const PointerType *PT = cast(I.getCalledValue()->getType()); + const FunctionType *FTy = cast(PT->getElementType()); + std::pair Result = - TLI.LowerCallTo(getRoot(), I.getType(), Callee, Args, DAG); + TLI.LowerCallTo(getRoot(), I.getType(), FTy->isVarArg(), Callee, Args, DAG); if (I.getType() != Type::VoidTy) setValue(&I, Result.first); DAG.setRoot(Result.second); @@ -696,7 +699,7 @@ Args.push_back(std::make_pair(Src, TLI.getTargetData().getIntPtrType())); std::pair Result = - TLI.LowerCallTo(getRoot(), I.getType(), + TLI.LowerCallTo(getRoot(), I.getType(), false, DAG.getExternalSymbol("malloc", IntPtr), Args, DAG); setValue(&I, Result.first); // Pointers always fit in registers @@ -709,7 +712,7 @@ TLI.getTargetData().getIntPtrType())); MVT::ValueType IntPtr = TLI.getPointerTy(); std::pair Result = - TLI.LowerCallTo(getRoot(), Type::VoidTy, + TLI.LowerCallTo(getRoot(), Type::VoidTy, false, DAG.getExternalSymbol("free", IntPtr), Args, DAG); DAG.setRoot(Result.second); } From natebegeman at mac.com Fri Mar 25 19:30:42 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 19:30:42 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200503260130.TAA01350@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.7 -> 1.8 --- Log message: Change LowerCallTo to take a boolean isVarArg argument. This is needed by the PowerPC backend, and probably others in the future. --- Diffs of the changes: (+2 -3) TargetLowering.h | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.7 llvm/include/llvm/Target/TargetLowering.h:1.8 --- llvm/include/llvm/Target/TargetLowering.h:1.7 Tue Jan 18 21:36:03 2005 +++ llvm/include/llvm/Target/TargetLowering.h Fri Mar 25 19:30:30 2005 @@ -234,10 +234,9 @@ /// element is the outgoing token chain. typedef std::vector > ArgListTy; virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) = 0; + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) = 0; - /// LowerVAStart - This lowers the llvm.va_start intrinsic. If not /// implemented, this method prints a message and aborts. virtual std::pair From alkis at cs.uiuc.edu Fri Mar 25 19:42:50 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 19:42:50 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503260142.TAA01393@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.246 -> 1.247 --- Log message: Now getConstant returns an llvm::Constant. --- Diffs of the changes: (+2 -3) Compiler.cpp | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.246 llvm-java/lib/Compiler/Compiler.cpp:1.247 --- llvm-java/lib/Compiler/Compiler.cpp:1.246 Fri Mar 25 19:18:31 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Mar 25 19:42:38 2005 @@ -243,9 +243,8 @@ return it->second; } - /// Given a llvm::Java::Constant returns a Value - /// (java/lang/Strings are not llvm::Constants). - Value* getConstant(Constant* c) { + /// Given a llvm::Java::Constant returns an llvm::Constant. + llvm::Constant* getConstant(Constant* c) { if (ConstantString* s = dynamic_cast(c)) return getConstantString(s); else if (ConstantInteger* i = dynamic_cast(c)) From alkis at cs.uiuc.edu Fri Mar 25 20:04:37 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 20:04:37 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/ArrayCopyOverlap.java Message-ID: <200503260204.UAA01708@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: ArrayCopyOverlap.java added (r1.1) --- Log message: Add new failing testcase. --- Diffs of the changes: (+18 -0) ArrayCopyOverlap.java | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+) Index: llvm-java/test/Programs/SingleSource/UnitTests/ArrayCopyOverlap.java diff -c /dev/null llvm-java/test/Programs/SingleSource/UnitTests/ArrayCopyOverlap.java:1.1 *** /dev/null Fri Mar 25 20:04:35 2005 --- llvm-java/test/Programs/SingleSource/UnitTests/ArrayCopyOverlap.java Fri Mar 25 20:04:25 2005 *************** *** 0 **** --- 1,18 ---- + import java.util.*; + + public class ArrayCopyOverlap + { + public static Random rand = new Random(0); + + public static void main(String[] args) { + byte[] array = new byte[100]; + + for (int i = 0; i < array.length; ++i) { + array[i] = (byte) rand.nextInt(); + } + + System.arraycopy(array, 0, array, 23, 59); + + Util.printlnElements(array); + } + } From lattner at cs.uiuc.edu Fri Mar 25 20:05:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 25 Mar 2005 20:05:01 -0600 Subject: [llvm-commits] CVS: llvm-test/TEST.dsgraph.Makefile TEST.dsgraph.report Message-ID: <200503260205.j2Q250rL027035@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsgraph.Makefile updated: 1.16 -> 1.17 TEST.dsgraph.report updated: 1.13 -> 1.14 --- Log message: Add information about type safety --- Diffs of the changes: (+26 -1) TEST.dsgraph.Makefile | 4 ++++ TEST.dsgraph.report | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) Index: llvm-test/TEST.dsgraph.Makefile diff -u llvm-test/TEST.dsgraph.Makefile:1.16 llvm-test/TEST.dsgraph.Makefile:1.17 --- llvm-test/TEST.dsgraph.Makefile:1.16 Mon Mar 21 22:07:44 2005 +++ llvm-test/TEST.dsgraph.Makefile Fri Mar 25 20:04:44 2005 @@ -39,6 +39,10 @@ - at grep 'td.GlobalsGraph.dot' $@.time.1 >> $@ @echo -n "SCCSIZE: " >> $@ - at grep 'Maximum SCC Size in Call Graph' $@.time.1 >> $@ + @echo -n "ACCESSES TYPED: " >> $@ + - at grep 'Number of loads/stores which are fully typed' $@.time.1 >> $@ + @echo -n "ACCESSES UNTYPED: " >> $@ + - at grep 'Number of loads/stores which are untyped' $@.time.1 >> $@ @# Emit timing data. @echo -n "TIME: " >> $@ - at grep ' Local Data Structure' $@.time.1 >> $@ Index: llvm-test/TEST.dsgraph.report diff -u llvm-test/TEST.dsgraph.report:1.13 llvm-test/TEST.dsgraph.report:1.14 --- llvm-test/TEST.dsgraph.report:1.13 Fri Mar 25 14:28:21 2005 +++ llvm-test/TEST.dsgraph.report Fri Mar 25 20:04:44 2005 @@ -21,6 +21,20 @@ } } +sub TypeSafeRatio { + my ($Cols, $Col) = @_; + my $TS = $Cols->[$Col-2]; + my $NTS = $Cols->[$Col-1]; + $TS = 0 if ($TS eq "*"); + $NTS = 0 if ($NTS eq "*"); + + if ($TS + NTS != 0) { + return sprintf("%4.1f%%", 100*$TS/($TS+$NTS+0.0)); + } else { + return "n/a"; + } +} + sub FormatSize { my $Size = shift; if ($Size > 10*1024*1024) { @@ -92,10 +106,13 @@ 'povray' => 'povray31', ); - at LatexColumns = (1, 2, 19, # LOC, #MemInstrs, MaxSCC + at LxxatexColumns = (1, 2, 19, # LOC, #MemInstrs, MaxSCC 15,16, # Total/Collapsed nodes 17, 18); # Max Size, GG Size + at LatexColumns = (2, 21, 22, 23); # Type safety numbers + + # Specify how to format columns nicely for printing... %LatexColumnFormat = ( # 11 => \&FormatSize, @@ -139,5 +156,9 @@ ["MaxSz" , '([0-9]+).*Maximum graph size'], ["GlobGr" , '\\.GlobalsGraph\\.dot\'... \\[([0-9+]+)\\]'], ["MaxSCC" , '([0-9]+).*Maximum SCC Size in Call Graph'], + [], + ["TypeSafe", "ACCESSES TYPED: *([0-9]+)"], + ["NonType", "ACCESSES UNTYPED: *([0-9]+)"], + ["TS %" , sub { return TypeSafeRatio(@_); }], [] ); From natebegeman at mac.com Fri Mar 25 20:17:56 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 25 Mar 2005 20:17:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200503260217.UAA01968@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.6 -> 1.7 --- Log message: Make 64bit args and float args work correct with calls. Thanks to Chris for explaining EXTRACT_ELEMENT to me. --- Diffs of the changes: (+28 -10) PPC32ISelPattern.cpp | 38 ++++++++++++++++++++++++++++---------- 1 files changed, 28 insertions(+), 10 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.6 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.7 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.6 Fri Mar 25 19:28:53 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Fri Mar 25 20:17:46 2005 @@ -290,16 +290,23 @@ // If we have 2 or more GPRs, we won't do anything and let the ISD::CALL // functionality in SelectExpr move pieces for us. if (GPR_remaining > 1) { - args_to_use.push_back(Args[i].first); + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(1, MVT::i32)); + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(0, MVT::i32)); + args_to_use.push_back(Hi); + args_to_use.push_back(Lo); GPR_remaining -= 2; } else if (GPR_remaining > 0) { - args_to_use.push_back(Args[i].first); - SDOperand LowPart = - DAG.getNode(ISD::TRUNCATE, MVT::i32, Args[i].first); + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(1, MVT::i32)); + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(0, MVT::i32)); + args_to_use.push_back(Hi); SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - LowPart, PtrOff)); + Lo, PtrOff)); --GPR_remaining; } else { Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, @@ -312,6 +319,7 @@ --FPR_remaining; ArgOffset += 4; } else if (FPR_remaining > 0) { + args_to_use.push_back(Args[i].first); --FPR_remaining; if (GPR_remaining > 0) --GPR_remaining; } else { @@ -324,6 +332,7 @@ if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) { --FPR_remaining; } else if (FPR_remaining > 0) { + args_to_use.push_back(Args[i].first); --FPR_remaining; if (GPR_remaining > 0) --GPR_remaining; if (GPR_remaining > 0) --GPR_remaining; @@ -546,9 +555,11 @@ return Result; case ISD::CopyFromReg: - // FIXME: Handle copy from physregs! - // Just use the specified register as our input. - return dyn_cast(Node)->getReg(); + if (Result == 1) + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + Tmp1 = dyn_cast(Node)->getReg(); + BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1); + return Result; case ISD::LOAD: case ISD::EXTLOAD: @@ -749,13 +760,20 @@ case MVT::f64: if (FPR_remaining > 0) { BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(VRegs[i]); + ++FPR_idx; --FPR_remaining; } break; } // All arguments consume GPRs available for argument passing - if (GPR_remaining > 0) --GPR_remaining; - if (MVT::f64 == OperandType && GPR_remaining > 0) --GPR_remaining; + if (GPR_remaining > 0) { + ++GPR_idx; + --GPR_remaining; + } + if (MVT::f64 == OperandType && GPR_remaining > 0) { + ++GPR_idx; + --GPR_remaining; + } } // Emit the correct call instruction based on the type of symbol called. From alkis at cs.uiuc.edu Fri Mar 25 20:40:59 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 20:40:59 -0600 Subject: [llvm-commits] CVS: llvm-java/runtime/runtime.c Message-ID: <200503260240.UAA02162@zion.cs.uiuc.edu> Changes in directory llvm-java/runtime: runtime.c updated: 1.21 -> 1.22 --- Log message: Fix ArrayCopyOverlap. --- Diffs of the changes: (+8 -1) runtime.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletion(-) Index: llvm-java/runtime/runtime.c diff -u llvm-java/runtime/runtime.c:1.21 llvm-java/runtime/runtime.c:1.22 --- llvm-java/runtime/runtime.c:1.21 Tue Mar 15 19:11:05 2005 +++ llvm-java/runtime/runtime.c Fri Mar 25 20:40:48 2005 @@ -367,10 +367,12 @@ jint length) { struct llvm_java_bytearray* srcArray = (struct llvm_java_bytearray*) srcObj; struct llvm_java_bytearray* dstArray = (struct llvm_java_bytearray*) dstObj; + unsigned nbytes = length * srcObj->vtable->typeinfo.elementSize; jbyte* src = srcArray->data; jbyte* dst = dstArray->data; + // FIXME: Need to perform a proper type check here. if (srcObj->vtable->typeinfo.elementSize != dstObj->vtable->typeinfo.elementSize) llvm_java_throw(NULL); @@ -378,7 +380,12 @@ src += srcStart * srcObj->vtable->typeinfo.elementSize; dst += dstStart * dstObj->vtable->typeinfo.elementSize; - memcpy(dst, src, length * srcObj->vtable->typeinfo.elementSize); + // If arrays do not overlap use memcpy. + if ((dst > src ? dst - src : src - dst) > nbytes) + memcpy(dst, src, nbytes); + // If arrays overlap use memmove. + else + memmove(dst, src, nbytes); } void Java_gnu_classpath_VMSystemProperties_preInit(JNIEnv *env, jobject clazz, From alkis at cs.uiuc.edu Fri Mar 25 20:42:32 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 20:42:32 -0600 Subject: [llvm-commits] CVS: llvm-java/test/Programs/SingleSource/UnitTests/FieldAccess.java Message-ID: <200503260242.UAA02187@zion.cs.uiuc.edu> Changes in directory llvm-java/test/Programs/SingleSource/UnitTests: FieldAccess.java updated: 1.6 -> 1.7 --- Log message: Make test a bit more interesting. --- Diffs of the changes: (+4 -4) FieldAccess.java | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm-java/test/Programs/SingleSource/UnitTests/FieldAccess.java diff -u llvm-java/test/Programs/SingleSource/UnitTests/FieldAccess.java:1.6 llvm-java/test/Programs/SingleSource/UnitTests/FieldAccess.java:1.7 --- llvm-java/test/Programs/SingleSource/UnitTests/FieldAccess.java:1.6 Sat Dec 11 17:31:49 2004 +++ llvm-java/test/Programs/SingleSource/UnitTests/FieldAccess.java Fri Mar 25 20:42:22 2005 @@ -1,13 +1,13 @@ public class FieldAccess { private static class Base { - int i; - float f; + int i = 1; + float f = 1.0F; } private static class Derived extends Base { - int i; - double d; + int i = -1; + double d = -1.0; } public static void main(String[] args) { From alkis at cs.uiuc.edu Fri Mar 25 20:51:07 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 20:51:07 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.cpp Class.h Class.cpp Message-ID: <200503260251.UAA02244@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.cpp updated: 1.1 -> 1.2 Class.h updated: 1.3 -> 1.4 Class.cpp updated: 1.3 -> 1.4 --- Log message: Function renaming and debug output change. No functional changes. --- Diffs of the changes: (+15 -12) Class.cpp | 4 ++-- Class.h | 15 +++++++++------ Resolver.cpp | 8 ++++---- 3 files changed, 15 insertions(+), 12 deletions(-) Index: llvm-java/lib/Compiler/Resolver.cpp diff -u llvm-java/lib/Compiler/Resolver.cpp:1.1 llvm-java/lib/Compiler/Resolver.cpp:1.2 --- llvm-java/lib/Compiler/Resolver.cpp:1.1 Wed Mar 23 22:47:47 2005 +++ llvm-java/lib/Compiler/Resolver.cpp Fri Mar 25 20:50:56 2005 @@ -92,7 +92,7 @@ { ClassMap::iterator it = classMap_.lower_bound(descriptor); if (it == classMap_.end() || it->first != descriptor) { - DEBUG(std::cerr << "Building Class for: " << descriptor << '\n'); + DEBUG(std::cerr << "Loading class: " << descriptor << '\n'); // Insert dummy class to the map. it = classMap_.insert(it, std::make_pair(descriptor, Class(*this))); switch (descriptor[0]) { @@ -110,12 +110,12 @@ case 'L': { unsigned pos = descriptor.find(';', 1); const std::string& className = descriptor.substr(1, pos - 1); - it->second.buildClass(className); + it->second.loadClass(className); break; } case '[': { const std::string& componentDescriptor = descriptor.substr(1); - it->second.buildArrayClass(getClassForDesc(componentDescriptor)); + it->second.loadArrayClass(getClassForDesc(componentDescriptor)); break; } default: @@ -123,7 +123,7 @@ abort(); } module_.addTypeName(descriptor, it->second.getStructType()); - DEBUG(std::cerr << "Built Class for: " << descriptor << '\n'); + DEBUG(std::cerr << "Loaded class: " << descriptor << '\n'); } return it->second; Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.3 llvm-java/lib/Compiler/Class.h:1.4 --- llvm-java/lib/Compiler/Class.h:1.3 Thu Mar 24 16:35:36 2005 +++ llvm-java/lib/Compiler/Class.h Fri Mar 25 20:50:56 2005 @@ -43,18 +43,21 @@ void addField(const std::string& name, const Type* type); void resolveType(); - // Creates a dummy class. - explicit Class(Resolver& resolver); - // Creates primitive class for type. Class(Resolver& resolver, const Type* type); + friend class Resolver; + + // Resolver interface. + + // Creates a dummy class. + explicit Class(Resolver& resolver); + // Builds the class object for the named class. - void buildClass(const std::string& className); + void loadClass(const std::string& className); // Builds the array class object of component type componentClass. - void buildArrayClass(const Class& componentClass); + void loadArrayClass(const Class& componentClass); - friend class Resolver; public: const Type* getStructType() const { return structType_; } Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.3 llvm-java/lib/Compiler/Class.cpp:1.4 --- llvm-java/lib/Compiler/Class.cpp:1.3 Thu Mar 24 16:35:36 2005 +++ llvm-java/lib/Compiler/Class.cpp Fri Mar 25 20:50:56 2005 @@ -68,7 +68,7 @@ type_ = PointerType::get(structType_); } -void Class::buildClass(const std::string& className) +void Class::loadClass(const std::string& className) { classFile_ = ClassFile::get(className); @@ -107,7 +107,7 @@ assert(!isa(getStructType()) &&"Class not initialized properly!"); } -void Class::buildArrayClass(const Class& componentClass) +void Class::loadArrayClass(const Class& componentClass) { superClass_ = &resolver_->getClass("java/lang/Object"); componentClass_ = &componentClass; From alkis at cs.uiuc.edu Fri Mar 25 20:56:25 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 20:56:25 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.h Message-ID: <200503260256.UAA02281@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.h updated: 1.1 -> 1.2 --- Log message: Remove left over declaration. --- Diffs of the changes: (+0 -1) Resolver.h | 1 - 1 files changed, 1 deletion(-) Index: llvm-java/lib/Compiler/Resolver.h diff -u llvm-java/lib/Compiler/Resolver.h:1.1 llvm-java/lib/Compiler/Resolver.h:1.2 --- llvm-java/lib/Compiler/Resolver.h:1.1 Wed Mar 23 22:47:47 2005 +++ llvm-java/lib/Compiler/Resolver.h Fri Mar 25 20:56:14 2005 @@ -45,7 +45,6 @@ const Type* getObjectBaseType() const { return objectBaseType_; } const Type* getObjectBaseRefType() const { return objectBaseRefType_; } - const Class& getFieldClass(const std::string& descriptor); const Type* getType(const std::string& descriptor, bool memberMethod = false) const; const Type* getStorageType(const Type* type) const; From alkis at cs.uiuc.edu Fri Mar 25 22:32:18 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 22:32:18 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.cpp Class.h Class.cpp Message-ID: <200503260432.WAA02779@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.cpp updated: 1.2 -> 1.3 Class.h updated: 1.4 -> 1.5 Class.cpp updated: 1.4 -> 1.5 --- Log message: Change class interface a bit to model a jvm better in terms of classloading. Classloading involves three phases: load, link, initialize. Class resolution can be performed anywhere between link and use of the to be resolved reference. --- Diffs of the changes: (+74 -57) Class.cpp | 96 ++++++++++++++++++++++++++++++++--------------------------- Class.h | 24 ++++++++------ Resolver.cpp | 11 ++++-- 3 files changed, 74 insertions(+), 57 deletions(-) Index: llvm-java/lib/Compiler/Resolver.cpp diff -u llvm-java/lib/Compiler/Resolver.cpp:1.2 llvm-java/lib/Compiler/Resolver.cpp:1.3 --- llvm-java/lib/Compiler/Resolver.cpp:1.2 Fri Mar 25 20:50:56 2005 +++ llvm-java/lib/Compiler/Resolver.cpp Fri Mar 25 22:32:07 2005 @@ -93,8 +93,6 @@ ClassMap::iterator it = classMap_.lower_bound(descriptor); if (it == classMap_.end() || it->first != descriptor) { DEBUG(std::cerr << "Loading class: " << descriptor << '\n'); - // Insert dummy class to the map. - it = classMap_.insert(it, std::make_pair(descriptor, Class(*this))); switch (descriptor[0]) { case 'B': case 'C': @@ -110,18 +108,23 @@ case 'L': { unsigned pos = descriptor.find(';', 1); const std::string& className = descriptor.substr(1, pos - 1); - it->second.loadClass(className); + it = classMap_.insert( + it, std::make_pair(descriptor, + Class(*this, className))); break; } case '[': { const std::string& componentDescriptor = descriptor.substr(1); - it->second.loadArrayClass(getClassForDesc(componentDescriptor)); + it = classMap_.insert( + it, std::make_pair(descriptor, + Class(*this, getClassForDesc(componentDescriptor)))); break; } default: assert(0 && "Cannot parse type descriptor!"); abort(); } + it->second.link(); module_.addTypeName(descriptor, it->second.getStructType()); DEBUG(std::cerr << "Loaded class: " << descriptor << '\n'); } Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.4 llvm-java/lib/Compiler/Class.h:1.5 --- llvm-java/lib/Compiler/Class.h:1.4 Fri Mar 25 20:50:56 2005 +++ llvm-java/lib/Compiler/Class.h Fri Mar 25 22:32:07 2005 @@ -43,22 +43,26 @@ void addField(const std::string& name, const Type* type); void resolveType(); - // Creates primitive class for type. - Class(Resolver& resolver, const Type* type); - friend class Resolver; // Resolver interface. - // Creates a dummy class. - explicit Class(Resolver& resolver); + // Load primitive class for type. + Class(Resolver& resolver, const Type* type); + + // Load class by name. + Class(Resolver& resolver, const std::string& className); + + // Load array class of component the passed class. + Class(Resolver& resolver, const Class& componentClass); - // Builds the class object for the named class. - void loadClass(const std::string& className); - // Builds the array class object of component type componentClass. - void loadArrayClass(const Class& componentClass); + // Link the class. + void link(); + // Resolve the class. + void resolve(); + // Initialize the class. + void initialize(); - public: const Type* getStructType() const { return structType_; } const Type* getType() const { return type_; } Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.4 llvm-java/lib/Compiler/Class.cpp:1.5 --- llvm-java/lib/Compiler/Class.cpp:1.4 Fri Mar 25 20:50:56 2005 +++ llvm-java/lib/Compiler/Class.cpp Fri Mar 25 22:32:07 2005 @@ -25,9 +25,9 @@ using namespace llvm; using namespace llvm::Java; -Class::Class(Resolver& resolver) +Class::Class(Resolver& resolver, const std::string& className) : resolver_(&resolver), - classFile_(NULL), + classFile_(ClassFile::get(className)), superClass_(NULL), componentClass_(NULL), structType_(OpaqueType::get()), @@ -37,12 +37,24 @@ } +Class::Class(Resolver& resolver, const Class& componentClass) + : resolver_(&resolver), + classFile_(NULL), + superClass_(NULL), + componentClass_(&componentClass), + structType_(OpaqueType::get()), + type_(PointerType::get(structType_)), + interfaceIndex_(INVALID_INTERFACE_INDEX) +{ + +} + Class::Class(Resolver& resolver, const Type* type) : resolver_(&resolver), classFile_(NULL), superClass_(NULL), componentClass_(NULL), - structType_(0), + structType_(NULL), type_(type), interfaceIndex_(INVALID_INTERFACE_INDEX) { @@ -68,52 +80,50 @@ type_ = PointerType::get(structType_); } -void Class::loadClass(const std::string& className) +void Class::link() { - classFile_ = ClassFile::get(className); + assert(!isPrimitive() && "Should not link primitive classes!"); - // This is any class but java/lang/Object. - if (classFile_->getSuperClass()) { - const Class& superClass = - resolver_->getClass(classFile_->getSuperClass()->getName()->str()); - - // We first add the struct of the super class. - addField("super", superClass.getStructType()); - - // Although we can safely assume that all interfaces inherits from - // java/lang/Object, java/lang/Class.getSuperclass() returns null - // on interface types. So we only set the superClass_ field when - // the class is not an interface type, but we model the LLVM type - // of the interface to be as if it inherits java/lang/Object. - if (classFile_->isInterface()) - interfaceIndex_ = resolver_->getNextInterfaceIndex(); - else - superClass_ = &superClass; + if (isArray()) { + superClass_ = &resolver_->getClass("java/lang/Object"); + addField("super", superClass_->getStructType()); + addField("", Type::UIntTy); + addField("", ArrayType::get(componentClass_->getType(), 0)); } - // This is java/lang/Object. - else - addField("base", resolver_->getObjectBaseType()); - - // Then we add the rest of the fields. - const Fields& fields = classFile_->getFields(); - for (unsigned i = 0, e = fields.size(); i != e; ++i) { - Field& field = *fields[i]; - if (!field.isStatic()) - addField(field.getName()->str(), resolver_->getClass(field).getType()); + else { + // This is any class but java/lang/Object. + if (classFile_->getSuperClass()) { + const Class& superClass = + resolver_->getClass(classFile_->getSuperClass()->getName()->str()); + + // We first add the struct of the super class. + addField("super", superClass.getStructType()); + + // Although we can safely assume that all interfaces inherits + // from java/lang/Object, java/lang/Class.getSuperclass() + // returns null on interface types. So we only set the + // superClass_ field when the class is not an interface type, + // but we model the LLVM type of the interface to be as if it + // inherits java/lang/Object. + if (classFile_->isInterface()) + interfaceIndex_ = resolver_->getNextInterfaceIndex(); + else + superClass_ = &superClass; + } + // This is java/lang/Object. + else + addField("base", resolver_->getObjectBaseType()); + + // Then we add the rest of the fields. + const Fields& fields = classFile_->getFields(); + for (unsigned i = 0, e = fields.size(); i != e; ++i) { + Field& field = *fields[i]; + if (!field.isStatic()) + addField(field.getName()->str(), resolver_->getClass(field).getType()); + } } resolveType(); assert(!isa(getStructType()) &&"Class not initialized properly!"); } - -void Class::loadArrayClass(const Class& componentClass) -{ - superClass_ = &resolver_->getClass("java/lang/Object"); - componentClass_ = &componentClass; - addField("super", superClass_->getStructType()); - addField("", Type::UIntTy); - addField("", ArrayType::get(componentClass_->getType(), 0)); - - resolveType(); -} From alkis at cs.uiuc.edu Fri Mar 25 23:24:16 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 23:24:16 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Class.h Class.cpp Message-ID: <200503260524.XAA03286@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Class.h updated: 1.5 -> 1.6 Class.cpp updated: 1.5 -> 1.6 --- Log message: Rename member variable. --- Diffs of the changes: (+4 -4) Class.cpp | 6 +++--- Class.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.5 llvm-java/lib/Compiler/Class.h:1.6 --- llvm-java/lib/Compiler/Class.h:1.5 Fri Mar 25 22:32:07 2005 +++ llvm-java/lib/Compiler/Class.h Fri Mar 25 23:24:05 2005 @@ -38,7 +38,7 @@ typedef std::map Field2IndexMap; Field2IndexMap f2iMap_; typedef std::vector ElementTypes; - ElementTypes elementTypes; + ElementTypes elementTypes_; void addField(const std::string& name, const Type* type); void resolveType(); Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.5 llvm-java/lib/Compiler/Class.cpp:1.6 --- llvm-java/lib/Compiler/Class.cpp:1.5 Fri Mar 25 22:32:07 2005 +++ llvm-java/lib/Compiler/Class.cpp Fri Mar 25 23:24:05 2005 @@ -63,8 +63,8 @@ void Class::addField(const std::string& name, const Type* type) { - f2iMap_.insert(std::make_pair(name, elementTypes.size())); - elementTypes.push_back(type); + f2iMap_.insert(std::make_pair(name, elementTypes_.size())); + elementTypes_.push_back(type); } int Class::getFieldIndex(const std::string& name) const { @@ -74,7 +74,7 @@ void Class::resolveType() { PATypeHolder holder = structType_; - Type* resolvedType = StructType::get(elementTypes); + Type* resolvedType = StructType::get(elementTypes_); cast(structType_)->refineAbstractTypeTo(resolvedType); structType_ = holder.get(); type_ = PointerType::get(structType_); From alkis at cs.uiuc.edu Fri Mar 25 23:39:16 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri, 25 Mar 2005 23:39:16 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503260539.XAA03366@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.247 -> 1.248 --- Log message: Keep track of the current class being compiled, not its classfile. This is the first step in migrating a lot of the code in Compiler to Class itself. --- Diffs of the changes: (+28 -16) Compiler.cpp | 44 ++++++++++++++++++++++++++++---------------- 1 files changed, 28 insertions(+), 16 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.247 llvm-java/lib/Compiler/Compiler.cpp:1.248 --- llvm-java/lib/Compiler/Compiler.cpp:1.247 Fri Mar 25 19:42:38 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Fri Mar 25 23:39:05 2005 @@ -61,7 +61,7 @@ Module& module_; std::auto_ptr resolver_; GlobalVariable* JNIEnvPtr_; - const ClassFile* cf_; + const Class* class_; std::auto_ptr bbBuilder_; std::list bbWorkList_; typedef std::map OpStackDepthMap; @@ -1030,7 +1030,8 @@ /// Emits the necessary code to get a pointer to a static field of /// an object. GlobalVariable* getStaticField(unsigned index) { - ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); + ConstantFieldRef* fieldRef = + class_->getClassFile()->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); const std::string& className = fieldRef->getClass()->getName()->str(); @@ -1080,7 +1081,8 @@ /// Emits the necessary code to get a field from the passed /// pointer to an object. Value* getField(unsigned index, Value* ptr) { - ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); + ConstantFieldRef* fieldRef = + class_->getClassFile()->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); return getField( &resolver_->getClass(fieldRef->getClass()->getName()->str()), @@ -1135,7 +1137,9 @@ /// callers or methods of objects it creates). Function* compileMethodOnly(const std::string& classMethodDesc) { Method* method = getMethod(classMethodDesc); - cf_ = method->getParent(); + const std::string& className = + method->getParent()->getThisClass()->getName()->str(); + class_ = &resolver_->getClass(className); Function* function = getFunction(method); if (!function->empty()) { @@ -1151,9 +1155,9 @@ std::string funcName = "Java_" + - getMangledString(cf_->getThisClass()->getName()->str()) + '_' + + getMangledString(className) + '_' + getMangledString(method->getName()->str()); - if (cf_->isNativeMethodOverloaded(*method)) { + if (class_->getClassFile()->isNativeMethodOverloaded(*method)) { // We need to add two underscores and a mangled argument signature funcName += "__"; const std::string descr = method->getDescriptor()->str(); @@ -1474,7 +1478,7 @@ } void do_ldc(unsigned index) { - Constant* c = cf_->getConstant(index); + Constant* c = class_->getClassFile()->getConstant(index); assert(getConstant(c) && "Java constant not handled!"); push(getConstant(c)); } @@ -1848,7 +1852,8 @@ } void do_getfield(unsigned index) { - ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); + ConstantFieldRef* fieldRef = + class_->getClassFile()->getConstantFieldRef(index); const std::string& name = fieldRef->getNameAndType()->getName()->str(); Value* p = pop(resolver_->getObjectBaseRefType()); Value* v = new LoadInst(getField(index, p), name, currentBB_); @@ -1856,7 +1861,8 @@ } void do_putfield(unsigned index) { - ConstantFieldRef* fieldRef = cf_->getConstantFieldRef(index); + ConstantFieldRef* fieldRef = + class_->getClassFile()->getConstantFieldRef(index); const Type* type = resolver_->getType(fieldRef->getNameAndType()->getDescriptor()->str()); Value* v = pop(type); @@ -1931,7 +1937,8 @@ } void do_invokevirtual(unsigned index) { - ConstantMethodRef* methodRef = cf_->getConstantMethodRef(index); + ConstantMethodRef* methodRef = + class_->getClassFile()->getConstantMethodRef(index); ConstantNameAndType* nameAndType = methodRef->getNameAndType(); const std::string& className = methodRef->getClass()->getName()->str(); @@ -1969,7 +1976,8 @@ } void do_invokespecial(unsigned index) { - ConstantMethodRef* methodRef = cf_->getConstantMethodRef(index); + ConstantMethodRef* methodRef = + class_->getClassFile()->getConstantMethodRef(index); ConstantNameAndType* nameAndType = methodRef->getNameAndType(); const std::string& className = methodRef->getClass()->getName()->str(); @@ -1987,7 +1995,8 @@ } void do_invokestatic(unsigned index) { - ConstantMethodRef* methodRef = cf_->getConstantMethodRef(index); + ConstantMethodRef* methodRef = + class_->getClassFile()->getConstantMethodRef(index); emitStaticInitializers( ClassFile::get(methodRef->getClass()->getName()->str())); Method* method = getMethod(methodRef); @@ -2010,7 +2019,7 @@ void do_invokeinterface(unsigned index) { ConstantInterfaceMethodRef* methodRef = - cf_->getConstantInterfaceMethodRef(index); + class_->getClassFile()->getConstantInterfaceMethodRef(index); ConstantNameAndType* nameAndType = methodRef->getNameAndType(); const std::string& className = methodRef->getClass()->getName()->str(); @@ -2087,7 +2096,8 @@ } void do_new(unsigned index) { - ConstantClass* classRef = cf_->getConstantClass(index); + ConstantClass* classRef = + class_->getClassFile()->getConstantClass(index); const Class& ci = resolver_->getClass(classRef->getName()->str()); emitStaticInitializers(ci.getClassFile()); const VTableInfo& vi = getVTableInfo(ci.getClassFile()); @@ -2201,7 +2211,8 @@ } void do_checkcast(unsigned index) { - ConstantClass* classRef = cf_->getConstantClass(index); + ConstantClass* classRef = + class_->getClassFile()->getConstantClass(index); const Class* ci = &resolver_->getClass(classRef->getName()->str()); const VTableInfo* vi = getVTableInfoGeneric(classRef->getName()->str()); @@ -2220,7 +2231,8 @@ } void do_instanceof(unsigned index) { - ConstantClass* classRef = cf_->getConstantClass(index); + ConstantClass* classRef = + class_->getClassFile()->getConstantClass(index); const Class* ci = &resolver_->getClass(classRef->getName()->str()); const VTableInfo* vi = getVTableInfoGeneric(classRef->getName()->str()); From alkis at cs.uiuc.edu Sat Mar 26 00:11:06 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 00:11:06 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503260611.AAA03631@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.248 -> 1.249 --- Log message: Now that ConstantString becomes an llvm::Constant as well, we can initialize class static variables with them. --- Diffs of the changes: (+2 -5) Compiler.cpp | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.248 llvm-java/lib/Compiler/Compiler.cpp:1.249 --- llvm-java/lib/Compiler/Compiler.cpp:1.248 Fri Mar 25 23:39:05 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 00:10:56 2005 @@ -1340,11 +1340,8 @@ if (field->getConstantValueAttribute()) { Constant* constant = field->getConstantValueAttribute()->getValue(); - if (!dynamic_cast(constant)) { - init = ConstantExpr::getCast( - dyn_cast(getConstant(constant)), globalTy); - isConstant = field->isFinal(); - } + init = ConstantExpr::getCast(getConstant(constant), globalTy); + isConstant = field->isFinal(); } std::string globalName = From natebegeman at mac.com Sat Mar 26 01:46:47 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 26 Mar 2005 01:46:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200503260746.BAA03962@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.7 -> 1.8 --- Log message: Get closer to having varargs working. There's still something strange going on with copies between floating point and integer register files being generated. Once that is solved, varargs will be done. --- Diffs of the changes: (+38 -37) PPC32ISelPattern.cpp | 75 +++++++++++++++++++++++++-------------------------- 1 files changed, 38 insertions(+), 37 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.7 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.8 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.7 Fri Mar 25 20:17:46 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Mar 26 01:46:36 2005 @@ -132,7 +132,8 @@ needsLoad = true; } break; - case MVT::i64: ObjSize = 8; + case MVT::i64: ObjSize = 8; + // FIXME: can split 64b load between reg/mem if it is last arg in regs if (GPR_remaining > 1) { BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]); @@ -263,8 +264,9 @@ // register cannot be found for it. SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + MVT::ValueType ArgVT = getValueType(Args[i].second); - switch (getValueType(Args[i].second)) { + switch (ArgVT) { default: assert(0 && "Unexpected ValueType for argument!"); case MVT::i1: case MVT::i8: @@ -287,27 +289,25 @@ ArgOffset += 4; break; case MVT::i64: - // If we have 2 or more GPRs, we won't do anything and let the ISD::CALL - // functionality in SelectExpr move pieces for us. - if (GPR_remaining > 1) { - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(0, MVT::i32)); - args_to_use.push_back(Hi); - args_to_use.push_back(Lo); - GPR_remaining -= 2; - } else if (GPR_remaining > 0) { + // If we have one free GPR left, we can place the upper half of the i64 + // in it, and store the other half to the stack. If we have two or more + // free GPRs, then we can pass both halves of the i64 in registers. + if (GPR_remaining > 0) { SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Args[i].first, DAG.getConstant(1, MVT::i32)); SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Args[i].first, DAG.getConstant(0, MVT::i32)); - args_to_use.push_back(Hi); - SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Lo, PtrOff)); - --GPR_remaining; + args_to_use.push_back(Hi); + if (GPR_remaining > 1) { + args_to_use.push_back(Lo); + GPR_remaining -= 2; + } else { + SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Lo, PtrOff)); + --GPR_remaining; + } } else { Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, Args[i].first, PtrOff)); @@ -315,32 +315,33 @@ ArgOffset += 8; break; case MVT::f32: - if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) { - --FPR_remaining; - ArgOffset += 4; - } else if (FPR_remaining > 0) { - args_to_use.push_back(Args[i].first); - --FPR_remaining; - if (GPR_remaining > 0) --GPR_remaining; - } else { - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff)); - } - ArgOffset += 4; - break; case MVT::f64: - if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) { - --FPR_remaining; - } else if (FPR_remaining > 0) { + if (FPR_remaining > 0) { + if (isVarArg) { + // FIXME: Need FunctionType information so we can conditionally + // store only the non-fixed arguments in a vararg function. + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff)); + if (GPR_remaining > 0) + args_to_use.push_back(DAG.getLoad(MVT::i32, Chain, PtrOff)); + if (GPR_remaining > 1) { + SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); + args_to_use.push_back(DAG.getLoad(MVT::i32, Chain, PtrOff)); + } + } args_to_use.push_back(Args[i].first); --FPR_remaining; + // If we have any FPRs remaining, we may also have GPRs remaining. + // Args passed in FPRs consume either 1 (f32) or 2 (f64) available + // GPRs. if (GPR_remaining > 0) --GPR_remaining; - if (GPR_remaining > 0) --GPR_remaining; + if (GPR_remaining > 0 && MVT::f64 == ArgVT) --GPR_remaining; } else { Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, Args[i].first, PtrOff)); } - ArgOffset += 8; + ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; break; } } From natebegeman at mac.com Sat Mar 26 02:25:33 2005 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 26 Mar 2005 02:25:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Message-ID: <200503260825.CAA04176@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC32ISelPattern.cpp updated: 1.8 -> 1.9 --- Log message: Fix that pesky floats in integer regs problem by assigning the f32 type to the correct register class. Also remove the loading of float data into int regs part of varargs; it will need to be implemented differently later. --- Diffs of the changes: (+4 -8) PPC32ISelPattern.cpp | 12 ++++-------- 1 files changed, 4 insertions(+), 8 deletions(-) Index: llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.8 llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.9 --- llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp:1.8 Sat Mar 26 01:46:36 2005 +++ llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp Sat Mar 26 02:25:22 2005 @@ -44,7 +44,7 @@ // Set up the register classes. addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass); - addRegisterClass(MVT::f32, PPC32::GPRCRegisterClass); + addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass); addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass); computeRegisterProperties(); @@ -322,13 +322,9 @@ // store only the non-fixed arguments in a vararg function. Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, Args[i].first, PtrOff)); - if (GPR_remaining > 0) - args_to_use.push_back(DAG.getLoad(MVT::i32, Chain, PtrOff)); - if (GPR_remaining > 1) { - SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); - args_to_use.push_back(DAG.getLoad(MVT::i32, Chain, PtrOff)); - } + // FIXME: Need a way to communicate to the ISD::CALL select code + // that a particular argument is non-fixed so that we can load them + // into the correct GPR to shadow the FPR } args_to_use.push_back(Args[i].first); --FPR_remaining; From alkis at cs.uiuc.edu Sat Mar 26 08:08:50 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 08:08:50 -0600 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200503261408.IAA32145@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.33 -> 1.34 --- Log message: Expose constant pool indexes. --- Diffs of the changes: (+29 -14) ClassFile.h | 43 +++++++++++++++++++++++++++++-------------- 1 files changed, 29 insertions(+), 14 deletions(-) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.33 llvm-java/include/llvm/Java/ClassFile.h:1.34 --- llvm-java/include/llvm/Java/ClassFile.h:1.33 Wed Mar 23 19:04:28 2005 +++ llvm-java/include/llvm/Java/ClassFile.h Sat Mar 26 08:08:38 2005 @@ -181,6 +181,7 @@ uint16_t nameIdx_; public: ConstantClass(const ClassFile* cf, std::istream& is); + unsigned getNameIndex() const { return nameIdx_; } ConstantUtf8* getName() const { return parent_->getConstantUtf8(nameIdx_); } @@ -194,9 +195,11 @@ ConstantMemberRef(const ClassFile* cf, std::istream& is); public: + unsigned getClassIndex() const { return classIdx_; } ConstantClass* getClass() const { return parent_->getConstantClass(classIdx_); } + unsigned getNameAndTypeIndex() const { return nameAndTypeIdx_; } ConstantNameAndType* getNameAndType() const { return parent_->getConstantNameAndType(nameAndTypeIdx_); } @@ -227,6 +230,7 @@ uint16_t stringIdx_; public: ConstantString(const ClassFile* cf, std::istream& is); + unsigned getStringIndex() const { return stringIdx_; } ConstantUtf8* getValue() const { return parent_->getConstantUtf8(stringIdx_); } @@ -272,9 +276,11 @@ uint16_t descriptorIdx_; public: ConstantNameAndType(const ClassFile* cf, std::istream& is); + unsigned getNameIndex() const { return nameIdx_; } ConstantUtf8* getName() const { return parent_->getConstantUtf8(nameIdx_); } + unsigned getDescriptorIndex() const { return descriptorIdx_; } ConstantUtf8* getDescriptor() const { return parent_->getConstantUtf8(descriptorIdx_); } @@ -309,7 +315,9 @@ bool isFinal() const { return accessFlags_ & ACC_FINAL; } const ClassFile* getParent() const { return parent_; } + unsigned getNameIndex() const { return nameIdx_; } ConstantUtf8* getName() const { return parent_->getConstantUtf8(nameIdx_); } + unsigned getDescriptorIndex() const { return descriptorIdx_; } ConstantUtf8* getDescriptor() const { return parent_->getConstantUtf8(descriptorIdx_); } @@ -365,17 +373,19 @@ } class Attribute { - ConstantUtf8* name_; - protected: - Attribute(ConstantUtf8* name, const ClassFile* cf, std::istream& is); + const ClassFile* parent_; + uint16_t nameIdx_; + + Attribute(const ClassFile* cf, uint16_t nameIdx, std::istream& is); public: static Attribute* readAttribute(const ClassFile* cf, std::istream& is); virtual ~Attribute(); - ConstantUtf8* getName() const { return name_; } + unsigned getNameIndex() const { return nameIdx_; } + ConstantUtf8* getName() const { return parent_->getConstantUtf8(nameIdx_); } virtual std::ostream& dump(std::ostream& os) const; @@ -395,13 +405,14 @@ } class ConstantValueAttribute : public Attribute { - Constant* value_; + uint16_t valueIdx_; public: - ConstantValueAttribute(ConstantUtf8* name, - const ClassFile* cf, + ConstantValueAttribute(const ClassFile* cf, + uint16_t nameIdx, std::istream& is); - Constant* getValue() const { return value_; } + unsigned getValueIndex() const { return valueIdx_; } + Constant* getValue() const { return parent_->getConstant(valueIdx_); } std::ostream& dump(std::ostream& os) const; }; @@ -409,10 +420,11 @@ class CodeAttribute : public Attribute { public: class Exception { + const ClassFile* parent_; uint16_t startPc_; uint16_t endPc_; uint16_t handlerPc_; - ConstantClass* catchType_; + uint16_t catchTypeIdx_; public: Exception(const ClassFile* cf, std::istream& is); @@ -420,7 +432,10 @@ uint16_t getStartPc() const { return startPc_; } uint16_t getEndPc() const { return endPc_; } uint16_t getHandlerPc() const { return handlerPc_; } - ConstantClass* getCatchType() const { return catchType_; } + uint16_t getCatchTypeIndex() const { return catchTypeIdx_; } + ConstantClass* getCatchType() const { + return catchTypeIdx_ ? NULL : parent_->getConstantClass(catchTypeIdx_); + } std::ostream& dump(std::ostream& os) const; }; @@ -436,7 +451,7 @@ Attributes attributes_; public: - CodeAttribute(ConstantUtf8* name, const ClassFile* cf, std::istream& is); + CodeAttribute(const ClassFile* cf, uint16_t nameIdx, std::istream& is); ~CodeAttribute(); uint16_t getMaxStack() const { return maxStack_; } uint16_t getMaxLocals() const { return maxLocals_; } @@ -455,12 +470,12 @@ class ExceptionsAttribute : public Attribute { private: - ConstantUtf8* name_; + uint16_t nameIdx_; Classes exceptions_; public: - ExceptionsAttribute(ConstantUtf8* name, - const ClassFile* cf, + ExceptionsAttribute(const ClassFile* cf, + uint16_t nameIdx, std::istream& is); const Classes& getExceptions() const { return exceptions_; } From alkis at cs.uiuc.edu Sat Mar 26 08:08:50 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 08:08:50 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Message-ID: <200503261408.IAA32144@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp updated: 1.42 -> 1.43 --- Log message: Expose constant pool indexes. --- Diffs of the changes: (+28 -29) ClassFile.cpp | 57 ++++++++++++++++++++++++++++----------------------------- 1 files changed, 28 insertions(+), 29 deletions(-) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.42 llvm-java/lib/ClassFile/ClassFile.cpp:1.43 --- llvm-java/lib/ClassFile/ClassFile.cpp:1.42 Wed Mar 23 19:04:28 2005 +++ llvm-java/lib/ClassFile/ClassFile.cpp Sat Mar 26 08:08:38 2005 @@ -657,24 +657,26 @@ Attribute* Attribute::readAttribute(const ClassFile* cf, std::istream& is) { - ConstantUtf8* name = cf->getConstantUtf8(readU2(is)); + uint16_t nameIdx = readU2(is); + ConstantUtf8* name = cf->getConstantUtf8(nameIdx); if (!name) throw ClassFileSemanticError( "Representation of attribute name is not of type ConstantUtf8"); if (CONSTANT_VALUE == name->str()) - return new ConstantValueAttribute(name, cf, is); + return new ConstantValueAttribute(cf, nameIdx, is); else if (CODE == name->str()) - return new CodeAttribute(name, cf, is); + return new CodeAttribute(cf, nameIdx, is); else { uint32_t length = readU4(is); is.ignore(length); - return new Attribute(name, cf, is); + return new Attribute(cf, nameIdx, is); } } -Attribute::Attribute(ConstantUtf8* name, const ClassFile* cf, std::istream& is) - : name_(name) +Attribute::Attribute(const ClassFile* cf, uint16_t nameIdx, std::istream& is) + : parent_(cf), + nameIdx_(nameIdx) { } @@ -691,29 +693,29 @@ //===----------------------------------------------------------------------===// // AttributeConstantValue implementation -ConstantValueAttribute::ConstantValueAttribute(ConstantUtf8* name, - const ClassFile* cf, +ConstantValueAttribute::ConstantValueAttribute(const ClassFile* cf, + uint16_t nameIdx, std::istream& is) - : Attribute(name, cf, is) + : Attribute(cf, nameIdx, is) { uint32_t length = readU4(is); if (length != 2) throw ClassFileSemanticError( "Length of ConstantValueAttribute is not 2"); - value_ = cf->getConstant(readU2(is)); + valueIdx_ = readU2(is); } std::ostream& ConstantValueAttribute::dump(std::ostream& os) const { - return Attribute::dump(os) << ": " << *value_; + return Attribute::dump(os) << ": " << *getValue(); } //===----------------------------------------------------------------------===// // AttributeCode implementation -CodeAttribute::CodeAttribute(ConstantUtf8* name, - const ClassFile* cf, +CodeAttribute::CodeAttribute(const ClassFile* cf, + uint16_t nameIdx, std::istream& is) - : Attribute(name, cf, is) + : Attribute(cf, nameIdx, is) { uint32_t length = readU4(is); maxStack_ = readU2(is); @@ -752,18 +754,15 @@ } CodeAttribute::Exception::Exception(const ClassFile* cf, std::istream& is) - : catchType_(NULL) -{ - startPc_ = readU2(is); - endPc_ = readU2(is); - handlerPc_ = readU2(is); - uint16_t idx = readU2(is); - if (idx) { - catchType_ = cf->getConstantClass(idx); - if (!catchType_) - throw ClassFileSemanticError - ("Representation of catch type is not of type ConstantClass"); - } + : parent_(cf), + startPc_(readU2(is)), + endPc_(readU2(is)), + handlerPc_(readU2(is)), + catchTypeIdx_(readU2(is)) +{ + if (catchTypeIdx_ && !cf->getConstantClass(catchTypeIdx_)) + throw ClassFileSemanticError + ("Representation of catch type is not of type ConstantClass"); } std::ostream& CodeAttribute::Exception::dump(std::ostream& os) const @@ -779,10 +778,10 @@ //===----------------------------------------------------------------------===// // AttributeExceptions implementation -ExceptionsAttribute::ExceptionsAttribute(ConstantUtf8* name, - const ClassFile* cf, +ExceptionsAttribute::ExceptionsAttribute(const ClassFile* cf, + uint16_t nameIdx, std::istream& is) - : Attribute(name, cf, is) + : Attribute(cf, nameIdx, is) { uint32_t length = readU4(is); readClasses(exceptions_, cf, is); From alkis at cs.uiuc.edu Sat Mar 26 08:41:59 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 08:41:59 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Class.h Class.cpp Message-ID: <200503261441.IAA32317@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.249 -> 1.250 Class.h updated: 1.6 -> 1.7 Class.cpp updated: 1.6 -> 1.7 --- Log message: Resolve constant pool inside the Class object and cache the results. Right now we only resolve constants (class and member references will follow). --- Diffs of the changes: (+77 -67) Class.cpp | 47 +++++++++++++++++++++++++++++ Class.h | 4 ++ Compiler.cpp | 93 +++++++++++++++++------------------------------------------ 3 files changed, 77 insertions(+), 67 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.249 llvm-java/lib/Compiler/Compiler.cpp:1.250 --- llvm-java/lib/Compiler/Compiler.cpp:1.249 Sat Mar 26 00:10:56 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 08:41:48 2005 @@ -156,8 +156,9 @@ } template - GlobalVariable* createNewString(const std::string& str, - InsertionPointTy* ip) { + void initializeString(Value* globalString, + const std::string& str, + InsertionPointTy* ip) { // Create a new byte[] object and initialize it with the // contents of this string constant. Value* count = ConstantUInt::get(Type::UIntTy, str.size()); @@ -194,14 +195,6 @@ const Class& ci = resolver_->getClass("java/lang/String"); const VTableInfo& vi = getVTableInfo(ci.getClassFile()); - // Create a zeroinitialized static java/lang/String object. - GlobalVariable* globalString = - new GlobalVariable(ci.getStructType(), - false, - GlobalVariable::LinkOnceLinkage, - llvm::Constant::getNullValue(ci.getStructType()), - str + ".java/lang/String", - &module_); // Install the vtable pointer. Value* objBase = new CastInst(globalString, resolver_->getObjectBaseRefType(), TMP, ip); @@ -219,45 +212,6 @@ params.push_back(new CastInst(arrayRef, resolver_->getObjectBaseRefType(), TMP, ip)); params.push_back(ConstantSInt::get(Type::IntTy, 0)); new CallInst(function, params, "", ip); - - return globalString; - } - - GlobalVariable* getConstantString(ConstantString* s) { - const std::string& str = s->getValue()->str(); - StringMap::iterator it = stringMap_.find(str); - if (it == stringMap_.end()) { - // Get the static initializer function and get its one and - // only basic block to add code to. - Function* hook = module_.getOrInsertFunction(LLVM_JAVA_STATIC_INIT, - Type::VoidTy, 0); - Instruction* I = hook->front().getTerminator(); - assert(I && LLVM_JAVA_STATIC_INIT " should have a terminator!"); - - GlobalVariable* stringGlobal = createNewString(str, I); - - // Insert this new string into the map. - it = stringMap_.insert(it, std::make_pair(str, stringGlobal)); - } - - return it->second; - } - - /// Given a llvm::Java::Constant returns an llvm::Constant. - llvm::Constant* getConstant(Constant* c) { - if (ConstantString* s = dynamic_cast(c)) - return getConstantString(s); - else if (ConstantInteger* i = dynamic_cast(c)) - return ConstantSInt::get(Type::IntTy, i->getValue()); - else if (ConstantFloat* f = dynamic_cast(c)) - return ConstantFP::get(Type::FloatTy, f->getValue()); - else if (ConstantLong* l = dynamic_cast(c)) - return ConstantSInt::get(Type::LongTy, l->getValue()); - else if (ConstantDouble* d = dynamic_cast(c)) - return ConstantFP::get(Type::DoubleTy, d->getValue()); - else - assert(0 && "Unknown llvm::Java::Constant!"); - return 0; // not reached } /// Returns the type of the Java string descriptor for JNI. @@ -1325,6 +1279,10 @@ emitStaticInitializers( ClassFile::get(classfile->getSuperClass()->getName()->str())); + const std::string& className = + classfile->getThisClass()->getName()->str(); + const Class& clazz = resolver_->getClass(className); + // Create the global variables of this class. const Fields& fields = classfile->getFields(); for (unsigned i = 0, e = fields.size(); i != e; ++i) { @@ -1338,9 +1296,8 @@ bool isConstant = false; llvm::Constant* init = llvm::Constant::getNullValue(globalTy); if (field->getConstantValueAttribute()) { - Constant* constant = - field->getConstantValueAttribute()->getValue(); - init = ConstantExpr::getCast(getConstant(constant), globalTy); + unsigned i = field->getConstantValueAttribute()->getValueIndex(); + init = ConstantExpr::getCast(clazz.getConstant(i), globalTy); isConstant = field->isFinal(); } @@ -1357,24 +1314,28 @@ } } + Function* hook = module_.getOrInsertFunction(LLVM_JAVA_STATIC_INIT, + Type::VoidTy, 0); + Instruction* I = hook->front().getTerminator(); + assert(I && LLVM_JAVA_STATIC_INIT " should have a terminator!"); + + // Create constant strings for this class. + for (unsigned i = 0, e = classfile->getNumConstants(); i != e; ++i) + if (ConstantString* s = dynamic_cast(classfile->getConstant(i))) + initializeString(clazz.getConstant(i), s->getValue()->str(), I); + // Call its class initialization method if it exists. if (const Method* method = classfile->getMethod("()V")) { - std::string name = classfile->getThisClass()->getName()->str(); - name += '/'; - name += method->getName()->str(); - name += method->getDescriptor()->str(); - - Function* hook = module_.getOrInsertFunction(LLVM_JAVA_STATIC_INIT, - Type::VoidTy, 0); - Function* init = module_.getOrInsertFunction(name, Type::VoidTy, 0); + const std::string& functionName = className + '/' + + method->getName()->str() + method->getDescriptor()->str(); + Function* init = + module_.getOrInsertFunction(functionName, Type::VoidTy, 0); // Insert a call to it right before the terminator of the only // basic block in llvm_java_static_init. bool inserted = scheduleFunction(init); assert(inserted && "Class initialization method already called!"); - assert(hook->front().getTerminator() && - LLVM_JAVA_STATIC_INIT " should have a terminator!"); - new CallInst(init, "", hook->front().getTerminator()); + new CallInst(init, "", I); } } } @@ -1475,9 +1436,9 @@ } void do_ldc(unsigned index) { - Constant* c = class_->getClassFile()->getConstant(index); - assert(getConstant(c) && "Java constant not handled!"); - push(getConstant(c)); + llvm::Constant* c = class_->getConstant(index); + assert(c && "Java constant not handled!"); + push(c); } void do_ldc2(unsigned index) { Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.6 llvm-java/lib/Compiler/Class.h:1.7 --- llvm-java/lib/Compiler/Class.h:1.6 Fri Mar 25 23:24:05 2005 +++ llvm-java/lib/Compiler/Class.h Sat Mar 26 08:41:48 2005 @@ -15,6 +15,7 @@ #ifndef LLVM_JAVA_CLASS_H #define LLVM_JAVA_CLASS_H +#include #include #include #include @@ -39,6 +40,7 @@ Field2IndexMap f2iMap_; typedef std::vector ElementTypes; ElementTypes elementTypes_; + mutable std::vector resolvedConstantPool_; void addField(const std::string& name, const Type* type); void resolveType(); @@ -73,6 +75,8 @@ bool isPrimitive() const { return !structType_; } unsigned getInterfaceIndex() const { return interfaceIndex_; } int getFieldIndex(const std::string& name) const; + + llvm::Constant* getConstant(unsigned index) const; }; } } // namespace llvm::Java Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.6 llvm-java/lib/Compiler/Class.cpp:1.7 --- llvm-java/lib/Compiler/Class.cpp:1.6 Fri Mar 25 23:24:05 2005 +++ llvm-java/lib/Compiler/Class.cpp Sat Mar 26 08:41:48 2005 @@ -18,6 +18,7 @@ #include "Class.h" #include "Resolver.h" #include +#include #include #define LLVM_JAVA_OBJECT_BASE "struct.llvm_java_object_base" @@ -32,7 +33,8 @@ componentClass_(NULL), structType_(OpaqueType::get()), type_(PointerType::get(structType_)), - interfaceIndex_(INVALID_INTERFACE_INDEX) + interfaceIndex_(INVALID_INTERFACE_INDEX), + resolvedConstantPool_(classFile_->getNumConstants()) { } @@ -127,3 +129,46 @@ assert(!isa(getStructType()) &&"Class not initialized properly!"); } + +llvm::Constant* Class::getConstant(unsigned index) const +{ + assert(classFile_ && "No constant pool!"); + assert((dynamic_cast(classFile_->getConstant(index)) || + dynamic_cast(classFile_->getConstant(index)) || + dynamic_cast(classFile_->getConstant(index)) || + dynamic_cast(classFile_->getConstant(index)) || + dynamic_cast(classFile_->getConstant(index))) && + "Not an index to a constant!"); + + // If we haven't resolved this constant already, do so now. + if (!resolvedConstantPool_[index]) { + Constant* jc = classFile_->getConstant(index); + if (ConstantString* s = dynamic_cast(jc)) { + const Class& stringClass = resolver_->getClass("java/lang/String"); + const Type* stringType = stringClass.getStructType(); + resolvedConstantPool_[index] = + new GlobalVariable(stringType, + false, + GlobalVariable::LinkOnceLinkage, + llvm::Constant::getNullValue(stringType), + s->getValue()->str() + ".java/lang/String", + &resolver_->getModule()); + } + else if (ConstantInteger* i = dynamic_cast(jc)) + resolvedConstantPool_[index] = + ConstantSInt::get(Type::IntTy, i->getValue()); + else if (ConstantFloat* f = dynamic_cast(jc)) + resolvedConstantPool_[index] = + ConstantFP::get(Type::FloatTy, f->getValue()); + else if (ConstantLong* l = dynamic_cast(jc)) + resolvedConstantPool_[index] = + ConstantSInt::get(Type::LongTy, l->getValue()); + else if (ConstantDouble* d = dynamic_cast(jc)) + resolvedConstantPool_[index] = + ConstantFP::get(Type::DoubleTy, d->getValue()); + else + assert(0 && "Not a constant!"); + } + + return static_cast(resolvedConstantPool_[index]); +} From alkis at cs.uiuc.edu Sat Mar 26 09:47:40 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 09:47:40 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503261547.JAA32548@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.250 -> 1.251 --- Log message: Simplify getVTableInfoGeneric. --- Diffs of the changes: (+24 -50) Compiler.cpp | 74 +++++++++++++++++++---------------------------------------- 1 files changed, 24 insertions(+), 50 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.250 llvm-java/lib/Compiler/Compiler.cpp:1.251 --- llvm-java/lib/Compiler/Compiler.cpp:1.250 Sat Mar 26 08:41:48 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 09:47:29 2005 @@ -755,7 +755,7 @@ return vi; } - const VTableInfo& getPrimitiveArrayVTableInfo(Type* type) { + const VTableInfo& getPrimitiveArrayVTableInfo(const Type* type) { if (Type::BoolTy == type) return getPrimitiveArrayVTableInfo(BOOLEAN); else if (Type::UShortTy == type) return getPrimitiveArrayVTableInfo(CHAR); else if (Type::FloatTy == type) return getPrimitiveArrayVTableInfo(FLOAT); @@ -1853,45 +1853,18 @@ return params; } - const VTableInfo* getVTableInfoGeneric(const std::string& className) { - const VTableInfo* vi = NULL; - - if (className[0] == '[') { - if (className[1] == '[' || className[1] == 'L') - vi = &getObjectArrayVTableInfo(ClassFile::get("java/lang/Object")); - else switch (className[1]) { - case 'B': - vi = &getPrimitiveArrayVTableInfo(Type::SByteTy); - break; - case 'C': - vi = &getPrimitiveArrayVTableInfo(Type::UShortTy); - break; - case 'D': - vi = &getPrimitiveArrayVTableInfo(Type::DoubleTy); - break; - case 'F': - vi = &getPrimitiveArrayVTableInfo(Type::FloatTy); - break; - case 'I': - vi = &getPrimitiveArrayVTableInfo(Type::IntTy); - break; - case 'J': - vi = &getPrimitiveArrayVTableInfo(Type::LongTy); - break; - case 'S': - vi = &getPrimitiveArrayVTableInfo(Type::ShortTy); - break; - case 'Z': - vi = &getPrimitiveArrayVTableInfo(Type::BoolTy); - break; - } - } - else { - const ClassFile* cf = ClassFile::get(className); - vi = &getVTableInfo(cf); + const VTableInfo* getVTableInfoGeneric(const Class* clazz) { + assert(!clazz->isPrimitive() && + "Cannot get VTableInfo for primitive class!"); + if (clazz->isArray()) { + const Class* componentClass = clazz->getComponentClass(); + if (componentClass->isPrimitive()) + return &getPrimitiveArrayVTableInfo(componentClass->getType()); + else + return &getObjectArrayVTableInfo(ClassFile::get("java/lang/Object")); } - - return vi; + else + return &getVTableInfo(clazz->getClassFile()); } void do_invokevirtual(unsigned index) { @@ -1901,8 +1874,8 @@ const std::string& className = methodRef->getClass()->getName()->str(); - const Class* ci = &resolver_->getClass(className); - const VTableInfo* vi = getVTableInfoGeneric(className); + const Class* clazz = &resolver_->getClass(className); + const VTableInfo* vi = getVTableInfoGeneric(clazz); const std::string& methodDescr = nameAndType->getName()->str() + @@ -1914,7 +1887,7 @@ std::vector params(getParams(funTy)); Value* objRef = params.front(); - objRef = new CastInst(objRef, ci->getType(), "this", currentBB_); + objRef = new CastInst(objRef, clazz->getType(), "this", currentBB_); Value* objBase = new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, currentBB_); Value* vtable = new CallInst(getVtable_, objBase, TMP, currentBB_); @@ -1982,8 +1955,8 @@ const std::string& className = methodRef->getClass()->getName()->str(); - const Class* ci = &resolver_->getClass(className); - const VTableInfo* vi = getVTableInfoGeneric(className); + const Class* clazz = &resolver_->getClass(className); + const VTableInfo* vi = getVTableInfoGeneric(clazz); const std::string& methodDescr = nameAndType->getName()->str() + @@ -1995,7 +1968,7 @@ std::vector params(getParams(funTy)); Value* objRef = params.front(); - objRef = new CastInst(objRef, ci->getType(), "this", currentBB_); + objRef = new CastInst(objRef, clazz->getType(), "this", currentBB_); Value* objBase = new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, currentBB_); Value* vtable = new CallInst(getVtable_, objBase, TMP, currentBB_); @@ -2009,7 +1982,8 @@ interfaceVTables = new LoadInst(interfaceVTables, TMP, currentBB_); // Get the actual interface vtable. indices.clear(); - indices.push_back(ConstantUInt::get(Type::UIntTy, ci->getInterfaceIndex())); + indices.push_back(ConstantUInt::get(Type::UIntTy, + clazz->getInterfaceIndex())); Value* interfaceVTable = new GetElementPtrInst(interfaceVTables, indices, TMP, currentBB_); interfaceVTable = @@ -2172,8 +2146,8 @@ ConstantClass* classRef = class_->getClassFile()->getConstantClass(index); - const Class* ci = &resolver_->getClass(classRef->getName()->str()); - const VTableInfo* vi = getVTableInfoGeneric(classRef->getName()->str()); + const Class* clazz = &resolver_->getClass(classRef->getName()->str()); + const VTableInfo* vi = getVTableInfoGeneric(clazz); Value* objRef = pop(resolver_->getObjectBaseRefType()); Value* vtable = new CastInst(vi->vtable, @@ -2192,8 +2166,8 @@ ConstantClass* classRef = class_->getClassFile()->getConstantClass(index); - const Class* ci = &resolver_->getClass(classRef->getName()->str()); - const VTableInfo* vi = getVTableInfoGeneric(classRef->getName()->str()); + const Class* clazz = &resolver_->getClass(classRef->getName()->str()); + const VTableInfo* vi = getVTableInfoGeneric(clazz); Value* objRef = pop(resolver_->getObjectBaseRefType()); Value* vtable = new CastInst(vi->vtable, VTableBaseRefTy, From alkis at cs.uiuc.edu Sat Mar 26 10:14:40 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 10:14:40 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.h Message-ID: <200503261614.KAA32665@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.h updated: 1.2 -> 1.3 --- Log message: Split canonicalization of class name's in its own function. --- Diffs of the changes: (+8 -4) Resolver.h | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) Index: llvm-java/lib/Compiler/Resolver.h diff -u llvm-java/lib/Compiler/Resolver.h:1.2 llvm-java/lib/Compiler/Resolver.h:1.3 --- llvm-java/lib/Compiler/Resolver.h:1.2 Fri Mar 25 20:56:14 2005 +++ llvm-java/lib/Compiler/Resolver.h Sat Mar 26 10:14:29 2005 @@ -39,6 +39,13 @@ unsigned& i, bool memberMethod = false) const; + std::string canonicalizeClassName(const std::string& className) { + if (className[0] == '[') + return className; + else + return 'L' + className + ';'; + } + public: Resolver(Module& module); @@ -58,10 +65,7 @@ } const Class& getClass(const std::string& className) { - if (className[0] == '[') - return getClassForDesc(className); - else - return getClassForDesc('L' + className + ';'); + return getClassForDesc(canonicalizeClassName(className)); } const Class& getClass(const Field& field) { return getClassForDesc(field.getDescriptor()->str()); From alkis at cs.uiuc.edu Sat Mar 26 10:44:51 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 10:44:51 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Class.h Class.cpp Message-ID: <200503261644.KAA00443@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.251 -> 1.252 Class.h updated: 1.7 -> 1.8 Class.cpp updated: 1.7 -> 1.8 --- Log message: Resolve and cache class references as well. --- Diffs of the changes: (+35 -27) Class.cpp | 16 ++++++++++++++++ Class.h | 1 + Compiler.cpp | 45 ++++++++++++++++++--------------------------- 3 files changed, 35 insertions(+), 27 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.251 llvm-java/lib/Compiler/Compiler.cpp:1.252 --- llvm-java/lib/Compiler/Compiler.cpp:1.251 Sat Mar 26 09:47:29 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 10:44:40 2005 @@ -1039,7 +1039,7 @@ class_->getClassFile()->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); return getField( - &resolver_->getClass(fieldRef->getClass()->getName()->str()), + class_->getClass(fieldRef->getClassIndex()), nameAndType->getName()->str(), ptr); } @@ -1853,7 +1853,7 @@ return params; } - const VTableInfo* getVTableInfoGeneric(const Class* clazz) { + const VTableInfo* getVTableInfoGeneric(const Class* clazz) { assert(!clazz->isPrimitive() && "Cannot get VTableInfo for primitive class!"); if (clazz->isArray()) { @@ -1874,7 +1874,7 @@ const std::string& className = methodRef->getClass()->getName()->str(); - const Class* clazz = &resolver_->getClass(className); + const Class* clazz = class_->getClass(methodRef->getClassIndex()); const VTableInfo* vi = getVTableInfoGeneric(clazz); const std::string& methodDescr = @@ -1916,7 +1916,7 @@ const std::string& methodDescr = methodName + nameAndType->getDescriptor()->str(); std::string funcName = className + '/' + methodDescr; - const Class& ci = resolver_->getClass(className); + const Class* clazz = class_->getClass(methodRef->getClassIndex()); const FunctionType* funcTy = cast( resolver_->getType(nameAndType->getDescriptor()->str(), true)); @@ -1928,8 +1928,8 @@ void do_invokestatic(unsigned index) { ConstantMethodRef* methodRef = class_->getClassFile()->getConstantMethodRef(index); - emitStaticInitializers( - ClassFile::get(methodRef->getClass()->getName()->str())); + const Class* clazz = class_->getClass(methodRef->getClassIndex()); + emitStaticInitializers(clazz->getClassFile()); Method* method = getMethod(methodRef); Function* function = getFunction(method); // Intercept java/lang/System/loadLibrary() calls and add @@ -1955,7 +1955,7 @@ const std::string& className = methodRef->getClass()->getName()->str(); - const Class* clazz = &resolver_->getClass(className); + const Class* clazz = class_->getClass(methodRef->getClassIndex()); const VTableInfo* vi = getVTableInfoGeneric(clazz); const std::string& methodDescr = @@ -2028,13 +2028,11 @@ } void do_new(unsigned index) { - ConstantClass* classRef = - class_->getClassFile()->getConstantClass(index); - const Class& ci = resolver_->getClass(classRef->getName()->str()); - emitStaticInitializers(ci.getClassFile()); - const VTableInfo& vi = getVTableInfo(ci.getClassFile()); + const Class* clazz = class_->getClass(index); + emitStaticInitializers(clazz->getClassFile()); + const VTableInfo& vi = getVTableInfo(clazz->getClassFile()); - push(allocateObject(ci, vi, currentBB_)); + push(allocateObject(*clazz, vi, currentBB_)); } template @@ -2118,14 +2116,13 @@ void do_anewarray(unsigned index) { Value* count = pop(Type::UIntTy); - // FIXME: Need to do handle different element types. This now - // assumes that all arrays of references are arrays of + // FIXME: Need to handle different element types. This now + // assumes that all arrays of reference type are arrays of // java/lang/Object's. - const Class& clazz = resolver_->getClass("[Ljava/lang/Object;"); - const VTableInfo& vi = - getObjectArrayVTableInfo(clazz.getComponentClass()->getClassFile()); + const Class* clazz = &resolver_->getClass("[Ljava/lang/Object;"); + const VTableInfo* vi = getVTableInfoGeneric(clazz); - push(allocateArray(clazz, vi, count, currentBB_)); + push(allocateArray(*clazz, *vi, count, currentBB_)); } void do_arraylength() { @@ -2143,10 +2140,7 @@ } void do_checkcast(unsigned index) { - ConstantClass* classRef = - class_->getClassFile()->getConstantClass(index); - - const Class* clazz = &resolver_->getClass(classRef->getName()->str()); + const Class* clazz = class_->getClass(index); const VTableInfo* vi = getVTableInfoGeneric(clazz); Value* objRef = pop(resolver_->getObjectBaseRefType()); @@ -2163,10 +2157,7 @@ } void do_instanceof(unsigned index) { - ConstantClass* classRef = - class_->getClassFile()->getConstantClass(index); - - const Class* clazz = &resolver_->getClass(classRef->getName()->str()); + const Class* clazz = class_->getClass(index); const VTableInfo* vi = getVTableInfoGeneric(clazz); Value* objRef = pop(resolver_->getObjectBaseRefType()); Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.7 llvm-java/lib/Compiler/Class.h:1.8 --- llvm-java/lib/Compiler/Class.h:1.7 Sat Mar 26 08:41:48 2005 +++ llvm-java/lib/Compiler/Class.h Sat Mar 26 10:44:40 2005 @@ -77,6 +77,7 @@ int getFieldIndex(const std::string& name) const; llvm::Constant* getConstant(unsigned index) const; + const Class* getClass(unsigned index) const; }; } } // namespace llvm::Java Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.7 llvm-java/lib/Compiler/Class.cpp:1.8 --- llvm-java/lib/Compiler/Class.cpp:1.7 Sat Mar 26 08:41:48 2005 +++ llvm-java/lib/Compiler/Class.cpp Sat Mar 26 10:44:40 2005 @@ -172,3 +172,19 @@ return static_cast(resolvedConstantPool_[index]); } + +const Class* Class::getClass(unsigned index) const +{ + assert(classFile_ && "No constant pool!"); + assert(dynamic_cast(classFile_->getConstant(index)) && + "Not an index to a class reference!"); + + // If we haven't resolved this constant already, do so now. + if (!resolvedConstantPool_[index]) { + ConstantClass* jc = classFile_->getConstantClass(index); + resolvedConstantPool_[index] = + const_cast(&resolver_->getClass(jc->getName()->str())); + } + + return static_cast(resolvedConstantPool_[index]); +} From alkis at cs.uiuc.edu Sat Mar 26 11:15:58 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 11:15:58 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.h Resolver.cpp OperandStack.h Locals.h Locals.cpp Compiler.cpp Class.h Class.cpp Message-ID: <200503261715.LAA00692@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.h updated: 1.3 -> 1.4 Resolver.cpp updated: 1.3 -> 1.4 OperandStack.h updated: 1.4 -> 1.5 Locals.h updated: 1.6 -> 1.7 Locals.cpp updated: 1.11 -> 1.12 Compiler.cpp updated: 1.252 -> 1.253 Class.h updated: 1.8 -> 1.9 Class.cpp updated: 1.8 -> 1.9 --- Log message: I am starting to hate reference members. Make them into pointers. --- Diffs of the changes: (+159 -158) Class.cpp | 32 ++++---- Class.h | 6 - Compiler.cpp | 217 ++++++++++++++++++++++++++++----------------------------- Locals.cpp | 4 - Locals.h | 2 OperandStack.h | 4 - Resolver.cpp | 36 ++++----- Resolver.h | 16 ++-- 8 files changed, 159 insertions(+), 158 deletions(-) Index: llvm-java/lib/Compiler/Resolver.h diff -u llvm-java/lib/Compiler/Resolver.h:1.3 llvm-java/lib/Compiler/Resolver.h:1.4 --- llvm-java/lib/Compiler/Resolver.h:1.3 Sat Mar 26 10:14:29 2005 +++ llvm-java/lib/Compiler/Resolver.h Sat Mar 26 11:15:47 2005 @@ -26,14 +26,14 @@ namespace llvm { namespace Java { class Resolver { - Module& module_; + Module* module_; typedef std::map ClassMap; ClassMap classMap_; unsigned nextInterfaceIndex_; const Type* objectBaseType_; const Type* objectBaseRefType_; - const Class& getClassForDesc(const std::string& descriptor); + const Class* getClassForDesc(const std::string& descriptor); const Type* getTypeHelper(const std::string&, unsigned& i, @@ -47,7 +47,7 @@ } public: - Resolver(Module& module); + Resolver(Module* module); const Type* getObjectBaseType() const { return objectBaseType_; } const Type* getObjectBaseRefType() const { return objectBaseRefType_; } @@ -64,17 +64,17 @@ return !isTwoSlotType(type); } - const Class& getClass(const std::string& className) { + const Class* getClass(const std::string& className) { return getClassForDesc(canonicalizeClassName(className)); } - const Class& getClass(const Field& field) { + const Class* getClass(const Field& field) { return getClassForDesc(field.getDescriptor()->str()); } - const Class& getClass(JType type); - const Class& getArrayClass(JType type); + const Class* getClass(JType type); + const Class* getArrayClass(JType type); unsigned getNextInterfaceIndex() { return nextInterfaceIndex_++; } - Module& getModule() { return module_; } + Module* getModule() { return module_; } }; Index: llvm-java/lib/Compiler/Resolver.cpp diff -u llvm-java/lib/Compiler/Resolver.cpp:1.3 llvm-java/lib/Compiler/Resolver.cpp:1.4 --- llvm-java/lib/Compiler/Resolver.cpp:1.3 Fri Mar 25 22:32:07 2005 +++ llvm-java/lib/Compiler/Resolver.cpp Sat Mar 26 11:15:47 2005 @@ -21,23 +21,23 @@ using namespace llvm; using namespace llvm::Java; -Resolver::Resolver(Module& module) +Resolver::Resolver(Module* module) : module_(module), nextInterfaceIndex_(0), objectBaseType_(OpaqueType::get()), objectBaseRefType_(PointerType::get(objectBaseType_)) { - classMap_.insert(std::make_pair("B", Class(*this, Type::SByteTy))); - classMap_.insert(std::make_pair("C", Class(*this, Type::UShortTy))); - classMap_.insert(std::make_pair("D", Class(*this, Type::DoubleTy))); - classMap_.insert(std::make_pair("F", Class(*this, Type::FloatTy))); - classMap_.insert(std::make_pair("I", Class(*this, Type::IntTy))); - classMap_.insert(std::make_pair("J", Class(*this, Type::LongTy))); - classMap_.insert(std::make_pair("S", Class(*this, Type::ShortTy))); - classMap_.insert(std::make_pair("Z", Class(*this, Type::BoolTy))); - classMap_.insert(std::make_pair("V", Class(*this, Type::VoidTy))); + classMap_.insert(std::make_pair("B", Class(this, Type::SByteTy))); + classMap_.insert(std::make_pair("C", Class(this, Type::UShortTy))); + classMap_.insert(std::make_pair("D", Class(this, Type::DoubleTy))); + classMap_.insert(std::make_pair("F", Class(this, Type::FloatTy))); + classMap_.insert(std::make_pair("I", Class(this, Type::IntTy))); + classMap_.insert(std::make_pair("J", Class(this, Type::LongTy))); + classMap_.insert(std::make_pair("S", Class(this, Type::ShortTy))); + classMap_.insert(std::make_pair("Z", Class(this, Type::BoolTy))); + classMap_.insert(std::make_pair("V", Class(this, Type::VoidTy))); - module_.addTypeName("struct.llvm_java_object_base", objectBaseType_); + module_->addTypeName("struct.llvm_java_object_base", objectBaseType_); } const Type* Resolver::getType(const std::string& descriptor, @@ -88,7 +88,7 @@ return 0; // not reached } -const Class& Resolver::getClassForDesc(const std::string& descriptor) +const Class* Resolver::getClassForDesc(const std::string& descriptor) { ClassMap::iterator it = classMap_.lower_bound(descriptor); if (it == classMap_.end() || it->first != descriptor) { @@ -110,14 +110,14 @@ const std::string& className = descriptor.substr(1, pos - 1); it = classMap_.insert( it, std::make_pair(descriptor, - Class(*this, className))); + Class(this, className))); break; } case '[': { const std::string& componentDescriptor = descriptor.substr(1); it = classMap_.insert( it, std::make_pair(descriptor, - Class(*this, getClassForDesc(componentDescriptor)))); + Class(this, getClassForDesc(componentDescriptor)))); break; } default: @@ -125,14 +125,14 @@ abort(); } it->second.link(); - module_.addTypeName(descriptor, it->second.getStructType()); + module_->addTypeName(descriptor, it->second.getStructType()); DEBUG(std::cerr << "Loaded class: " << descriptor << '\n'); } - return it->second; + return &it->second; } -const Class& Resolver::getClass(JType type) +const Class* Resolver::getClass(JType type) { switch (type) { case BOOLEAN: return getClassForDesc("Z"); @@ -147,7 +147,7 @@ } } -const Class& Resolver::getArrayClass(JType type) +const Class* Resolver::getArrayClass(JType type) { switch (type) { case BOOLEAN: return getClassForDesc("[Z"); Index: llvm-java/lib/Compiler/OperandStack.h diff -u llvm-java/lib/Compiler/OperandStack.h:1.4 llvm-java/lib/Compiler/OperandStack.h:1.5 --- llvm-java/lib/Compiler/OperandStack.h:1.4 Wed Mar 23 22:47:47 2005 +++ llvm-java/lib/Compiler/OperandStack.h Sat Mar 26 11:15:47 2005 @@ -38,8 +38,8 @@ std::vector stack_; public: - explicit OperandStack(const Resolver& resolver, unsigned maxDepth) - : resolver_(&resolver), + explicit OperandStack(const Resolver* resolver, unsigned maxDepth) + : resolver_(resolver), currentDepth_(0), stack_(maxDepth) { } Index: llvm-java/lib/Compiler/Locals.h diff -u llvm-java/lib/Compiler/Locals.h:1.6 llvm-java/lib/Compiler/Locals.h:1.7 --- llvm-java/lib/Compiler/Locals.h:1.6 Wed Mar 23 22:47:47 2005 +++ llvm-java/lib/Compiler/Locals.h Sat Mar 26 11:15:47 2005 @@ -37,7 +37,7 @@ std::vector locals_; public: - Locals(const Resolver& resolver, unsigned maxLocals); + Locals(const Resolver* resolver, unsigned maxLocals); /// @brief - Stores the value \c value on the \c i'th local /// variable and appends any instructions to implement this to \c Index: llvm-java/lib/Compiler/Locals.cpp diff -u llvm-java/lib/Compiler/Locals.cpp:1.11 llvm-java/lib/Compiler/Locals.cpp:1.12 --- llvm-java/lib/Compiler/Locals.cpp:1.11 Wed Mar 23 22:47:47 2005 +++ llvm-java/lib/Compiler/Locals.cpp Sat Mar 26 11:15:47 2005 @@ -23,8 +23,8 @@ using namespace llvm; using namespace llvm::Java; -Locals::Locals(const Resolver& resolver, unsigned maxLocals) - : resolver_(&resolver), +Locals::Locals(const Resolver* resolver, unsigned maxLocals) + : resolver_(resolver), locals_(maxLocals) { Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.252 llvm-java/lib/Compiler/Compiler.cpp:1.253 --- llvm-java/lib/Compiler/Compiler.cpp:1.252 Sat Mar 26 10:44:40 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 11:15:47 2005 @@ -58,7 +58,7 @@ llvm::Constant* LONG_SHIFT_MASK = ConstantUInt::get(Type::UByteTy, 0x3f); class Compiler : public BytecodeParser { - Module& module_; + Module* module_; std::auto_ptr resolver_; GlobalVariable* JNIEnvPtr_; const Class* class_; @@ -98,38 +98,38 @@ Class2VTableInfoMap ac2viMap_; public: - Compiler(Module& m) + Compiler(Module* m) : module_(m), resolver_(new Resolver(module_)), - locals_(*resolver_, 0), - opStack_(*resolver_, 0) { + locals_(resolver_.get(), 0), + opStack_(resolver_.get(), 0) { Type* JNIEnvTy = OpaqueType::get(); - module_.addTypeName("JNIEnv", JNIEnvTy); + module_->addTypeName("JNIEnv", JNIEnvTy); JNIEnvPtr_ = new GlobalVariable(JNIEnvTy, true, GlobalVariable::ExternalLinkage, NULL, "llvm_java_JNIEnv", - &module_); - module_.addTypeName("llvm_java_object_vtable", VTableBaseTy); - getVtable_ = module_.getOrInsertFunction( + module_); + module_->addTypeName("llvm_java_object_vtable", VTableBaseTy); + getVtable_ = module_->getOrInsertFunction( "llvm_java_get_vtable", VTableBaseRefTy, resolver_->getObjectBaseRefType(), NULL); - setVtable_ = module_.getOrInsertFunction( + setVtable_ = module_->getOrInsertFunction( "llvm_java_set_vtable", Type::VoidTy, resolver_->getObjectBaseRefType(), VTableBaseRefTy, NULL); - throw_ = module_.getOrInsertFunction( + throw_ = module_->getOrInsertFunction( "llvm_java_throw", Type::IntTy, resolver_->getObjectBaseRefType(), NULL); - isInstanceOf_ = module_.getOrInsertFunction( + isInstanceOf_ = module_->getOrInsertFunction( "llvm_java_is_instance_of", Type::IntTy, resolver_->getObjectBaseRefType(), VTableBaseRefTy, NULL); - memcpy_ = module_.getOrInsertFunction( + memcpy_ = module_->getOrInsertFunction( "llvm.memcpy", Type::VoidTy, PointerType::get(Type::SByteTy), PointerType::get(Type::SByteTy), Type::ULongTy, Type::UIntTy, NULL); - memset_ = module_.getOrInsertFunction( + memset_ = module_->getOrInsertFunction( "llvm.memset", Type::VoidTy, PointerType::get(Type::SByteTy), Type::UByteTy, Type::ULongTy, Type::UIntTy, NULL); @@ -163,7 +163,7 @@ // contents of this string constant. Value* count = ConstantUInt::get(Type::UIntTy, str.size()); Value* arrayRef = allocateArray(resolver_->getClass("[B"), - getPrimitiveArrayVTableInfo(BYTE), + &getPrimitiveArrayVTableInfo(BYTE), count, ip); // Copy string data. @@ -180,7 +180,7 @@ GlobalVariable::InternalLinkage, init, str + ".str", - &module_); + module_); std::vector params; params.reserve(4); @@ -192,13 +192,13 @@ new CallInst(memcpy_, params, "", ip); // Get class information for java/lang/String. - const Class& ci = resolver_->getClass("java/lang/String"); - const VTableInfo& vi = getVTableInfo(ci.getClassFile()); + const Class* clazz = resolver_->getClass("java/lang/String"); + const VTableInfo* vi = getVTableInfoGeneric(clazz); // Install the vtable pointer. Value* objBase = new CastInst(globalString, resolver_->getObjectBaseRefType(), TMP, ip); - Value* vtable = new CastInst(vi.vtable, VTableBaseRefTy, TMP, ip); + Value* vtable = new CastInst(vi->vtable, VTableBaseRefTy, TMP, ip); new CallInst(setVtable_, objBase, vtable, "", ip); // Initialize it: call java/lang/String/(byte[],int) @@ -296,7 +296,7 @@ // This is a static variable. VTableInfo::TypeInfoTy = StructType::get(elements); - module_.addTypeName(LLVM_JAVA_OBJECT_TYPEINFO, VTableInfo::TypeInfoTy); + module_->addTypeName(LLVM_JAVA_OBJECT_TYPEINFO, VTableInfo::TypeInfoTy); llvm::Constant* typeInfoInit = ConstantStruct::get(VTableInfo::TypeInfoTy, init); @@ -329,7 +329,7 @@ const FunctionType* funcTy = cast( resolver_->getType(method->getDescriptor()->str(), true)); - Function* vfun = module_.getOrInsertFunction(funcName, funcTy); + Function* vfun = module_->getOrInsertFunction(funcName, funcTy); scheduleFunction(vfun); unsigned& index = vi.m2iMap[methodDescr]; @@ -347,13 +347,13 @@ cast(VTtype)->refineAbstractTypeTo(StructType::get(elements)); VTableInfo::VTableTy = cast(holder.get()); - module_.addTypeName("java/lang/Object", VTableInfo::VTableTy); + module_->addTypeName("java/lang/Object", VTableInfo::VTableTy); vi.vtable = new GlobalVariable(VTableInfo::VTableTy, true, GlobalVariable::ExternalLinkage, ConstantStruct::get(init), "java/lang/Object", - &module_); + module_); DEBUG(std::cerr << "Built VTableInfo for: java/lang/Object\n"); return true; } @@ -363,34 +363,34 @@ /// the array. std::pair buildSuperClassesVTables(const ClassFile* cf, const VTableInfo& vi) const { - std::vector superVtables(vi.superVtables.size()); - for (unsigned i = 0, e = vi.superVtables.size(); i != e; ++i) - superVtables[i] = ConstantExpr::getCast( - vi.superVtables[i], - PointerType::get(VTableInfo::VTableTy)); - - llvm::Constant* init = ConstantArray::get( - ArrayType::get(PointerType::get(VTableInfo::VTableTy), - superVtables.size()), - superVtables); - - GlobalVariable* vtablesArray = new GlobalVariable( - init->getType(), - true, - GlobalVariable::ExternalLinkage, - init, - cf->getThisClass()->getName()->str() + "", - &module_); - - return std::make_pair( - vi.superVtables.size(), - ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray)); - } - - /// Builds an interface VTable for the specified - /// pair. - llvm::Constant* buildInterfaceVTable(const ClassFile* cf, - const ClassFile* interface) { + std::vector superVtables(vi.superVtables.size()); + for (unsigned i = 0, e = vi.superVtables.size(); i != e; ++i) + superVtables[i] = ConstantExpr::getCast( + vi.superVtables[i], + PointerType::get(VTableInfo::VTableTy)); + + llvm::Constant* init = ConstantArray::get( + ArrayType::get(PointerType::get(VTableInfo::VTableTy), + superVtables.size()), + superVtables); + + GlobalVariable* vtablesArray = new GlobalVariable( + init->getType(), + true, + GlobalVariable::ExternalLinkage, + init, + cf->getThisClass()->getName()->str() + "", + module_); + + return std::make_pair( + vi.superVtables.size(), + ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray)); + } + + /// Builds an interface VTable for the specified + /// pair. + llvm::Constant* buildInterfaceVTable(const ClassFile* cf, + const ClassFile* interface) { DEBUG(std::cerr << "Building interface vtable: " << interface->getThisClass()->getName()->str() << " for: " << cf->getThisClass()->getName()->str() << '\n'); @@ -428,7 +428,7 @@ const std::string& globalName = cf->getThisClass()->getName()->str() + '+' + interface->getThisClass()->getName()->str() + ""; - module_.addTypeName(globalName, vtable->getType()); + module_->addTypeName(globalName, vtable->getType()); GlobalVariable* gv = new GlobalVariable( vtable->getType(), @@ -436,7 +436,7 @@ GlobalVariable::ExternalLinkage, vtable, globalName, - &module_); + module_); return ConstantExpr::getCast(gv, PointerType::get(VTableInfo::VTableTy)); } @@ -448,8 +448,9 @@ llvm::Constant::getNullValue(PointerType::get(VTableInfo::VTableTy)); assert(interfaceCf->isInterface() && "Classfile must be an interface!"); - const Class& interface = resolver_->getClass(interfaceCf->getThisClass()->getName()->str()); - unsigned index = interface.getInterfaceIndex(); + const Class* interface = + resolver_->getClass(interfaceCf->getThisClass()->getName()->str()); + unsigned index = interface->getInterfaceIndex(); if (index >= vtables.size()) vtables.resize(index+1, nullVTable); // Add this interface's vtable if it was not added before. @@ -475,7 +476,7 @@ // value. if (cf->isInterface()) return std::make_pair( - resolver_->getClass(cf->getThisClass()->getName()->str()).getInterfaceIndex(), + resolver_->getClass(cf->getThisClass()->getName()->str())->getInterfaceIndex(), ConstantExpr::getCast( ConstantIntegral::getAllOnesValue(Type::LongTy), PointerType::get(PointerType::get(VTableInfo::VTableTy)))); @@ -508,7 +509,7 @@ llvm::Constant* init = ConstantArray::get( ArrayType::get(PointerType::get(VTableInfo::VTableTy), vtables.size()), vtables); - module_.addTypeName(globalName, init->getType()); + module_->addTypeName(globalName, init->getType()); GlobalVariable* interfacesArray = new GlobalVariable( init->getType(), @@ -516,7 +517,7 @@ GlobalVariable::ExternalLinkage, init, globalName, - &module_); + module_); return std::make_pair( int(vtables.size())-1, @@ -642,7 +643,7 @@ if (cf->isInterface() || method->isAbstract()) vfun = llvm::Constant::getNullValue(PointerType::get(funcTy)); else { - vfun = module_.getOrInsertFunction(funcName, funcTy); + vfun = module_->getOrInsertFunction(funcName, funcTy); scheduleFunction(cast(vfun)); } @@ -663,13 +664,13 @@ const std::string& globalName = className + ""; llvm::Constant* vtable = ConstantStruct::get(init); - module_.addTypeName(globalName, vtable->getType()); + module_->addTypeName(globalName, vtable->getType()); vi.vtable = new GlobalVariable(vtable->getType(), true, GlobalVariable::ExternalLinkage, vtable, globalName, - &module_); + module_); // Now the vtable is complete, install the new typeinfo block // for this class: we install it last because we need the vtable @@ -715,13 +716,13 @@ elementTy->getDescription() + "[]"; llvm::Constant* vtable = ConstantStruct::get(init); - module_.addTypeName(globalName, vtable->getType()); + module_->addTypeName(globalName, vtable->getType()); vi.vtable = new GlobalVariable(vtable->getType(), true, GlobalVariable::ExternalLinkage, vtable, globalName, - &module_); + module_); // Construct the typeinfo now. std::vector typeInfoInit; @@ -737,7 +738,7 @@ GlobalVariable::ExternalLinkage, ConstantArray::get(vtablesArrayTy, vi.superVtables), elementTy->getDescription() + "[]", - &module_); + module_); typeInfoInit.push_back(ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray)); typeInfoInit.push_back(ConstantSInt::get(Type::IntTy, 0)); @@ -841,7 +842,7 @@ GlobalVariable::ExternalLinkage, ConstantArray::get(vtablesArrayTy, vi.superVtables), "java/lang/Object[]", - &module_); + module_); init.push_back(ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray)); // last interface index @@ -875,13 +876,13 @@ vi.m2iMap = javaLangObjectVI.m2iMap; llvm::Constant* vtable = ConstantStruct::get(init); - module_.addTypeName("java/lang/Object[]", vtable->getType()); + module_->addTypeName("java/lang/Object[]", vtable->getType()); vi.vtable = new GlobalVariable(VTableInfo::VTableTy, true, GlobalVariable::ExternalLinkage, vtable, "java/lang/Object[]", - &module_); + module_); DEBUG(std::cerr << "Built VTableInfo for: java/lang/Object[]\n"); return true; } @@ -932,13 +933,13 @@ const std::string& globalName = className + "[]"; llvm::Constant* vtable = ConstantStruct::get(init); - module_.addTypeName(globalName, vtable->getType()); + module_->addTypeName(globalName, vtable->getType()); vi.vtable = new GlobalVariable(vtable->getType(), true, GlobalVariable::ExternalLinkage, vtable, globalName, - &module_); + module_); // Now the vtable is complete, install the new typeinfo block // for this class: we install it last because we need the vtable @@ -959,7 +960,7 @@ GlobalVariable::ExternalLinkage, ConstantArray::get(vtablesArrayTy, vi.superVtables), className + "[]", - &module_); + module_); typeInfoInit.push_back(ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray)); // last interface index @@ -1011,7 +1012,7 @@ const std::string& globalName = className + '/' + name; DEBUG(std::cerr << "Looking up global: " << globalName << '\n'); - GlobalVariable* global = module_.getGlobalVariable(globalName, type); + GlobalVariable* global = module_->getGlobalVariable(globalName, type); if (global) return global; @@ -1093,7 +1094,7 @@ Method* method = getMethod(classMethodDesc); const std::string& className = method->getParent()->getThisClass()->getName()->str(); - class_ = &resolver_->getClass(className); + class_ = resolver_->getClass(className); Function* function = getFunction(method); if (!function->empty()) { @@ -1120,7 +1121,7 @@ descr.begin() + descr.find(')'))); } - Function* jniFunction = module_.getOrInsertFunction(funcName,jniFuncTy); + Function* jniFunction = module_->getOrInsertFunction(funcName,jniFuncTy); BasicBlock* bb = new BasicBlock("entry", function); std::vector params; @@ -1182,7 +1183,7 @@ bbBuilder_.reset(new BasicBlockBuilder(function, codeAttr)); // Put arguments into locals. - locals_ = Locals(*resolver_, codeAttr->getMaxLocals()); + locals_ = Locals(resolver_.get(), codeAttr->getMaxLocals()); unsigned index = 0; for (Function::arg_iterator a = function->arg_begin(), @@ -1199,7 +1200,7 @@ // NOTE: We create an operand stack one size too big because we // push extra values on the stack to simplify code generation // (see implementation of ifne). - opStack_ = OperandStack(*resolver_, codeAttr->getMaxStack()+2); + opStack_ = OperandStack(resolver_.get(), codeAttr->getMaxStack()+2); opStackDepthMap_.insert(std::make_pair(bb0, 0)); // Insert bb0 in the work list. @@ -1281,7 +1282,7 @@ const std::string& className = classfile->getThisClass()->getName()->str(); - const Class& clazz = resolver_->getClass(className); + const Class* clazz = resolver_->getClass(className); // Create the global variables of this class. const Fields& fields = classfile->getFields(); @@ -1297,7 +1298,7 @@ llvm::Constant* init = llvm::Constant::getNullValue(globalTy); if (field->getConstantValueAttribute()) { unsigned i = field->getConstantValueAttribute()->getValueIndex(); - init = ConstantExpr::getCast(clazz.getConstant(i), globalTy); + init = ConstantExpr::getCast(clazz->getConstant(i), globalTy); isConstant = field->isFinal(); } @@ -1310,26 +1311,26 @@ GlobalVariable::ExternalLinkage, init, globalName, - &module_); + module_); } } - Function* hook = module_.getOrInsertFunction(LLVM_JAVA_STATIC_INIT, - Type::VoidTy, 0); + Function* hook = module_->getOrInsertFunction(LLVM_JAVA_STATIC_INIT, + Type::VoidTy, 0); Instruction* I = hook->front().getTerminator(); assert(I && LLVM_JAVA_STATIC_INIT " should have a terminator!"); // Create constant strings for this class. for (unsigned i = 0, e = classfile->getNumConstants(); i != e; ++i) if (ConstantString* s = dynamic_cast(classfile->getConstant(i))) - initializeString(clazz.getConstant(i), s->getValue()->str(), I); + initializeString(clazz->getConstant(i), s->getValue()->str(), I); // Call its class initialization method if it exists. if (const Method* method = classfile->getMethod("()V")) { const std::string& functionName = className + '/' + method->getName()->str() + method->getDescriptor()->str(); Function* init = - module_.getOrInsertFunction(functionName, Type::VoidTy, 0); + module_->getOrInsertFunction(functionName, Type::VoidTy, 0); // Insert a call to it right before the terminator of the only // basic block in llvm_java_static_init. @@ -1352,7 +1353,7 @@ clazz->getThisClass()->getName()->str() + '/' + method->getName()->str() + method->getDescriptor()->str(); - Function* function = module_.getOrInsertFunction(funcName, funcTy); + Function* function = module_->getOrInsertFunction(funcName, funcTy); return function; } @@ -1397,7 +1398,7 @@ Function* compileMethod(const std::string& classMethodDesc) { // Initialize the static initializer function. Function* staticInit = - module_.getOrInsertFunction(LLVM_JAVA_STATIC_INIT, Type::VoidTy, 0); + module_->getOrInsertFunction(LLVM_JAVA_STATIC_INIT, Type::VoidTy, 0); BasicBlock* staticInitBB = new BasicBlock("entry", staticInit); new ReturnInst(NULL, staticInitBB); @@ -1466,10 +1467,10 @@ void do_saload() { do_aload_common("[S"); } void do_aload_common(const std::string& className) { - const Class& arrayClass = resolver_->getClass(className); - assert(arrayClass.isArray() && "Not an array class!"); + const Class* arrayClass = resolver_->getClass(className); + assert(arrayClass->isArray() && "Not an array class!"); Value* index = pop(Type::IntTy); - Value* arrayRef = pop(arrayClass.getType()); + Value* arrayRef = pop(arrayClass->getType()); std::vector indices; indices.reserve(3); @@ -1503,12 +1504,12 @@ void do_sastore() { do_astore_common("[S"); } void do_astore_common(const std::string& className) { - const Class& arrayClass = resolver_->getClass(className); - assert(arrayClass.isArray() && "Not an array class!"); - const Class& componentClass = *arrayClass.getComponentClass(); - Value* value = pop(componentClass.getType()); + const Class* arrayClass = resolver_->getClass(className); + assert(arrayClass->isArray() && "Not an array class!"); + const Class* componentClass = arrayClass->getComponentClass(); + Value* value = pop(componentClass->getType()); Value* index = pop(Type::IntTy); - Value* arrayRef = pop(arrayClass.getType()); + Value* arrayRef = pop(arrayClass->getType()); std::vector indices; indices.reserve(3); @@ -1675,7 +1676,7 @@ Value* r = new SelectInst(c, ONE, ZERO, TMP, currentBB_); c = BinaryOperator::createSetLT(v1, v2, TMP, currentBB_); r = new SelectInst(c, MINUS_ONE, r, TMP, currentBB_); - c = new CallInst(module_.getOrInsertFunction + c = new CallInst(module_->getOrInsertFunction ("llvm.isunordered", Type::BoolTy, v1->getType(), v2->getType(), 0), v1, v2, TMP, currentBB_); @@ -1920,7 +1921,7 @@ const FunctionType* funcTy = cast( resolver_->getType(nameAndType->getDescriptor()->str(), true)); - Function* function = module_.getOrInsertFunction(funcName, funcTy); + Function* function = module_->getOrInsertFunction(funcName, funcTy); scheduleFunction(function); makeCall(function, getParams(funcTy)); } @@ -2056,15 +2057,15 @@ } template - Value* allocateArray(const Class& clazz, - const VTableInfo& vi, + Value* allocateArray(const Class* clazz, + const VTableInfo* vi, Value* count, InsertionPointTy* ip) { static std::vector params(4); - assert(clazz.isArray() && "Not an array class!"); - const Class& componentClass = *clazz.getComponentClass(); - const Type* elementTy = componentClass.getType(); + assert(clazz->isArray() && "Not an array class!"); + const Class* componentClass = clazz->getComponentClass(); + const Type* elementTy = componentClass->getType(); // The size of the element. llvm::Constant* elementSize = @@ -2075,7 +2076,7 @@ Instruction::Mul, count, elementSize, TMP, ip); // The size of the rest of the array object. llvm::Constant* arrayObjectSize = - ConstantExpr::getCast(ConstantExpr::getSizeOf(clazz.getStructType()), + ConstantExpr::getCast(ConstantExpr::getSizeOf(clazz->getStructType()), Type::UIntTy); // Add the array part plus the object part together. @@ -2090,7 +2091,7 @@ new CallInst(memset_, params, "", ip); // Cast back to array type. - objRef = new CastInst(objRef, clazz.getType(), TMP, ip); + objRef = new CastInst(objRef, clazz->getType(), TMP, ip); // Store the size. Value* lengthPtr = getArrayLengthPtr(objRef, ip); @@ -2098,7 +2099,7 @@ // Install the vtable pointer. Value* objBase = new CastInst(objRef, resolver_->getObjectBaseRefType(), TMP, ip); - Value* vtable = new CastInst(vi.vtable, VTableBaseRefTy, TMP, ip); + Value* vtable = new CastInst(vi->vtable, VTableBaseRefTy, TMP, ip); new CallInst(setVtable_, objBase, vtable, "", ip); return objRef; @@ -2107,8 +2108,8 @@ void do_newarray(JType type) { Value* count = pop(Type::UIntTy); - const Class& clazz = resolver_->getArrayClass(type); - const VTableInfo& vi = getPrimitiveArrayVTableInfo(type); + const Class* clazz = resolver_->getArrayClass(type); + const VTableInfo* vi = getVTableInfoGeneric(clazz); push(allocateArray(clazz, vi, count, currentBB_)); } @@ -2119,15 +2120,15 @@ // FIXME: Need to handle different element types. This now // assumes that all arrays of reference type are arrays of // java/lang/Object's. - const Class* clazz = &resolver_->getClass("[Ljava/lang/Object;"); + const Class* clazz = resolver_->getClass("[Ljava/lang/Object;"); const VTableInfo* vi = getVTableInfoGeneric(clazz); - push(allocateArray(*clazz, *vi, count, currentBB_)); + push(allocateArray(clazz, vi, count, currentBB_)); } void do_arraylength() { - const Class& clazz = resolver_->getClass("[Ljava/lang/Object;"); - Value* arrayRef = pop(clazz.getType()); + const Class* clazz = resolver_->getClass("[Ljava/lang/Object;"); + Value* arrayRef = pop(clazz->getType()); Value* lengthPtr = getArrayLengthPtr(arrayRef, currentBB_); Value* length = new LoadInst(lengthPtr, TMP, currentBB_); push(length); @@ -2195,7 +2196,7 @@ // Require the Java runtime. m->addLibrary("jrt"); - Compiler c(*m); + Compiler c(m.get()); Function* main = c.compileMethod(className + "/main([Ljava/lang/String;)V"); Function* javaMain = m->getOrInsertFunction ("llvm_java_main", Type::VoidTy, Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.8 llvm-java/lib/Compiler/Class.h:1.9 --- llvm-java/lib/Compiler/Class.h:1.8 Sat Mar 26 10:44:40 2005 +++ llvm-java/lib/Compiler/Class.h Sat Mar 26 11:15:47 2005 @@ -50,13 +50,13 @@ // Resolver interface. // Load primitive class for type. - Class(Resolver& resolver, const Type* type); + Class(Resolver* resolver, const Type* type); // Load class by name. - Class(Resolver& resolver, const std::string& className); + Class(Resolver* resolver, const std::string& className); // Load array class of component the passed class. - Class(Resolver& resolver, const Class& componentClass); + Class(Resolver* resolver, const Class* componentClass); // Link the class. void link(); Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.8 llvm-java/lib/Compiler/Class.cpp:1.9 --- llvm-java/lib/Compiler/Class.cpp:1.8 Sat Mar 26 10:44:40 2005 +++ llvm-java/lib/Compiler/Class.cpp Sat Mar 26 11:15:47 2005 @@ -26,8 +26,8 @@ using namespace llvm; using namespace llvm::Java; -Class::Class(Resolver& resolver, const std::string& className) - : resolver_(&resolver), +Class::Class(Resolver* resolver, const std::string& className) + : resolver_(resolver), classFile_(ClassFile::get(className)), superClass_(NULL), componentClass_(NULL), @@ -39,11 +39,11 @@ } -Class::Class(Resolver& resolver, const Class& componentClass) - : resolver_(&resolver), +Class::Class(Resolver* resolver, const Class* componentClass) + : resolver_(resolver), classFile_(NULL), superClass_(NULL), - componentClass_(&componentClass), + componentClass_(componentClass), structType_(OpaqueType::get()), type_(PointerType::get(structType_)), interfaceIndex_(INVALID_INTERFACE_INDEX) @@ -51,8 +51,8 @@ } -Class::Class(Resolver& resolver, const Type* type) - : resolver_(&resolver), +Class::Class(Resolver* resolver, const Type* type) + : resolver_(resolver), classFile_(NULL), superClass_(NULL), componentClass_(NULL), @@ -87,7 +87,7 @@ assert(!isPrimitive() && "Should not link primitive classes!"); if (isArray()) { - superClass_ = &resolver_->getClass("java/lang/Object"); + superClass_ = resolver_->getClass("java/lang/Object"); addField("super", superClass_->getStructType()); addField("", Type::UIntTy); addField("", ArrayType::get(componentClass_->getType(), 0)); @@ -95,11 +95,11 @@ else { // This is any class but java/lang/Object. if (classFile_->getSuperClass()) { - const Class& superClass = + const Class* superClass = resolver_->getClass(classFile_->getSuperClass()->getName()->str()); // We first add the struct of the super class. - addField("super", superClass.getStructType()); + addField("super", superClass->getStructType()); // Although we can safely assume that all interfaces inherits // from java/lang/Object, java/lang/Class.getSuperclass() @@ -110,7 +110,7 @@ if (classFile_->isInterface()) interfaceIndex_ = resolver_->getNextInterfaceIndex(); else - superClass_ = &superClass; + superClass_ = superClass; } // This is java/lang/Object. else @@ -121,7 +121,7 @@ for (unsigned i = 0, e = fields.size(); i != e; ++i) { Field& field = *fields[i]; if (!field.isStatic()) - addField(field.getName()->str(), resolver_->getClass(field).getType()); + addField(field.getName()->str(), resolver_->getClass(field)->getType()); } } @@ -144,15 +144,15 @@ if (!resolvedConstantPool_[index]) { Constant* jc = classFile_->getConstant(index); if (ConstantString* s = dynamic_cast(jc)) { - const Class& stringClass = resolver_->getClass("java/lang/String"); - const Type* stringType = stringClass.getStructType(); + const Class* stringClass = resolver_->getClass("java/lang/String"); + const Type* stringType = stringClass->getStructType(); resolvedConstantPool_[index] = new GlobalVariable(stringType, false, GlobalVariable::LinkOnceLinkage, llvm::Constant::getNullValue(stringType), s->getValue()->str() + ".java/lang/String", - &resolver_->getModule()); + resolver_->getModule()); } else if (ConstantInteger* i = dynamic_cast(jc)) resolvedConstantPool_[index] = @@ -183,7 +183,7 @@ if (!resolvedConstantPool_[index]) { ConstantClass* jc = classFile_->getConstantClass(index); resolvedConstantPool_[index] = - const_cast(&resolver_->getClass(jc->getName()->str())); + const_cast(resolver_->getClass(jc->getName()->str())); } return static_cast(resolvedConstantPool_[index]); From alkis at cs.uiuc.edu Sat Mar 26 13:14:14 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 13:14:14 -0600 Subject: [llvm-commits] CVS: llvm-java/tools/classdump/classdump.cpp Message-ID: <200503261914.NAA01430@zion.cs.uiuc.edu> Changes in directory llvm-java/tools/classdump: classdump.cpp updated: 1.20 -> 1.21 --- Log message: Expose ConstantClass indices. --- Diffs of the changes: (+4 -5) classdump.cpp | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) Index: llvm-java/tools/classdump/classdump.cpp diff -u llvm-java/tools/classdump/classdump.cpp:1.20 llvm-java/tools/classdump/classdump.cpp:1.21 --- llvm-java/tools/classdump/classdump.cpp:1.20 Wed Mar 23 19:04:28 2005 +++ llvm-java/tools/classdump/classdump.cpp Sat Mar 26 13:14:02 2005 @@ -60,11 +60,10 @@ if (ConstantClass* super = CF->getSuperClass()) Out << "extends " << super->getName()->str() << ' '; - if (!CF->getInterfaces().empty()) { - const Classes& interfaces = CF->getInterfaces(); - Out << "implements " << interfaces[0]->getName()->str(); - for (unsigned i = 1, e = interfaces.size(); i != e; ++i) - Out << ", " << interfaces[i]->getName()->str(); + if (CF->getNumInterfaces()) { + Out << "implements " << CF->getInterface(0)->getName()->str(); + for (unsigned i = 1, e = CF->getNumInterfaces(); i != e; ++i) + Out << ", " << CF->getInterface(i)->getName()->str(); Out << ' '; } Out << "{\n"; From alkis at cs.uiuc.edu Sat Mar 26 13:14:14 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 13:14:14 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503261914.NAA01434@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.253 -> 1.254 --- Log message: Expose ConstantClass indices. --- Diffs of the changes: (+10 -12) Compiler.cpp | 22 ++++++++++------------ 1 files changed, 10 insertions(+), 12 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.253 llvm-java/lib/Compiler/Compiler.cpp:1.254 --- llvm-java/lib/Compiler/Compiler.cpp:1.253 Sat Mar 26 11:15:47 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 13:14:02 2005 @@ -456,10 +456,10 @@ // Add this interface's vtable if it was not added before. if (vtables[index] == nullVTable) { vtables[index] = buildInterfaceVTable(cf, interfaceCf); - const Classes& interfaces = interfaceCf->getInterfaces(); - for (unsigned i = 0, e = interfaces.size(); i != e; ++i) { + unsigned numInterface = interfaceCf->getNumInterfaces(); + for (unsigned i = 0, e = interfaceCf->getNumInterfaces(); i != e; ++i) { const ClassFile* superInterface = - ClassFile::get(interfaces[i]->getName()->str()); + ClassFile::get(interfaceCf->getInterface(i)->getName()->str()); insertVtablesForInterface(vtables, cf, superInterface); } } @@ -492,10 +492,9 @@ const ClassFile* curCf = cf; while (true) { - const Classes& interfaces = curCf->getInterfaces(); - for (unsigned i = 0, e = interfaces.size(); i != e; ++i) { + for (unsigned i = 0, e = curCf->getNumInterfaces(); i != e; ++i) { const ClassFile* ifaceCf = - ClassFile::get(interfaces[i]->getName()->str()); + ClassFile::get(curCf->getInterface(i)->getName()->str()); insertVtablesForInterface(vtables, cf, ifaceCf); } if (!curCf->getSuperClass()) @@ -587,10 +586,9 @@ // If this is an interface, add all methods from each interface // this inherits from. if (cf->isInterface()) { - const Classes& ifaces = cf->getInterfaces(); - for (unsigned i = 0, e = ifaces.size(); i != e; ++i) { + for (unsigned i = 0, e = cf->getNumInterfaces(); i != e; ++i) { const ClassFile* ifaceCF = - ClassFile::get(ifaces[i]->getName()->str()); + ClassFile::get(cf->getInterface(i)->getName()->str()); const VTableInfo& ifaceVI = getVTableInfo(ifaceCF); ConstantStruct* ifaceInit = cast(ifaceVI.vtable->getInitializer()); @@ -1016,9 +1014,9 @@ if (global) return global; - const Classes& ifaces = cf->getInterfaces(); - for (unsigned i = 0, e = ifaces.size(); i != e; ++i) { - const ClassFile* ifaceCF = ClassFile::get(ifaces[i]->getName()->str()); + for (unsigned i = 0, e = cf->getNumInterfaces(); i != e; ++i) { + const ClassFile* ifaceCF = + ClassFile::get(cf->getInterface(i)->getName()->str()); if (global = getStaticField(ifaceCF, name, type)) return global; } From alkis at cs.uiuc.edu Sat Mar 26 13:14:14 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 13:14:14 -0600 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200503261914.NAA01442@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.34 -> 1.35 --- Log message: Expose ConstantClass indices. --- Diffs of the changes: (+12 -5) ClassFile.h | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.34 llvm-java/include/llvm/Java/ClassFile.h:1.35 --- llvm-java/include/llvm/Java/ClassFile.h:1.34 Sat Mar 26 08:08:38 2005 +++ llvm-java/include/llvm/Java/ClassFile.h Sat Mar 26 13:14:02 2005 @@ -60,7 +60,6 @@ }; typedef std::vector ConstantPool; - typedef std::vector Classes; typedef std::vector Fields; typedef std::vector Methods; typedef std::vector Attributes; @@ -107,7 +106,11 @@ return superClassIdx_ ? getConstantClass(superClassIdx_) : NULL; } - const Classes& getInterfaces() const { return interfaces_; } + unsigned getNumInterfaces() const { return interfaces_.size(); } + unsigned getInterfaceIndex(unsigned i) const { return interfaces_[i]; } + ConstantClass* getInterface(unsigned i) const { + return getConstantClass(getInterfaceIndex(i)); + } const Fields& getFields() const { return fields_; } @@ -127,7 +130,7 @@ uint16_t accessFlags_; uint16_t thisClassIdx_; uint16_t superClassIdx_; - Classes interfaces_; + std::vector interfaces_; Fields fields_; Methods methods_; Attributes attributes_; @@ -471,14 +474,18 @@ class ExceptionsAttribute : public Attribute { private: uint16_t nameIdx_; - Classes exceptions_; + std::vector exceptions_; public: ExceptionsAttribute(const ClassFile* cf, uint16_t nameIdx, std::istream& is); - const Classes& getExceptions() const { return exceptions_; } + unsigned getNumExceptions() const { return exceptions_.size(); } + unsigned getExceptionIndex(unsigned i) const { return exceptions_[i]; } + ConstantClass* getException(unsigned i) const { + return parent_->getConstantClass(getExceptionIndex(i)); + } std::ostream& dump(std::ostream& os) const; }; From alkis at cs.uiuc.edu Sat Mar 26 13:14:14 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 13:14:14 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Message-ID: <200503261914.NAA01438@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp updated: 1.43 -> 1.44 --- Log message: Expose ConstantClass indices. --- Diffs of the changes: (+19 -41) ClassFile.cpp | 60 ++++++++++++++++++---------------------------------------- 1 files changed, 19 insertions(+), 41 deletions(-) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.43 llvm-java/lib/ClassFile/ClassFile.cpp:1.44 --- llvm-java/lib/ClassFile/ClassFile.cpp:1.43 Sat Mar 26 08:08:38 2005 +++ llvm-java/lib/ClassFile/ClassFile.cpp Sat Mar 26 13:14:02 2005 @@ -84,20 +84,6 @@ return tmp.out; } - void readClasses(Classes& i, const ClassFile* cf, std::istream& is) - { - assert(i.empty() && - "Should not call with a non-empty classes vector"); - uint16_t count = readU2(is); - i.reserve(count); - while (count--) { - ConstantClass* c = cf->getConstantClass(readU2(is)); - if (!c) - throw ClassFileSemanticError("ConstantClass expected"); - i.push_back(c); - } - } - void readFields(Fields& f, const ClassFile* parent, std::istream& is) { assert(f.empty() && "Should not call with a non-empty fields vector"); @@ -126,20 +112,6 @@ a.push_back(Attribute::readAttribute(cf, is)); } - template - std::ostream& dumpCollection(Container& c, - const char* const name, - std::ostream& os) { - os << '\n' << name << "s:\n"; - for (typename Container::const_iterator - i = c.begin(), e = c.end(); i != e; ++i) - if (*i) - (*i)->dump(os << name << ' ') << '\n'; - else - os << name << " NULL\n"; - return os; - } - } //===----------------------------------------------------------------------===// @@ -228,7 +200,11 @@ accessFlags_ = readU2(is); thisClassIdx_ = readU2(is); superClassIdx_ = readU2(is); - readClasses(interfaces_, this, is); + count = readU2(is); + interfaces_.reserve(count); + while (count--) + interfaces_.push_back(readU2(is)); + readFields(fields_, this, is); readMethods(methods_, this, is); readAttributes(attributes_, this, is); @@ -329,10 +305,10 @@ if (isInterface()) os << " interface"; if (isAbstract()) os << " abstract"; - dumpCollection(interfaces_, "Interface", os); - dumpCollection(fields_, "Field", os); - dumpCollection(methods_, "Method", os); - dumpCollection(attributes_, "Attribute", os); +// dumpCollection(interfaces_, "Interface", os); +// dumpCollection(fields_, "Field", os); +// dumpCollection(methods_, "Method", os); +// dumpCollection(attributes_, "Attribute", os); return os; } @@ -587,7 +563,7 @@ if (isVolatile()) os << " volatile"; if (isTransient()) os << " transient"; - dumpCollection(attributes_, "Attribute", os); +// dumpCollection(attributes_, "Attribute", os); return os; } @@ -627,7 +603,7 @@ if (isNative()) os << " native"; if (isStrict()) os << " strict"; - dumpCollection(attributes_, "Attribute", os); +// dumpCollection(attributes_, "Attribute", os); return os; } @@ -747,8 +723,8 @@ << "Max stack: " << maxStack_ << '\n' << "Max locals: " << maxLocals_ << '\n' << "Code size: " << codeSize_ << '\n'; - dumpCollection(exceptions_, "Exception", os); - dumpCollection(attributes_, "Attribute", os); +// dumpCollection(exceptions_, "Exception", os); +// dumpCollection(attributes_, "Attribute", os); return os; } @@ -784,14 +760,16 @@ : Attribute(cf, nameIdx, is) { uint32_t length = readU4(is); - readClasses(exceptions_, cf, is); + uint16_t count = readU2(is); + exceptions_.reserve(count); + while (count--) + exceptions_.push_back(readU2(is)); } std::ostream& ExceptionsAttribute::dump(std::ostream& os) const { os << Attribute::dump(os) << ": "; - for (Classes::const_iterator - i = exceptions_.begin(), e = exceptions_.end(); i != e; ++i) - os << *i << ' '; + for (unsigned i = 0, e = getNumExceptions(); i != e; ++i) + os << *getException(i) << ' '; return os; } From lattner at cs.uiuc.edu Sat Mar 26 15:50:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 15:50:05 -0600 Subject: [llvm-commits] CVS: llvm-test/TEST.dsprecision.Makefile TEST.dsprecision.report Message-ID: <200503262150.j2QLo5kE001407@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsprecision.Makefile updated: 1.1 -> 1.2 TEST.dsprecision.report updated: 1.2 -> 1.3 --- Log message: Add ALL mod/ref info --- Diffs of the changes: (+44 -2) TEST.dsprecision.Makefile | 24 ++++++++++++++++++++++++ TEST.dsprecision.report | 22 ++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) Index: llvm-test/TEST.dsprecision.Makefile diff -u llvm-test/TEST.dsprecision.Makefile:1.1 llvm-test/TEST.dsprecision.Makefile:1.2 --- llvm-test/TEST.dsprecision.Makefile:1.1 Thu Mar 17 13:59:05 2005 +++ llvm-test/TEST.dsprecision.Makefile Sat Mar 26 15:49:49 2005 @@ -16,6 +16,12 @@ -($(LOPT) -basicaa -aa-eval -disable-output $<) > Output/$*.basicaa.out 2>&1 @echo -n "BASIC MA: " >> $@ - at grep 'may alias responses' Output/$*.basicaa.out >> $@ + @echo -n "BASIC NOMR: " >> $@ + - at grep 'no mod/ref responses' Output/$*.basicaa.out >> $@ + @echo -n "BASIC JUSTREF: " >> $@ + - at grep '[0-9] ref responses' Output/$*.basicaa.out >> $@ + @echo -n "BASIC JUSTMOD: " >> $@ + - at grep 'mod responses' Output/$*.basicaa.out >> $@ @echo -n "BASIC MR: " >> $@ - at grep 'mod & ref responses' Output/$*.basicaa.out >> $@ @ @@ -23,17 +29,35 @@ -disable-output $<) > Output/$*.steensfiaa.out 2>&1 @echo -n "STEENS-FI MA: " >> $@ - at grep 'may alias responses' Output/$*.steensfiaa.out >> $@ + @echo -n "STEENS-FI NOMR: " >> $@ + - at grep 'no mod/ref responses' Output/$*.steensfiaa.out >> $@ + @echo -n "STEENS-FI JUSTREF: " >> $@ + - at grep '[0-9] ref responses' Output/$*.steensfiaa.out >> $@ + @echo -n "STEENS-FI JUSTMOD: " >> $@ + - at grep 'mod responses' Output/$*.steensfiaa.out >> $@ @echo -n "STEENS-FI MR: " >> $@ - at grep 'mod & ref responses' Output/$*.steensfiaa.out >> $@ @ -($(LOPT) -steens-aa -aa-eval -disable-output $<) > Output/$*.steensfsaa.out 2>&1 @echo -n "STEENS-FS MA: " >> $@ - at grep 'may alias responses' Output/$*.steensfsaa.out >> $@ + @echo -n "STEENS-FS NOMR: " >> $@ + - at grep 'no mod/ref responses' Output/$*.steensfsaa.out >> $@ + @echo -n "STEENS-FS JUSTREF: " >> $@ + - at grep '[0-9] ref responses' Output/$*.steensfsaa.out >> $@ + @echo -n "STEENS-FS JUSTMOD: " >> $@ + - at grep 'mod responses' Output/$*.steensfsaa.out >> $@ @echo -n "STEENS-FS MR: " >> $@ - at grep 'mod & ref responses' Output/$*.steensfsaa.out >> $@ -($(LOPT) -ds-aa -aa-eval -disable-output $<) > Output/$*.dsaa.out 2>&1 @echo -n "DS MA: " >> $@ - at grep 'may alias responses' Output/$*.dsaa.out >> $@ + @echo -n "DS NOMR: " >> $@ + - at grep 'no mod/ref responses' Output/$*.dsaa.out >> $@ + @echo -n "DS JUSTREF: " >> $@ + - at grep '[0-9] ref responses' Output/$*.dsaa.out >> $@ + @echo -n "DS JUSTMOD: " >> $@ + - at grep 'mod responses' Output/$*.dsaa.out >> $@ @echo -n "DS MR: " >> $@ - at grep 'mod & ref responses' Output/$*.dsaa.out >> $@ Index: llvm-test/TEST.dsprecision.report diff -u llvm-test/TEST.dsprecision.report:1.2 llvm-test/TEST.dsprecision.report:1.3 --- llvm-test/TEST.dsprecision.report:1.2 Tue Mar 22 23:39:15 2005 +++ llvm-test/TEST.dsprecision.report Sat Mar 26 15:49:49 2005 @@ -31,16 +31,34 @@ # Name ["Name:", '\'([^\']+)\' Program'], [], -# AA Precision +# AA MayAlias Query Percents ["basic", 'BASIC MA:.* \((.*)\)'], ["steens-fi", 'STEENS-FI MA:.* \((.*)\)'], ["steens-fs", 'STEENS-FS MA:.* \((.*)\)'], ["ds", 'DS MA:.* \((.*)\)'], [], -# MR Precision +# Mod&Ref percents ["basic", 'BASIC MR:.* \((.*)\)'], ["steens-fi", 'STEENS-FI MR:.* \((.*)\)'], ["steens-fs", 'STEENS-FS MR:.* \((.*)\)'], ["ds", 'DS MR:.* \((.*)\)'], [], +# Mod Percents + ["basic", 'BASIC JUSTMOD:.* \((.*)\)'], + ["steens-fi", 'STEENS-FI JUSTMOD:.* \((.*)\)'], + ["steens-fs", 'STEENS-FS JUSTMOD:.* \((.*)\)'], + ["ds", 'DS JUSTMOD:.* \((.*)\)'], + [], +# Ref Percents + ["basic", 'BASIC JUSTREF:.* \((.*)\)'], + ["steens-fi", 'STEENS-FI JUSTREF:.* \((.*)\)'], + ["steens-fs", 'STEENS-FS JUSTREF:.* \((.*)\)'], + ["ds", 'DS JUSTREF:.* \((.*)\)'], + [], +# No Mod/Ref Percents + ["basic", 'BASIC NOMR:.* \((.*)\)'], + ["steens-fi", 'STEENS-FI NOMR:.* \((.*)\)'], + ["steens-fs", 'STEENS-FS NOMR:.* \((.*)\)'], + ["ds", 'DS NOMR:.* \((.*)\)'], + [], ); From lattner at cs.uiuc.edu Sat Mar 26 16:16:57 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 16:16:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200503262216.j2QMGv3Q001652@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp updated: 1.23 -> 1.24 --- Log message: Interchange this loop so that we test all pointers against one call site before moving on to the next call site. This will be a more efficient way to compute the mod/ref set for AA implementations like DSA. --- Diffs of the changes: (+11 -10) AliasAnalysisEvaluator.cpp | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) Index: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp diff -u llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.23 llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.24 --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.23 Thu Mar 17 14:25:04 2005 +++ llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Sat Mar 26 16:16:44 2005 @@ -156,15 +156,16 @@ } // Mod/ref alias analysis: compare all pairs of calls and values - for (std::set::iterator V = Pointers.begin(), Ve = Pointers.end(); - V != Ve; ++V) { - unsigned Size = 0; - const Type *ElTy = cast((*V)->getType())->getElementType(); - if (ElTy->isSized()) Size = TD.getTypeSize(ElTy); - - for (std::set::iterator C = CallSites.begin(), - Ce = CallSites.end(); C != Ce; ++C) { - Instruction *I = C->getInstruction(); + for (std::set::iterator C = CallSites.begin(), + Ce = CallSites.end(); C != Ce; ++C) { + Instruction *I = C->getInstruction(); + + for (std::set::iterator V = Pointers.begin(), Ve = Pointers.end(); + V != Ve; ++V) { + unsigned Size = 0; + const Type *ElTy = cast((*V)->getType())->getElementType(); + if (ElTy->isSized()) Size = TD.getTypeSize(ElTy); + switch (AA.getModRefInfo(*C, *V, Size)) { case AliasAnalysis::NoModRef: PrintModRefResults("NoModRef", PrintNoModRef, I, *V, F.getParent()); @@ -183,7 +184,7 @@ } } } - + return false; } From lattner at cs.uiuc.edu Sat Mar 26 16:43:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 16:43:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200503262243.j2QMhaoX002756@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.56 -> 1.57 --- Log message: Teach steens-aa two things about mod/ref information: 1. If memory never escapes the program, it cannot be mod/ref'd by external functions. 2. If memory is global never mod/ref'd in the program, it cannot be mod/ref'd by any call. --- Diffs of the changes: (+33 -3) Steensgaard.cpp | 36 +++++++++++++++++++++++++++++++++--- 1 files changed, 33 insertions(+), 3 deletions(-) Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.56 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.57 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.56 Thu Mar 24 12:42:28 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Sat Mar 26 16:43:20 2005 @@ -62,10 +62,11 @@ // Implement the AliasAnalysis API // - // alias - This is the only method here that does anything interesting... AliasResult alias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size); - + + ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); + private: void ResolveFunctionCall(Function *F, const DSCallSite &Call, DSNodeHandle &RetVal); @@ -183,7 +184,6 @@ return false; } -// alias - This is the only method here that does anything interesting... AliasAnalysis::AliasResult Steens::alias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size) { assert(ResultGraph && "Result graph has not been computed yet!"); @@ -224,3 +224,33 @@ // return AliasAnalysis::alias(V1, V1Size, V2, V2Size); } + +AliasAnalysis::ModRefResult +Steens::getModRefInfo(CallSite CS, Value *P, unsigned Size) { + AliasAnalysis::ModRefResult Result = ModRef; + + // Find the node in question. + DSGraph::ScalarMapTy &GSM = ResultGraph->getScalarMap(); + DSGraph::ScalarMapTy::iterator I = GSM.find(P); + + if (I != GSM.end() && !I->second.isNull()) { + DSNode *N = I->second.getNode(); + if (N->isComplete()) { + // If this is a direct call to an external function, and if the pointer + // points to a complete node, the external function cannot modify or read + // the value (we know it's not passed out of the program!). + if (Function *F = CS.getCalledFunction()) + if (F->isExternal()) + return NoModRef; + + // Otherwise, if the node is complete, but it is only M or R, return this. + // This can be useful for globals that should be marked const but are not. + if (!N->isModified()) + Result = (ModRefResult)(Result & ~Mod); + if (!N->isRead()) + Result = (ModRefResult)(Result & ~Ref); + } + } + + return (ModRefResult)(Result & AliasAnalysis::getModRefInfo(CS, P, Size)); +} From lattner at cs.uiuc.edu Sat Mar 26 16:47:16 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 16:47:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200503262247.j2QMlGCc002802@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.31 -> 1.32 --- Log message: slightly improve mod/ref for DSAA by checking the globals graph for fallback --- Diffs of the changes: (+12 -0) DataStructureAA.cpp | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.31 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.32 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.31 Wed Mar 23 21:04:50 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Sat Mar 26 16:47:03 2005 @@ -222,6 +222,18 @@ cast(P)->getType()->getElementType()->isFirstClassType() && "This isn't a global that DSA inconsiderately dropped " "from the graph?"); + + DSGraph &GG = *CallerTDGraph.getGlobalsGraph(); + DSScalarMap::iterator NI = GG.getScalarMap().find(P); + if (NI != GG.getScalarMap().end() && !NI->second.isNull()) { + // Otherwise, if the node is only M or R, return this. This can be + // useful for globals that should be marked const but are not. + DSNode *N = NI->second.getNode(); + if (!N->isModified()) + Result = (ModRefResult)(Result & ~Mod); + if (!N->isRead()) + Result = (ModRefResult)(Result & ~Ref); + } } return Result; } From lattner at cs.uiuc.edu Sat Mar 26 16:48:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 16:48:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200503262248.j2QMmuiN002908@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.32 -> 1.33 --- Log message: remove some unsafe code that has long been dead --- Diffs of the changes: (+0 -24) DataStructureAA.cpp | 24 ------------------------ 1 files changed, 24 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.32 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.33 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.32 Sat Mar 26 16:47:03 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Sat Mar 26 16:48:42 2005 @@ -100,19 +100,6 @@ return 0; } -#if 0 -// isSinglePhysicalObject - For now, the only case that we know that there is -// only one memory object in the node is when there is a single global in the -// node, and the only composition bit set is Global. -// -static bool isSinglePhysicalObject(DSNode *N) { - assert(N->isComplete() && "Can only tell if this is a complete object!"); - return N->isGlobalNode() && N->getGlobals().size() == 1 && - !N->isHeapNode() && !N->isAllocaNode() && !N->isUnknownNode(); -} -#endif - -// alias - This is the only method here that does anything interesting... AliasAnalysis::AliasResult DSAA::alias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size) { if (V1 == V2) return MustAlias; @@ -141,17 +128,6 @@ if (N1 != N2) return NoAlias; // Completely different nodes. -#if 0 // This does not correctly handle arrays! - // Both point to the same node and same offset, and there is only one - // physical memory object represented in the node, return must alias. - // - // FIXME: This isn't correct because we do not handle array indexing - // correctly. - - if (O1 == O2 && isSinglePhysicalObject(N1)) - return MustAlias; // Exactly the same object & offset -#endif - // See if they point to different offsets... if so, we may be able to // determine that they do not alias... if (O1 != O2) { From lattner at cs.uiuc.edu Sat Mar 26 16:55:00 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 16:55:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200503262255.j2QMt0fm003209@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.33 -> 1.34 --- Log message: Remove more long dead code: dsa doesn't provide must alias info --- Diffs of the changes: (+0 -32) DataStructureAA.cpp | 32 -------------------------------- 1 files changed, 32 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.33 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.34 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.33 Sat Mar 26 16:48:42 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Sat Mar 26 16:54:46 2005 @@ -56,8 +56,6 @@ AliasResult alias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size); - void getMustAliases(Value *P, std::vector &RetVals); - ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) { return AliasAnalysis::getModRefInfo(CS1,CS2); @@ -245,33 +243,3 @@ return Result; } - - -/// getMustAliases - If there are any pointers known that must alias this -/// pointer, return them now. This allows alias-set based alias analyses to -/// perform a form a value numbering (which is exposed by load-vn). If an alias -/// analysis supports this, it should ADD any must aliased pointers to the -/// specified vector. -/// -void DSAA::getMustAliases(Value *P, std::vector &RetVals) { -#if 0 // This does not correctly handle arrays! - // Currently the only must alias information we can provide is to say that - // something is equal to a global value. If we already have a global value, - // don't get worked up about it. - if (!isa(P)) { - DSGraph *G = getGraphForValue(P); - if (!G) G = &TD->getGlobalsGraph(); - - // The only must alias information we can currently determine occurs when - // the node for P is a global node with only one entry. - DSGraph::ScalarMapTy::const_iterator I = G->getScalarMap().find(P); - if (I != G->getScalarMap().end()) { - DSNode *N = I->second.getNode(); - if (N->isComplete() && isSinglePhysicalObject(N)) - RetVals.push_back(N->getGlobals()[0]); - } - } -#endif - return AliasAnalysis::getMustAliases(P, RetVals); -} - From lattner at cs.uiuc.edu Sat Mar 26 17:29:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 17:29:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200503262329.j2QNTJ8N004696@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.34 -> 1.35 --- Log message: Cache mapping information for a call site after computing it for a mod/ref query. If the next mod/ref query happens to be for the same call site (which is extremely likely), use the cache instead of recomputing the callee/caller mapping. This makes -aa-eval ***MUCH*** faster with ds-aa --- Diffs of the changes: (+81 -27) DataStructureAA.cpp | 108 +++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 81 insertions(+), 27 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.34 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.35 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.34 Sat Mar 26 16:54:46 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Sat Mar 26 17:29:03 2005 @@ -25,8 +25,25 @@ class DSAA : public ModulePass, public AliasAnalysis { TDDataStructures *TD; BUDataStructures *BU; + + // These members are used to cache mod/ref information to make us return + // results faster, particularly for aa-eval. On the first request of + // mod/ref information for a particular call site, we compute and store the + // calculated nodemap for the call site. Any time DSA info is updated we + // free this information, and when we move onto a new call site, this + // information is also freed. + CallSite MapCS; + std::multimap CallerCalleeMap; public: DSAA() : TD(0) {} + ~DSAA() { + InvalidateCache(); + } + + void InvalidateCache() { + MapCS = CallSite(); + CallerCalleeMap.clear(); + } //------------------------------------------------ // Implement the Pass API @@ -62,12 +79,14 @@ } virtual void deleteValue(Value *V) { + InvalidateCache(); BU->deleteValue(V); TD->deleteValue(V); } virtual void copyValue(Value *From, Value *To) { if (From == To) return; + InvalidateCache(); BU->copyValue(From, To); TD->copyValue(From, To); } @@ -149,11 +168,56 @@ /// AliasAnalysis::ModRefResult DSAA::getModRefInfo(CallSite CS, Value *P, unsigned Size) { - AliasAnalysis::ModRefResult Result =AliasAnalysis::getModRefInfo(CS, P, Size); + DSNode *N = 0; + // First step, check our cache. + if (CS.getInstruction() == MapCS.getInstruction()) { + { + const Function *Caller = CS.getInstruction()->getParent()->getParent(); + DSGraph &CallerTDGraph = TD->getDSGraph(*Caller); + + // Figure out which node in the TD graph this pointer corresponds to. + DSScalarMap &CallerSM = CallerTDGraph.getScalarMap(); + DSScalarMap::iterator NI = CallerSM.find(P); + if (NI == CallerSM.end()) { + InvalidateCache(); + return DSAA::getModRefInfo(CS, P, Size); + } + N = NI->second.getNode(); + } + + HaveMappingInfo: + assert(N && "Null pointer in scalar map??"); + + typedef std::multimap::iterator NodeMapIt; + std::pair Range = CallerCalleeMap.equal_range(N); + + // Loop over all of the nodes in the callee that correspond to "N", keeping + // track of aggregate mod/ref info. + bool NeverReads = true, NeverWrites = true; + for (; Range.first != Range.second; ++Range.first) { + if (Range.first->second->isModified()) + NeverWrites = false; + if (Range.first->second->isRead()) + NeverReads = false; + if (NeverReads == false && NeverWrites == false) + return AliasAnalysis::getModRefInfo(CS, P, Size); + } + + ModRefResult Result = ModRef; + if (NeverWrites) // We proved it was not modified. + Result = ModRefResult(Result & ~Mod); + if (NeverReads) // We proved it was not read. + Result = ModRefResult(Result & ~Ref); + + return ModRefResult(Result & AliasAnalysis::getModRefInfo(CS, P, Size)); + } + + // Any cached info we have is for the wrong function. + InvalidateCache(); + Function *F = CS.getCalledFunction(); - if (!F || Result == NoModRef) - return Result; + if (!F) return AliasAnalysis::getModRefInfo(CS, P, Size); if (F->isExternal()) { // If we are calling an external function, and if this global doesn't escape @@ -169,14 +233,14 @@ G = G->getGlobalsGraph(); NI = G->getScalarMap().find(P); if (NI == G->getScalarMap().end()) - return Result; + return AliasAnalysis::getModRefInfo(CS, P, Size); } // If we found a node and it's complete, it cannot be passed out to the // called function. if (NI->second.getNode()->isComplete()) return NoModRef; - return Result; + return AliasAnalysis::getModRefInfo(CS, P, Size); } // Get the graphs for the callee and caller. Note that we want the BU graph @@ -189,8 +253,9 @@ DSScalarMap &CallerSM = CallerTDGraph.getScalarMap(); DSScalarMap::iterator NI = CallerSM.find(P); if (NI == CallerSM.end()) { + ModRefResult Result = ModRef; if (isa(P) || isa(P)) - Result = NoModRef; // null is never modified :) + return NoModRef; // null is never modified :) else { assert(isa(P) && cast(P)->getType()->getElementType()->isFirstClassType() && @@ -209,11 +274,10 @@ Result = (ModRefResult)(Result & ~Ref); } } - return Result; - } - const DSNode *N = NI->second.getNode(); - assert(N && "Null pointer in scalar map??"); + if (Result == NoModRef) return Result; + return ModRefResult(Result & AliasAnalysis::getModRefInfo(CS, P, Size)); + } // Compute the mapping from nodes in the callee graph to the nodes in the // caller graph for this call site. @@ -222,24 +286,14 @@ CallerTDGraph.computeCalleeCallerMapping(DSCS, *F, CalleeBUGraph, CalleeCallerMap); - // Loop over all of the nodes in the callee that correspond to "N", keeping - // track of aggregate mod/ref info. - bool NeverReads = true, NeverWrites = true; + // Remember the mapping and the call site for future queries. + MapCS = CS; + + // Invert the mapping into CalleeCallerInvMap. for (DSGraph::NodeMapTy::iterator I = CalleeCallerMap.begin(), E = CalleeCallerMap.end(); I != E; ++I) - if (I->second.getNode() == N) { - if (I->first->isModified()) - NeverWrites = false; - if (I->first->isRead()) - NeverReads = false; - if (NeverReads == false && NeverWrites == false) - return Result; - } - - if (NeverWrites) // We proved it was not modified. - Result = ModRefResult(Result & ~Mod); - if (NeverReads) // We proved it was not read. - Result = ModRefResult(Result & ~Ref); + CallerCalleeMap.insert(std::make_pair(I->second.getNode(), I->first)); - return Result; + N = NI->second.getNode(); + goto HaveMappingInfo; } From lattner at cs.uiuc.edu Sat Mar 26 17:56:49 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 17:56:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200503262356.j2QNunmm006076@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp updated: 1.24 -> 1.25 --- Log message: Factor out percentage printing into its own function. Make two changes to the function: print more precision XX.X% instead of XX%, and cast to ULL before scaling by 100/1000 to avoid wrap around for large numbers of queries (such as occur for 253.perlbmk and 176.gcc) --- Diffs of the changes: (+19 -14) AliasAnalysisEvaluator.cpp | 33 +++++++++++++++++++-------------- 1 files changed, 19 insertions(+), 14 deletions(-) Index: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp diff -u llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.24 llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.25 --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.24 Sat Mar 26 16:16:44 2005 +++ llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Sat Mar 26 17:56:33 2005 @@ -188,6 +188,11 @@ return false; } +static void PrintPercent(unsigned Num, unsigned Sum) { + std::cerr << "(" << Num*100ULL/Sum << "." + << ((Num*1000ULL/Sum) % 10) << "%)\n"; +} + bool AAEval::doFinalization(Module &M) { unsigned AliasSum = NoAlias + MayAlias + MustAlias; std::cerr << "===== Alias Analysis Evaluator Report =====\n"; @@ -195,12 +200,12 @@ std::cerr << " Alias Analysis Evaluator Summary: No pointers!\n"; } 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 << " " << NoAlias << " no alias responses "; + PrintPercent(NoAlias, AliasSum); + std::cerr << " " << MayAlias << " may alias responses "; + PrintPercent(MayAlias, AliasSum); + std::cerr << " " << MustAlias << " must alias responses "; + PrintPercent(MustAlias, AliasSum); std::cerr << " Alias Analysis Evaluator Pointer Alias Summary: " << NoAlias*100/AliasSum << "%/" << MayAlias*100/AliasSum << "%/" << MustAlias*100/AliasSum << "%\n"; @@ -212,14 +217,14 @@ 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 << " " << NoModRef << " no mod/ref responses "; + PrintPercent(NoModRef, ModRefSum); + std::cerr << " " << Mod << " mod responses "; + PrintPercent(Mod, ModRefSum); + std::cerr << " " << Ref << " ref responses "; + PrintPercent(Ref, ModRefSum); + std::cerr << " " << ModRef << " mod & ref responses "; + PrintPercent(ModRef, ModRefSum); std::cerr << " Alias Analysis Evaluator Mod/Ref Summary: " << NoModRef*100/ModRefSum << "%/" << Mod*100/ModRefSum << "%/" << Ref*100/ModRefSum << "%/" << ModRef*100/ModRefSum << "%\n"; From lattner at cs.uiuc.edu Sat Mar 26 18:02:47 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 18:02:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200503270002.j2R02lYB006244@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.35 -> 1.36 --- Log message: Don't give up completely, maybe other AA can say something about this. --- Diffs of the changes: (+2 -1) DataStructureAA.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.35 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.36 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.35 Sat Mar 26 17:29:03 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Sat Mar 26 18:02:33 2005 @@ -138,7 +138,8 @@ DSNode *N1 = I->second.getNode(), *N2 = J->second.getNode(); unsigned O1 = I->second.getOffset(), O2 = J->second.getOffset(); if (N1 == 0 || N2 == 0) - return MayAlias; // Can't tell whether anything aliases null. + // Can't tell whether anything aliases null. + return AliasAnalysis::alias(V1, V1Size, V2, V2Size); // We can only make a judgment of one of the nodes is complete... if (N1->isComplete() || N2->isComplete()) { From alkis at cs.uiuc.edu Sat Mar 26 18:04:21 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 18:04:21 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.h Resolver.cpp Compiler.cpp Class.h Class.cpp Message-ID: <200503270004.SAA03621@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.h updated: 1.4 -> 1.5 Resolver.cpp updated: 1.4 -> 1.5 Compiler.cpp updated: 1.254 -> 1.255 Class.h updated: 1.9 -> 1.10 Class.cpp updated: 1.9 -> 1.10 --- Log message: Add ability to load an array class given its component class. Add a name field to Class. --- Diffs of the changes: (+48 -45) Class.cpp | 16 +++++++++++++--- Class.h | 3 +++ Compiler.cpp | 17 ++++++++--------- Resolver.cpp | 41 +++++++++++------------------------------ Resolver.h | 16 +++++++++++++--- 5 files changed, 48 insertions(+), 45 deletions(-) Index: llvm-java/lib/Compiler/Resolver.h diff -u llvm-java/lib/Compiler/Resolver.h:1.4 llvm-java/lib/Compiler/Resolver.h:1.5 --- llvm-java/lib/Compiler/Resolver.h:1.4 Sat Mar 26 11:15:47 2005 +++ llvm-java/lib/Compiler/Resolver.h Sat Mar 26 18:04:10 2005 @@ -39,14 +39,21 @@ unsigned& i, bool memberMethod = false) const; - std::string canonicalizeClassName(const std::string& className) { + std::pair insertClass(const Class& clazz) { + return classMap_.insert(std::make_pair(clazz.getName(), clazz)); + } + ClassMap::iterator insertClass(ClassMap::iterator i, const Class& clazz) { + return classMap_.insert(i, std::make_pair(clazz.getName(), clazz)); + } + + public: + static std::string canonicalizeClassName(const std::string& className) { if (className[0] == '[') return className; else return 'L' + className + ';'; } - public: Resolver(Module* module); const Type* getObjectBaseType() const { return objectBaseType_; } @@ -71,7 +78,10 @@ return getClassForDesc(field.getDescriptor()->str()); } const Class* getClass(JType type); - const Class* getArrayClass(JType type); + + const Class* getArrayClass(const Class* clazz) { + return getClassForDesc('[' + clazz->getName()); + } unsigned getNextInterfaceIndex() { return nextInterfaceIndex_++; } Module* getModule() { return module_; } Index: llvm-java/lib/Compiler/Resolver.cpp diff -u llvm-java/lib/Compiler/Resolver.cpp:1.4 llvm-java/lib/Compiler/Resolver.cpp:1.5 --- llvm-java/lib/Compiler/Resolver.cpp:1.4 Sat Mar 26 11:15:47 2005 +++ llvm-java/lib/Compiler/Resolver.cpp Sat Mar 26 18:04:10 2005 @@ -27,15 +27,15 @@ objectBaseType_(OpaqueType::get()), objectBaseRefType_(PointerType::get(objectBaseType_)) { - classMap_.insert(std::make_pair("B", Class(this, Type::SByteTy))); - classMap_.insert(std::make_pair("C", Class(this, Type::UShortTy))); - classMap_.insert(std::make_pair("D", Class(this, Type::DoubleTy))); - classMap_.insert(std::make_pair("F", Class(this, Type::FloatTy))); - classMap_.insert(std::make_pair("I", Class(this, Type::IntTy))); - classMap_.insert(std::make_pair("J", Class(this, Type::LongTy))); - classMap_.insert(std::make_pair("S", Class(this, Type::ShortTy))); - classMap_.insert(std::make_pair("Z", Class(this, Type::BoolTy))); - classMap_.insert(std::make_pair("V", Class(this, Type::VoidTy))); + insertClass(Class(this, Type::SByteTy)); + insertClass(Class(this, Type::UShortTy)); + insertClass(Class(this, Type::DoubleTy)); + insertClass(Class(this, Type::FloatTy)); + insertClass(Class(this, Type::IntTy)); + insertClass(Class(this, Type::LongTy)); + insertClass(Class(this, Type::ShortTy)); + insertClass(Class(this, Type::BoolTy)); + insertClass(Class(this, Type::VoidTy)); module_->addTypeName("struct.llvm_java_object_base", objectBaseType_); } @@ -108,16 +108,12 @@ case 'L': { unsigned pos = descriptor.find(';', 1); const std::string& className = descriptor.substr(1, pos - 1); - it = classMap_.insert( - it, std::make_pair(descriptor, - Class(this, className))); + it = insertClass(it, Class(this, className)); break; } case '[': { const std::string& componentDescriptor = descriptor.substr(1); - it = classMap_.insert( - it, std::make_pair(descriptor, - Class(this, getClassForDesc(componentDescriptor)))); + it = insertClass(it, Class(this, getClassForDesc(componentDescriptor))); break; } default: @@ -147,21 +143,6 @@ } } -const Class* Resolver::getArrayClass(JType type) -{ - switch (type) { - case BOOLEAN: return getClassForDesc("[Z"); - case CHAR: return getClassForDesc("[C"); - case FLOAT: return getClassForDesc("[F"); - case DOUBLE: return getClassForDesc("[D"); - case BYTE: return getClassForDesc("[B"); - case SHORT: return getClassForDesc("[S"); - case INT: return getClassForDesc("[I"); - case LONG: return getClassForDesc("[J"); - default: assert(0 && "Unhandled JType!"); abort(); - } -} - const Type* Resolver::getStorageType(const Type* type) const { if (isa(type)) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.254 llvm-java/lib/Compiler/Compiler.cpp:1.255 --- llvm-java/lib/Compiler/Compiler.cpp:1.254 Sat Mar 26 13:14:02 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 18:04:10 2005 @@ -2106,22 +2106,21 @@ void do_newarray(JType type) { Value* count = pop(Type::UIntTy); - const Class* clazz = resolver_->getArrayClass(type); - const VTableInfo* vi = getVTableInfoGeneric(clazz); + const Class* clazz = resolver_->getClass(type); + const Class* arrayClass = resolver_->getArrayClass(clazz); + const VTableInfo* vi = getVTableInfoGeneric(arrayClass); - push(allocateArray(clazz, vi, count, currentBB_)); + push(allocateArray(arrayClass, vi, count, currentBB_)); } void do_anewarray(unsigned index) { Value* count = pop(Type::UIntTy); - // FIXME: Need to handle different element types. This now - // assumes that all arrays of reference type are arrays of - // java/lang/Object's. - const Class* clazz = resolver_->getClass("[Ljava/lang/Object;"); - const VTableInfo* vi = getVTableInfoGeneric(clazz); + const Class* clazz = class_->getClass(index); + const Class* arrayClass = resolver_->getArrayClass(clazz); + const VTableInfo* vi = getVTableInfoGeneric(arrayClass); - push(allocateArray(clazz, vi, count, currentBB_)); + push(allocateArray(arrayClass, vi, count, currentBB_)); } void do_arraylength() { Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.9 llvm-java/lib/Compiler/Class.h:1.10 --- llvm-java/lib/Compiler/Class.h:1.9 Sat Mar 26 11:15:47 2005 +++ llvm-java/lib/Compiler/Class.h Sat Mar 26 18:04:10 2005 @@ -19,6 +19,7 @@ #include #include #include +#include #include namespace llvm { namespace Java { @@ -29,6 +30,7 @@ class Class { static const unsigned INVALID_INTERFACE_INDEX = 0xFFFFFFFF; + const std::string name_; Resolver* resolver_; const ClassFile* classFile_; const Class* superClass_; @@ -66,6 +68,7 @@ void initialize(); public: + const std::string& getName() const { return name_; } const Type* getStructType() const { return structType_; } const Type* getType() const { return type_; } const ClassFile* getClassFile() const { return classFile_; } Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.9 llvm-java/lib/Compiler/Class.cpp:1.10 --- llvm-java/lib/Compiler/Class.cpp:1.9 Sat Mar 26 11:15:47 2005 +++ llvm-java/lib/Compiler/Class.cpp Sat Mar 26 18:04:10 2005 @@ -27,7 +27,8 @@ using namespace llvm::Java; Class::Class(Resolver* resolver, const std::string& className) - : resolver_(resolver), + : name_(Resolver::canonicalizeClassName(className)), + resolver_(resolver), classFile_(ClassFile::get(className)), superClass_(NULL), componentClass_(NULL), @@ -40,7 +41,8 @@ } Class::Class(Resolver* resolver, const Class* componentClass) - : resolver_(resolver), + : name_('[' + componentClass->getName()), + resolver_(resolver), classFile_(NULL), superClass_(NULL), componentClass_(componentClass), @@ -52,7 +54,15 @@ } Class::Class(Resolver* resolver, const Type* type) - : resolver_(resolver), + : name_(type == Type::SByteTy ? "B" : + type == Type::UShortTy ? "C" : + type == Type::DoubleTy ? "D" : + type == Type::FloatTy ? "F" : + type == Type::IntTy ? "I" : + type == Type::LongTy ? "J" : + type == Type::ShortTy ? "S" : + type == Type::BoolTy ? "Z" : "V"), + resolver_(resolver), classFile_(NULL), superClass_(NULL), componentClass_(NULL), From lattner at cs.uiuc.edu Sat Mar 26 18:38:15 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 18:38:15 -0600 Subject: [llvm-commits] CVS: llvm-test/GenerateReport.pl Message-ID: <200503270038.j2R0cF8F011168@apoc.cs.uiuc.edu> Changes in directory llvm-test: GenerateReport.pl updated: 1.25 -> 1.26 --- Log message: When printing out a report in CSV for import to a spreadsheet, do so in latex row order if defined. --- Diffs of the changes: (+28 -1) GenerateReport.pl | 29 ++++++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletion(-) Index: llvm-test/GenerateReport.pl diff -u llvm-test/GenerateReport.pl:1.25 llvm-test/GenerateReport.pl:1.26 --- llvm-test/GenerateReport.pl:1.25 Tue Mar 22 23:38:34 2005 +++ llvm-test/GenerateReport.pl Sat Mar 26 18:37:59 2005 @@ -316,6 +316,33 @@ print "\\\\\n"; } } + } elsif ($CSV && scalar(@LatexRowMapOrder)) { + # + # Print out the table as csv in the row-order specified by LatexRowMapOrder + # + for ($i = 0; $i < @LatexRowMapOrder; $i += 2) { + my $Name = $LatexRowMapOrder[$i]; + if ($Name eq '-') { + print "----\n"; + } else { + # Output benchmark name. + printf "$LatexRowMapOrder[$i+1]"; + + # Find the row that this benchmark name corresponds to. + foreach $Row (@Values) { + if ($Row->[0] eq $Name) { + for ($j = 1; $j < @$Row-1; $j++) { + print ",$$Row[$j]"; + } + goto Done; + } + } + print "UNKNOWN Benchmark name: " . $Name; + Done: + print "\\\\\n"; + } + } + } elsif ($CSV) { # # Print out the table as csv @@ -323,7 +350,7 @@ foreach $Value (@Values) { printf "$$Value[0]"; for ($i = 1; $i < @$Value-1; $i++) { - printf ",$$Value[$i]" if ($$Value[$i] ne "|"); + print ",$$Value[$i]" if ($$Value[$i] ne "|"); } print "\n"; } From lattner at cs.uiuc.edu Sat Mar 26 18:54:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 26 Mar 2005 18:54:17 -0600 Subject: [llvm-commits] CVS: llvm-test/TEST.dsprecision.report Message-ID: <200503270054.j2R0sHPc011198@apoc.cs.uiuc.edu> Changes in directory llvm-test: TEST.dsprecision.report updated: 1.3 -> 1.4 --- Log message: add a row map so that we emit numbers in the same order as the dsgraph report. --- Diffs of the changes: (+51 -0) TEST.dsprecision.report | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+) Index: llvm-test/TEST.dsprecision.report diff -u llvm-test/TEST.dsprecision.report:1.3 llvm-test/TEST.dsprecision.report:1.4 --- llvm-test/TEST.dsprecision.report:1.3 Sat Mar 26 15:49:49 2005 +++ llvm-test/TEST.dsprecision.report Sat Mar 26 18:54:03 2005 @@ -24,6 +24,57 @@ # Sort in ascending order $SortReverse = 0; +# For latex/csv output, limit benchmarks and rename as appropriate + at LatexRowMapOrder = ( + '-' => '-', + + '181.mcf' => '181.mcf', + '256.bzip2' => '256.bzip2', + '164.gzip' => '164.gzip', + '175.vpr' => '175.vpr', + '197.parser' => '197.parser', + '186.crafty' => '186.crafty', + '300.twolf' => '300.twolf', + '255.vortex' => '255.vortex', + '254.gap' => '254.gap', + '252.eon' => '252.eon', + '253.perlbmk' => '253.perlbmk', + '176.gcc' => '176.gcc', + '-' => '-', + '179.art' => '179.art', + '183.equake' => '183.equake', + '171.swim' => '171.swim', + '172.mgrid' => '172.mgrid', + '168.wupwise' => '168.wupwise', + '173.applu' => '173.applu', + '188.ammp' => '188.ammp', + '177.mesa' => '177.mesa', + '-' => '-', + '129.compress' => '129.compress', + '130.li' => '130.li', + '124.m88ksim' => '124.m88ksim', + '132.ijpeg' => '132.ijpeg', + '099.go' => '099.go', + '134.perl' => '134.perl', + '147.vortex' => '147.vortex', + '126.gcc' => '126.gcc', + '-' => '-', + '102.swim' => '102.swim', + '101.tomcatv' => '101.tomcatv', + '107.mgrid' => '107.mgrid', + '145.fpppp' => '145.fpppp', + '104.hydro2d' => '104.hydro2d', + '110.applu' => '110.applu', + '103.su2cor' => '103.su2cor', + '146.wave5' => '146.wave5', + '-' => '-', + 'fpgrowth' => 'fpgrowth', + 'bsim' => 'boxed-sim', + 'namd' => 'NAMD', + 'povray' => 'povray31', + ); + + # These are the columns for the report. The first entry is the header for the # column, the second is the regex to use to match the value. Empty list create # seperators, and closures may be put in for custom processing. From alkis at cs.uiuc.edu Sat Mar 26 21:26:19 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 21:26:19 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503270326.VAA05690@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.255 -> 1.256 --- Log message: Only add super class vtables to classes not interfaces. --- Diffs of the changes: (+11 -11) Compiler.cpp | 22 +++++++++++----------- 1 files changed, 11 insertions(+), 11 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.255 llvm-java/lib/Compiler/Compiler.cpp:1.256 --- llvm-java/lib/Compiler/Compiler.cpp:1.255 Sat Mar 26 18:04:10 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 21:26:08 2005 @@ -568,17 +568,6 @@ assert(!vi.vtable && vi.m2iMap.empty() && "got already initialized VTableInfo!"); - ConstantClass* super = cf->getSuperClass(); - assert(super && "Class does not have superclass!"); - const VTableInfo& superVI = - getVTableInfo(ClassFile::get(super->getName()->str())); - - // Copy the super vtables array. - vi.superVtables.reserve(superVI.superVtables.size() + 1); - vi.superVtables.push_back(superVI.vtable); - std::copy(superVI.superVtables.begin(), superVI.superVtables.end(), - std::back_inserter(vi.superVtables)); - std::vector init(1); // Use a null typeinfo struct for now. init[0] = llvm::Constant::getNullValue(VTableInfo::TypeInfoTy); @@ -609,6 +598,17 @@ // Otherwise this is a class, so add all methods from its super // class. else { + ConstantClass* super = cf->getSuperClass(); + assert(super && "Class does not have superclass!"); + const VTableInfo& superVI = + getVTableInfo(ClassFile::get(super->getName()->str())); + + // Copy the super vtables array. + vi.superVtables.reserve(superVI.superVtables.size() + 1); + vi.superVtables.push_back(superVI.vtable); + std::copy(superVI.superVtables.begin(), superVI.superVtables.end(), + std::back_inserter(vi.superVtables)); + assert(superVI.vtable && "No vtable found for super class!"); ConstantStruct* superInit = cast(superVI.vtable->getInitializer()); From alkis at cs.uiuc.edu Sat Mar 26 21:48:32 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 21:48:32 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503270348.VAA05841@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.256 -> 1.257 --- Log message: Use a single vtable for all array objects of reference type. This is obviously incorrect but it does simplify the code and doesn't remove any existing functionality. --- Diffs of the changes: (+6 -174) Compiler.cpp | 180 +---------------------------------------------------------- 1 files changed, 6 insertions(+), 174 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.256 llvm-java/lib/Compiler/Compiler.cpp:1.257 --- llvm-java/lib/Compiler/Compiler.cpp:1.256 Sat Mar 26 21:26:08 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 21:48:21 2005 @@ -95,7 +95,6 @@ }; typedef std::map Class2VTableInfoMap; Class2VTableInfoMap c2viMap_; - Class2VTableInfoMap ac2viMap_; public: Compiler(Module* m) @@ -680,10 +679,7 @@ return vi; } - VTableInfo buildArrayVTableInfo(Type* elementTy) { - assert(elementTy->isPrimitiveType() && - "This should not be called for arrays of non-primitive types"); - + VTableInfo buildArrayVTableInfo(const Type* elementTy) { VTableInfo vi; const VTableInfo& superVI = getVTableInfo(ClassFile::get("java/lang/Object")); @@ -809,175 +805,11 @@ abort(); } - /// Initializes the VTableInfo map for object arrays; in other - /// words it adds the VTableInfo for java.lang.Object[]. - bool initializeObjectArrayVTableInfoMap() { - DEBUG(std::cerr << "Building VTableInfo for: java/lang/Object[]\n"); - const ClassFile* cf = ClassFile::get("java/lang/Object"); - VTableInfo& vi = ac2viMap_[cf]; - assert(!vi.vtable && vi.m2iMap.empty() && - "java/lang/Object[] VTableInfo should not be initialized!"); - - const VTableInfo& javaLangObjectVI = - getVTableInfo(ClassFile::get("java/lang/Object")); - vi.superVtables.reserve(1); - vi.superVtables.push_back(javaLangObjectVI.vtable); - - std::vector init; - - // This is java/lang/Object[] so we must add a - // llvm_java_object_typeinfo struct first. - - // depth - init.push_back(llvm::ConstantSInt::get(Type::IntTy, 1)); - // superclasses vtable pointers - ArrayType* vtablesArrayTy = - ArrayType::get(PointerType::get(VTableInfo::VTableTy), 1); - - GlobalVariable* vtablesArray = new GlobalVariable( - vtablesArrayTy, - true, - GlobalVariable::ExternalLinkage, - ConstantArray::get(vtablesArrayTy, vi.superVtables), - "java/lang/Object[]", - module_); - init.push_back(ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray)); - - // last interface index - init.push_back(llvm::ConstantSInt::get(Type::IntTy, -1)); - // interfaces vtable pointers - init.push_back( - llvm::Constant::getNullValue( - PointerType::get(PointerType::get(VTableInfo::VTableTy)))); - // the element size - init.push_back(ConstantExpr::getCast( - ConstantExpr::getSizeOf(resolver_->getObjectBaseRefType()), Type::IntTy)); - - llvm::Constant* typeInfoInit = - ConstantStruct::get(VTableInfo::TypeInfoTy, init); - - // Now that we have both the type and initializer for the - // llvm_java_object_typeinfo struct we can start adding the - // function pointers. - ConstantStruct* superInit = - cast(javaLangObjectVI.vtable->getInitializer()); - - init.clear(); - init.resize(superInit->getNumOperands()); - // Add the typeinfo block for this class. - init[0] = typeInfoInit; - - // Fill in the function pointers as they are in - // java/lang/Object. There are no overriden methods. - for (unsigned i = 1, e = superInit->getNumOperands(); i != e; ++i) - init[i] = superInit->getOperand(i); - vi.m2iMap = javaLangObjectVI.m2iMap; - - llvm::Constant* vtable = ConstantStruct::get(init); - module_->addTypeName("java/lang/Object[]", vtable->getType()); - - vi.vtable = new GlobalVariable(VTableInfo::VTableTy, - true, GlobalVariable::ExternalLinkage, - vtable, - "java/lang/Object[]", - module_); - DEBUG(std::cerr << "Built VTableInfo for: java/lang/Object[]\n"); - return true; - } - - const VTableInfo& getObjectArrayVTableInfo(const ClassFile* cf) { - static bool initialized = initializeObjectArrayVTableInfoMap(); - - Class2VTableInfoMap::iterator it = ac2viMap_.lower_bound(cf); - if (it != ac2viMap_.end() && it->first == cf) - return it->second; - - const std::string& className = cf->getThisClass()->getName()->str(); - DEBUG(std::cerr << "Building VTableInfo for: " << className << "[]\n"); - VTableInfo& vi = ac2viMap_[cf]; - - assert(!vi.vtable && vi.m2iMap.empty() && - "got already initialized VTableInfo!"); - - ConstantClass* super = cf->getSuperClass(); - assert(super && "Class does not have superclass!"); - const VTableInfo& superVI = - getVTableInfo(ClassFile::get(super->getName()->str())); - - // Copy the super vtables array. - vi.superVtables.reserve(superVI.superVtables.size() + 1); - vi.superVtables.push_back(superVI.vtable); - std::copy(superVI.superVtables.begin(), superVI.superVtables.end(), - std::back_inserter(vi.superVtables)); - - // Copy all the constants from the super class' vtable. - assert(superVI.vtable && "No vtable found for super class!"); - ConstantStruct* superInit = - cast(superVI.vtable->getInitializer()); - std::vector init(superInit->getNumOperands()); - // Use a null typeinfo struct for now. - init[0] = llvm::Constant::getNullValue(VTableInfo::TypeInfoTy); - // Fill in the function pointers as they are in the super - // class. There are no overriden methods. - for (unsigned i = 0, e = superInit->getNumOperands(); i != e; ++i) - init[i] = superInit->getOperand(i); - vi.m2iMap = superVI.m2iMap; - -#ifndef NDEBUG - for (unsigned i = 0, e = init.size(); i != e; ++i) - assert(init[i] && "No elements in the initializer should be NULL!"); -#endif - - const std::string& globalName = className + "[]"; - - llvm::Constant* vtable = ConstantStruct::get(init); - module_->addTypeName(globalName, vtable->getType()); - vi.vtable = new GlobalVariable(vtable->getType(), - true, - GlobalVariable::ExternalLinkage, - vtable, - globalName, - module_); - - // Now the vtable is complete, install the new typeinfo block - // for this class: we install it last because we need the vtable - // to exist in order to build it. - std::vector typeInfoInit; - typeInfoInit.reserve(4); - // depth - typeInfoInit.push_back( - llvm::ConstantSInt::get(Type::IntTy, vi.superVtables.size())); - // superclasses vtable pointers - ArrayType* vtablesArrayTy = - ArrayType::get(PointerType::get(VTableInfo::VTableTy), - vi.superVtables.size()); - - GlobalVariable* vtablesArray = new GlobalVariable( - vtablesArrayTy, - true, - GlobalVariable::ExternalLinkage, - ConstantArray::get(vtablesArrayTy, vi.superVtables), - className + "[]", - module_); - - typeInfoInit.push_back(ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray)); - // last interface index - typeInfoInit.push_back(llvm::ConstantSInt::get(Type::IntTy, -1)); - // interfaces vtable pointers - typeInfoInit.push_back( - llvm::Constant::getNullValue( - PointerType::get(PointerType::get(VTableInfo::VTableTy)))); - // the element size - typeInfoInit.push_back( - ConstantExpr::getCast( - ConstantExpr::getSizeOf(resolver_->getObjectBaseRefType()), Type::IntTy)); - - init[0] = ConstantStruct::get(VTableInfo::TypeInfoTy, typeInfoInit); - vi.vtable->setInitializer(ConstantStruct::get(init)); - - DEBUG(std::cerr << "Built VTableInfo for: " << className << "[]\n"); - return vi; + const VTableInfo& getObjectArrayVTableInfo() { + static VTableInfo arrayInfo = + buildArrayVTableInfo(resolver_->getObjectBaseRefType()); + return arrayInfo; } /// Emits the necessary code to get a pointer to a static field of @@ -1860,7 +1692,7 @@ if (componentClass->isPrimitive()) return &getPrimitiveArrayVTableInfo(componentClass->getType()); else - return &getObjectArrayVTableInfo(ClassFile::get("java/lang/Object")); + return &getObjectArrayVTableInfo(); } else return &getVTableInfo(clazz->getClassFile()); From alkis at cs.uiuc.edu Sat Mar 26 22:20:33 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 22:20:33 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Class.h Class.cpp Message-ID: <200503270420.WAA06288@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.257 -> 1.258 Class.h updated: 1.10 -> 1.11 Class.cpp updated: 1.10 -> 1.11 --- Log message: When dealing with VTableInfo's pass the Class around not the class file. Also add an array of all implemented interfaces and all superclasses in Class and use that when constructing a VTableInfo. --- Diffs of the changes: (+102 -91) Class.cpp | 51 +++++++++++++++++------ Class.h | 12 ++++- Compiler.cpp | 130 ++++++++++++++++++++++++----------------------------------- 3 files changed, 102 insertions(+), 91 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.257 llvm-java/lib/Compiler/Compiler.cpp:1.258 --- llvm-java/lib/Compiler/Compiler.cpp:1.257 Sat Mar 26 21:48:21 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 22:20:22 2005 @@ -93,7 +93,7 @@ static StructType* VTableTy; static StructType* TypeInfoTy; }; - typedef std::map Class2VTableInfoMap; + typedef std::map Class2VTableInfoMap; Class2VTableInfoMap c2viMap_; public: @@ -263,8 +263,8 @@ /// VTableInfo for java.lang.Object. bool initializeVTableInfoMap() { DEBUG(std::cerr << "Building VTableInfo for: java/lang/Object\n"); - const ClassFile* cf = ClassFile::get("java/lang/Object"); - VTableInfo& vi = c2viMap_[cf]; + const Class* clazz = resolver_->getClass("java/lang/Object"); + VTableInfo& vi = c2viMap_[clazz]; assert(!vi.vtable && vi.m2iMap.empty() && "java/lang/Object VTableInfo should not be initialized!"); @@ -310,7 +310,7 @@ // Add the typeinfo block for this class. init.push_back(typeInfoInit); - const Methods& methods = cf->getMethods(); + const Methods& methods = clazz->getClassFile()->getMethods(); // Add member functions to the vtable. for (unsigned i = 0, e = methods.size(); i != e; ++i) { @@ -358,10 +358,10 @@ } /// Builds the super classes' vtable array for this classfile and - /// its corresponding VTable. The most generic class goes first in + /// its corresponding VTable. The direct superclass goes first in /// the array. - std::pair - buildSuperClassesVTables(const ClassFile* cf, const VTableInfo& vi) const { + llvm::Constant* + buildSuperClassesVTables(const Class* clazz, const VTableInfo& vi) const { std::vector superVtables(vi.superVtables.size()); for (unsigned i = 0, e = vi.superVtables.size(); i != e; ++i) superVtables[i] = ConstantExpr::getCast( @@ -378,25 +378,23 @@ true, GlobalVariable::ExternalLinkage, init, - cf->getThisClass()->getName()->str() + "", + clazz->getClassFile()->getThisClass()->getName()->str() + + "", module_); - return std::make_pair( - vi.superVtables.size(), - ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray)); + return ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray); } /// Builds an interface VTable for the specified /// pair. - llvm::Constant* buildInterfaceVTable(const ClassFile* cf, - const ClassFile* interface) { + llvm::Constant* buildInterfaceVTable(const Class* clazz, + const Class* interface) { DEBUG(std::cerr << "Building interface vtable: " - << interface->getThisClass()->getName()->str() << " for: " - << cf->getThisClass()->getName()->str() << '\n'); + << interface->getName() << " for: " << clazz->getName() << '\n'); - const VTableInfo& classVI = getVTableInfo(cf); + const VTableInfo& classVI = getVTableInfo(clazz); const VTableInfo& interfaceVI = getVTableInfo(interface); - const Methods& methods = interface->getMethods(); + const Methods& methods = interface->getClassFile()->getMethods(); // The size of the initializer will be 1 greater than the number // of methods for this interface (the first slot is the typeinfo @@ -410,7 +408,7 @@ for (VTableInfo::Method2IndexMap::const_iterator i = interfaceVI.m2iMap.begin(), e = interfaceVI.m2iMap.end(); i != e; ++i) { - if (!cf->isAbstract()) { + if (!clazz->getClassFile()->isAbstract()) { assert(classVI.m2iMap.find(i->first) != classVI.m2iMap.end() && "Interface method not found in class definition!"); unsigned classMethodIdx = classVI.m2iMap.find(i->first)->second; @@ -425,8 +423,7 @@ llvm::Constant* vtable = ConstantStruct::get(init); const std::string& globalName = - cf->getThisClass()->getName()->str() + '+' + - interface->getThisClass()->getName()->str() + ""; + clazz->getName() + '+' + interface->getName() + ""; module_->addTypeName(globalName, vtable->getType()); GlobalVariable* gv = new GlobalVariable( @@ -441,41 +438,31 @@ } void insertVtablesForInterface(std::vector& vtables, - const ClassFile* cf, - const ClassFile* interfaceCf) { + const Class* clazz, + const Class* interface) { static llvm::Constant* nullVTable = llvm::Constant::getNullValue(PointerType::get(VTableInfo::VTableTy)); - assert(interfaceCf->isInterface() && "Classfile must be an interface!"); - const Class* interface = - resolver_->getClass(interfaceCf->getThisClass()->getName()->str()); + assert(interface->isInterface() && "Classfile must be an interface!"); unsigned index = interface->getInterfaceIndex(); if (index >= vtables.size()) vtables.resize(index+1, nullVTable); - // Add this interface's vtable if it was not added before. - if (vtables[index] == nullVTable) { - vtables[index] = buildInterfaceVTable(cf, interfaceCf); - unsigned numInterface = interfaceCf->getNumInterfaces(); - for (unsigned i = 0, e = interfaceCf->getNumInterfaces(); i != e; ++i) { - const ClassFile* superInterface = - ClassFile::get(interfaceCf->getInterface(i)->getName()->str()); - insertVtablesForInterface(vtables, cf, superInterface); - } - } + assert(vtables[index] == nullVTable && "Interface vtable already added!"); + vtables[index] = buildInterfaceVTable(clazz, interface); } /// Builds the interfaces vtable array for this classfile and its /// corresponding VTableInfo. If this classfile is an interface we /// return a pointer to 0xFFFFFFFF. std::pair - buildInterfacesVTables(const ClassFile* cf, const VTableInfo& vi) { + buildInterfacesVTables(const Class* clazz, const VTableInfo& vi) { // If this is an interface then we are not implementing any // interfaces so the lastInterface field is our index and the // pointer to the array of interface vtables is an all-ones // value. - if (cf->isInterface()) + if (clazz->isInterface()) return std::make_pair( - resolver_->getClass(cf->getThisClass()->getName()->str())->getInterfaceIndex(), + clazz->getInterfaceIndex(), ConstantExpr::getCast( ConstantIntegral::getAllOnesValue(Type::LongTy), PointerType::get(PointerType::get(VTableInfo::VTableTy)))); @@ -489,20 +476,10 @@ llvm::Constant* nullVTable = llvm::Constant::getNullValue(PointerType::get(VTableInfo::VTableTy)); - const ClassFile* curCf = cf; - while (true) { - for (unsigned i = 0, e = curCf->getNumInterfaces(); i != e; ++i) { - const ClassFile* ifaceCf = - ClassFile::get(curCf->getInterface(i)->getName()->str()); - insertVtablesForInterface(vtables, cf, ifaceCf); - } - if (!curCf->getSuperClass()) - break; - curCf = ClassFile::get(curCf->getSuperClass()->getName()->str()); - } + for (unsigned i = 0, e = clazz->getNumInterfaces(); i != e; ++i) + insertVtablesForInterface(vtables, clazz, clazz->getInterface(i)); - const std::string& globalName = - cf->getThisClass()->getName()->str() + ""; + const std::string& globalName = clazz->getName() + ""; llvm::Constant* init = ConstantArray::get( ArrayType::get(PointerType::get(VTableInfo::VTableTy), vtables.size()), @@ -524,22 +501,21 @@ /// Given the classfile and its corresponding VTableInfo, /// construct the typeinfo constant for it. - llvm::Constant* buildClassTypeInfo(const ClassFile* cf, + llvm::Constant* buildClassTypeInfo(const Class* clazz, const VTableInfo& vi) { std::vector typeInfoInit; - unsigned depth; - llvm::Constant* superClassesVTables; - tie(depth, superClassesVTables) = buildSuperClassesVTables(cf, vi); + llvm::Constant* superClassesVTables = buildSuperClassesVTables(clazz, vi); // The depth (java/lang/Object has depth 0). - typeInfoInit.push_back(ConstantSInt::get(Type::IntTy, depth)); + typeInfoInit.push_back( + ConstantSInt::get(Type::IntTy, clazz->getNumSuperClasses())); // The super classes' vtables. typeInfoInit.push_back(superClassesVTables); int lastInterface; llvm::Constant* interfacesVTables; - tie(lastInterface, interfacesVTables) = buildInterfacesVTables(cf, vi); + tie(lastInterface, interfacesVTables) = buildInterfacesVTables(clazz, vi); // The last interface index or the interface index if this is an // interface. @@ -553,16 +529,17 @@ } /// Returns the VTableInfo associated with this classfile. - const VTableInfo& getVTableInfo(const ClassFile* cf) { + const VTableInfo& getVTableInfo(const Class* clazz) { static bool initialized = initializeVTableInfoMap(); - Class2VTableInfoMap::iterator it = c2viMap_.lower_bound(cf); - if (it != c2viMap_.end() && it->first == cf) + Class2VTableInfoMap::iterator it = c2viMap_.lower_bound(clazz); + if (it != c2viMap_.end() && it->first == clazz) return it->second; - const std::string& className = cf->getThisClass()->getName()->str(); + const std::string& className = + clazz->getClassFile()->getThisClass()->getName()->str(); DEBUG(std::cerr << "Building VTableInfo for: " << className << '\n'); - VTableInfo& vi = c2viMap_[cf]; + VTableInfo& vi = c2viMap_[clazz]; assert(!vi.vtable && vi.m2iMap.empty() && "got already initialized VTableInfo!"); @@ -573,11 +550,11 @@ // If this is an interface, add all methods from each interface // this inherits from. - if (cf->isInterface()) { - for (unsigned i = 0, e = cf->getNumInterfaces(); i != e; ++i) { - const ClassFile* ifaceCF = - ClassFile::get(cf->getInterface(i)->getName()->str()); - const VTableInfo& ifaceVI = getVTableInfo(ifaceCF); + if (clazz->isInterface()) { + for (unsigned i = 0, e = clazz->getNumInterfaces(); i != e; ++i) { + const Class* interface = clazz->getInterface(i); + const VTableInfo& ifaceVI = getVTableInfo(interface); + const ClassFile* ifaceCF = interface->getClassFile(); ConstantStruct* ifaceInit = cast(ifaceVI.vtable->getInitializer()); for (VTableInfo::const_iterator MI = ifaceVI.m2iMap.begin(), @@ -597,10 +574,9 @@ // Otherwise this is a class, so add all methods from its super // class. else { - ConstantClass* super = cf->getSuperClass(); - assert(super && "Class does not have superclass!"); - const VTableInfo& superVI = - getVTableInfo(ClassFile::get(super->getName()->str())); + const Class* superClass = clazz->getSuperClass(); + assert(superClass && "Class does not have superclass!"); + const VTableInfo& superVI = getVTableInfo(superClass); // Copy the super vtables array. vi.superVtables.reserve(superVI.superVtables.size() + 1); @@ -620,7 +596,7 @@ } // Add member functions to the vtable. - const Methods& methods = cf->getMethods(); + const Methods& methods = clazz->getClassFile()->getMethods(); for (unsigned i = 0, e = methods.size(); i != e; ++i) { Method* method = methods[i]; @@ -637,7 +613,7 @@ const FunctionType* funcTy = cast( resolver_->getType(method->getDescriptor()->str(), true)); llvm::Constant* vfun = NULL; - if (cf->isInterface() || method->isAbstract()) + if (clazz->isInterface() || method->isAbstract()) vfun = llvm::Constant::getNullValue(PointerType::get(funcTy)); else { vfun = module_->getOrInsertFunction(funcName, funcTy); @@ -672,7 +648,7 @@ // Now the vtable is complete, install the new typeinfo block // for this class: we install it last because we need the vtable // to exist in order to build it. - init[0] = buildClassTypeInfo(cf, vi); + init[0] = buildClassTypeInfo(clazz, vi); vi.vtable->setInitializer(ConstantStruct::get(init)); DEBUG(std::cerr << "Built VTableInfo for: " << className << '\n'); @@ -682,7 +658,7 @@ VTableInfo buildArrayVTableInfo(const Type* elementTy) { VTableInfo vi; const VTableInfo& superVI = - getVTableInfo(ClassFile::get("java/lang/Object")); + getVTableInfo(resolver_->getClass("java/lang/Object")); // Add java/lang/Object as its superclass. vi.superVtables.reserve(1); @@ -1695,7 +1671,7 @@ return &getObjectArrayVTableInfo(); } else - return &getVTableInfo(clazz->getClassFile()); + return &getVTableInfo(clazz); } void do_invokevirtual(unsigned index) { @@ -1861,7 +1837,7 @@ void do_new(unsigned index) { const Class* clazz = class_->getClass(index); emitStaticInitializers(clazz->getClassFile()); - const VTableInfo& vi = getVTableInfo(clazz->getClassFile()); + const VTableInfo& vi = getVTableInfo(clazz); push(allocateObject(*clazz, vi, currentBB_)); } Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.10 llvm-java/lib/Compiler/Class.h:1.11 --- llvm-java/lib/Compiler/Class.h:1.10 Sat Mar 26 18:04:10 2005 +++ llvm-java/lib/Compiler/Class.h Sat Mar 26 22:20:22 2005 @@ -33,7 +33,6 @@ const std::string name_; Resolver* resolver_; const ClassFile* classFile_; - const Class* superClass_; const Class* componentClass_; Type* structType_; const Type* type_; @@ -43,6 +42,8 @@ typedef std::vector ElementTypes; ElementTypes elementTypes_; mutable std::vector resolvedConstantPool_; + std::vector superClasses_; + std::vector interfaces_; void addField(const std::string& name, const Type* type); void resolveType(); @@ -72,10 +73,17 @@ const Type* getStructType() const { return structType_; } const Type* getType() const { return type_; } const ClassFile* getClassFile() const { return classFile_; } - const Class* getSuperClass() const { return superClass_; } + unsigned getNumSuperClasses() const { return superClasses_.size(); } + const Class* getSuperClass(unsigned i) const { return superClasses_[i]; } + const Class* getSuperClass() const { + return getNumSuperClasses() ? getSuperClass(0) : NULL; + } + unsigned getNumInterfaces() const { return interfaces_.size(); } + const Class* getInterface(unsigned i) const { return interfaces_[i]; } const Class* getComponentClass() const { return componentClass_; } bool isArray() const { return componentClass_; } bool isPrimitive() const { return !structType_; } + bool isInterface() const { return classFile_ && !getSuperClass(); } unsigned getInterfaceIndex() const { return interfaceIndex_; } int getFieldIndex(const std::string& name) const; Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.10 llvm-java/lib/Compiler/Class.cpp:1.11 --- llvm-java/lib/Compiler/Class.cpp:1.10 Sat Mar 26 18:04:10 2005 +++ llvm-java/lib/Compiler/Class.cpp Sat Mar 26 22:20:22 2005 @@ -30,7 +30,6 @@ : name_(Resolver::canonicalizeClassName(className)), resolver_(resolver), classFile_(ClassFile::get(className)), - superClass_(NULL), componentClass_(NULL), structType_(OpaqueType::get()), type_(PointerType::get(structType_)), @@ -44,7 +43,6 @@ : name_('[' + componentClass->getName()), resolver_(resolver), classFile_(NULL), - superClass_(NULL), componentClass_(componentClass), structType_(OpaqueType::get()), type_(PointerType::get(structType_)), @@ -64,7 +62,6 @@ type == Type::BoolTy ? "Z" : "V"), resolver_(resolver), classFile_(NULL), - superClass_(NULL), componentClass_(NULL), structType_(NULL), type_(type), @@ -97,21 +94,48 @@ assert(!isPrimitive() && "Should not link primitive classes!"); if (isArray()) { - superClass_ = resolver_->getClass("java/lang/Object"); - addField("super", superClass_->getStructType()); + superClasses_.reserve(1); + superClasses_.push_back(resolver_->getClass("java/lang/Object")); + addField("super", superClasses_[0]->getStructType()); addField("", Type::UIntTy); addField("", ArrayType::get(componentClass_->getType(), 0)); + + interfaces_.reserve(2); + interfaces_.push_back(resolver_->getClass("java/lang/Cloneable")); + interfaces_.push_back(resolver_->getClass("java/io/Serializable")); } else { + // This is java/lang/Object. + if (!classFile_->getSuperClass()) + addField("base", resolver_->getObjectBaseType()); // This is any class but java/lang/Object. - if (classFile_->getSuperClass()) { + else { + // Our direct super class. const Class* superClass = resolver_->getClass(classFile_->getSuperClass()->getName()->str()); + // Add the interfaces of our direct superclass. + for (unsigned i = 0, e = superClass->getNumInterfaces(); i != e; ++i) + interfaces_.push_back(superClass->getInterface(i)); + + // For each of the interfaces we implement, load it and add that + // interface and all the interfaces it inherits from. + for (unsigned i = 0, e = classFile_->getNumInterfaces(); i != e; ++i) { + const Class* interface = getClass(classFile_->getInterfaceIndex(i)); + interfaces_.push_back(interface); + for (unsigned j = 0, f = interface->getNumInterfaces(); j != f; ++j) + interfaces_.push_back(interface->getInterface(j)); + } + + // Sort the interfaces array and remove duplicates. + std::sort(interfaces_.begin(), interfaces_.end()); + interfaces_.erase(std::unique(interfaces_.begin(), interfaces_.end()), + interfaces_.end()); + // We first add the struct of the super class. addField("super", superClass->getStructType()); - // Although we can safely assume that all interfaces inherits + // Although we can safely assume that all interfaces inherit // from java/lang/Object, java/lang/Class.getSuperclass() // returns null on interface types. So we only set the // superClass_ field when the class is not an interface type, @@ -119,12 +143,15 @@ // inherits java/lang/Object. if (classFile_->isInterface()) interfaceIndex_ = resolver_->getNextInterfaceIndex(); - else - superClass_ = superClass; + else { + // Build the super classes array. The first class is the + // direct super class of this class. + superClasses_.reserve(superClass->getNumSuperClasses() + 1); + superClasses_.push_back(superClass); + for (unsigned i = 0, e = superClass->getNumSuperClasses(); i != e; ++i) + superClasses_.push_back(superClass->getSuperClass(i)); + } } - // This is java/lang/Object. - else - addField("base", resolver_->getObjectBaseType()); // Then we add the rest of the fields. const Fields& fields = classFile_->getFields(); From alkis at cs.uiuc.edu Sat Mar 26 22:45:02 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat, 26 Mar 2005 22:45:02 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Message-ID: <200503270445.WAA06428@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Compiler.cpp updated: 1.258 -> 1.259 --- Log message: Use superclasses and interfaces in Class to make looking up a static variable a bit more efficient. --- Diffs of the changes: (+29 -24) Compiler.cpp | 53 +++++++++++++++++++++++++++++------------------------ 1 files changed, 29 insertions(+), 24 deletions(-) Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.258 llvm-java/lib/Compiler/Compiler.cpp:1.259 --- llvm-java/lib/Compiler/Compiler.cpp:1.258 Sat Mar 26 22:20:22 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 22:44:51 2005 @@ -797,7 +797,7 @@ const std::string& className = fieldRef->getClass()->getName()->str(); GlobalVariable* global = - getStaticField(ClassFile::get(className), + getStaticField(class_->getClass(fieldRef->getClassIndex()), nameAndType->getName()->str(), resolver_->getType(nameAndType->getDescriptor()->str())); @@ -808,35 +808,40 @@ /// Finds a static field in the specified class, any of its /// super clases, or any of the interfaces it implements. - GlobalVariable* getStaticField(const ClassFile* cf, + GlobalVariable* getStaticField(const Class* clazz, const std::string& name, const Type* type) { - // Emit the static initializers for this class, making sure that - // the globals are inserted into the module. - emitStaticInitializers(cf); - const std::string& className = cf->getThisClass()->getName()->str(); - const std::string& globalName = className + '/' + name; + emitStaticInitializers(clazz->getClassFile()); + std::string globalName = + clazz->getClassFile()->getThisClass()->getName()->str() + '/' + name; DEBUG(std::cerr << "Looking up global: " << globalName << '\n'); - GlobalVariable* global = module_->getGlobalVariable(globalName, type); - if (global) - return global; - - for (unsigned i = 0, e = cf->getNumInterfaces(); i != e; ++i) { - const ClassFile* ifaceCF = - ClassFile::get(cf->getInterface(i)->getName()->str()); - if (global = getStaticField(ifaceCF, name, type)) - return global; + if (GlobalVariable* g = module_->getGlobalVariable(globalName, type)) + return g; + + for (unsigned i = 0, e = clazz->getNumInterfaces(); i != e; ++i) { + const Class* interface = clazz->getInterface(i); + emitStaticInitializers(interface->getClassFile()); + globalName = + interface->getClassFile()->getThisClass()->getName()->str() + + '/' + name; + DEBUG(std::cerr << "Looking up global: " << globalName << '\n'); + if (GlobalVariable* g = module_->getGlobalVariable(globalName, type)) + return g; + } + + for (unsigned i = 0, e = clazz->getNumSuperClasses(); i != e; ++i) { + const Class* superClass = clazz->getSuperClass(i); + emitStaticInitializers(superClass->getClassFile()); + globalName = + superClass->getClassFile()->getThisClass()->getName()->str() + + '/' + name; + DEBUG(std::cerr << "Looking up global: " << globalName << '\n'); + if (GlobalVariable* g = module_->getGlobalVariable(globalName, type)) + return g; } - // If we have no super class it means the lookup terminates - // unsuccesfully. - if (!cf->getSuperClass()) - return NULL; - - const ClassFile* superCF = - ClassFile::get(cf->getSuperClass()->getName()->str()); - return getStaticField(superCF, name, type); + return NULL; } /// Emits the necessary code to get a field from the passed From lattner at cs.uiuc.edu Sun Mar 27 12:58:40 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 27 Mar 2005 12:58:40 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/Andersens.cpp Message-ID: <200503271858.j2RIwelG021551@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: Andersens.cpp updated: 1.11 -> 1.12 --- Log message: teach andersens about undef --- Diffs of the changes: (+1 -1) Andersens.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/IPA/Andersens.cpp diff -u llvm/lib/Analysis/IPA/Andersens.cpp:1.11 llvm/lib/Analysis/IPA/Andersens.cpp:1.12 --- llvm/lib/Analysis/IPA/Andersens.cpp:1.11 Mon Mar 14 22:54:18 2005 +++ llvm/lib/Analysis/IPA/Andersens.cpp Sun Mar 27 12:58:23 2005 @@ -481,7 +481,7 @@ Andersens::Node *Andersens::getNodeForConstantPointer(Constant *C) { assert(isa(C->getType()) && "Not a constant pointer!"); - if (isa(C)) + if (isa(C) || isa(C)) return &GraphNodes[NullPtr]; else if (GlobalValue *GV = dyn_cast(C)) return getNode(GV); From lattner at cs.uiuc.edu Sun Mar 27 15:57:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 27 Mar 2005 15:57:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200503272157.j2RLvPKE022349@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.36 -> 1.37 --- Log message: remove ... --- Diffs of the changes: (+2 -2) DataStructureAA.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.36 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.37 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.36 Sat Mar 26 18:02:33 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Sun Mar 27 15:57:09 2005 @@ -140,8 +140,8 @@ if (N1 == 0 || N2 == 0) // Can't tell whether anything aliases null. return AliasAnalysis::alias(V1, V1Size, V2, V2Size); - - // We can only make a judgment of one of the nodes is complete... + + // We can only make a judgment if one of the nodes is complete. if (N1->isComplete() || N2->isComplete()) { if (N1 != N2) return NoAlias; // Completely different nodes. From lattner at cs.uiuc.edu Sun Mar 27 15:57:39 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 27 Mar 2005 15:57:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200503272157.j2RLvdxG022356@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.57 -> 1.58 --- Log message: speed up steens by using spliceFrom, improve its precision by realizing that an incomplete node cannot alias a complete node. --- Diffs of the changes: (+10 -5) Steensgaard.cpp | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.57 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.58 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.57 Sat Mar 26 16:43:20 2005 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Sun Mar 27 15:56:55 2005 @@ -124,7 +124,7 @@ // for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) - ResultGraph->cloneInto(LDS.getDSGraph(*I)); + ResultGraph->spliceFrom(LDS.getDSGraph(*I)); ResultGraph->removeTriviallyDeadNodes(); @@ -191,13 +191,18 @@ DSGraph::ScalarMapTy &GSM = ResultGraph->getScalarMap(); DSGraph::ScalarMapTy::iterator I = GSM.find(const_cast(V1)); + DSGraph::ScalarMapTy::iterator J = GSM.find(const_cast(V2)); if (I != GSM.end() && !I->second.isNull() && - I->second.getNode()->isComplete()) { + J != GSM.end() && !J->second.isNull()) { DSNodeHandle &V1H = I->second; - DSGraph::ScalarMapTy::iterator J=GSM.find(const_cast(V2)); - if (J != GSM.end() && !J->second.isNull() && + DSNodeHandle &V2H = J->second; + + // If at least one of the nodes is complete, we can say something about + // this. If one is complete and the other isn't, then they are obviously + // different nodes. If they are both complete, we can't say anything + // useful. + if (I->second.getNode()->isComplete() || J->second.getNode()->isComplete()) { - DSNodeHandle &V2H = J->second; // If the two pointers point to different data structure graph nodes, they // cannot alias! if (V1H.getNode() != V2H.getNode()) From lattner at cs.uiuc.edu Sun Mar 27 16:03:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 27 Mar 2005 16:03:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/Andersens.cpp Message-ID: <200503272203.j2RM3xQm022683@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: Andersens.cpp updated: 1.12 -> 1.13 --- Log message: wrap some long lines --- Diffs of the changes: (+10 -5) Andersens.cpp | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) Index: llvm/lib/Analysis/IPA/Andersens.cpp diff -u llvm/lib/Analysis/IPA/Andersens.cpp:1.12 llvm/lib/Analysis/IPA/Andersens.cpp:1.13 --- llvm/lib/Analysis/IPA/Andersens.cpp:1.12 Sun Mar 27 12:58:23 2005 +++ llvm/lib/Analysis/IPA/Andersens.cpp Sun Mar 27 16:03:46 2005 @@ -433,7 +433,8 @@ ++NumObjects; // Add all the globals first. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { ObjectNodes[I] = NumObjects++; ValueNodes[I] = NumObjects++; } @@ -449,7 +450,8 @@ VarargNodes[F] = NumObjects++; // Add nodes for all of the incoming pointer arguments. - for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); + I != E; ++I) if (isa(I->getType())) ValueNodes[I] = NumObjects++; @@ -571,7 +573,8 @@ GraphNodes[NullPtr].addPointerTo(&GraphNodes[NullObject]); // Next, add any constraints on global variables and their initializers. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { // Associate the address of the global object as pointing to the memory for // the global: &G = Node *Object = getObject(I); @@ -599,7 +602,8 @@ getVarargNode(F)->setValue(F); // Set up incoming argument nodes. - for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); + I != E; ++I) if (isa(I->getType())) getNodeValue(*I); @@ -620,7 +624,8 @@ // Any pointers that are passed into the function have the universal set // stored into them. - for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); + I != E; ++I) if (isa(I->getType())) { // Pointers passed into external functions could have anything stored // through them. From alkis at cs.uiuc.edu Sun Mar 27 20:01:24 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 27 Mar 2005 20:01:24 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200503280201.UAA27758@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.109 -> 1.110 --- Log message: Rename createPromoteMemoryToRegister() to createPromoteMemoryToRegisterPass() to be consistent with other pass creation functions. --- Diffs of the changes: (+1 -1) gccas.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.109 llvm/tools/gccas/gccas.cpp:1.110 --- llvm/tools/gccas/gccas.cpp:1.109 Sun Mar 6 21:19:50 2005 +++ llvm/tools/gccas/gccas.cpp Sun Mar 27 20:01:12 2005 @@ -83,7 +83,7 @@ addPass(PM, createRaiseAllocationsPass()); // call %malloc -> malloc inst addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code - addPass(PM, createPromoteMemoryToRegister()); // Kill useless allocas + addPass(PM, createPromoteMemoryToRegisterPass());// Kill useless allocas addPass(PM, createGlobalOptimizerPass()); // Optimize out global vars addPass(PM, createGlobalDCEPass()); // Remove unused fns and globs addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation From alkis at cs.uiuc.edu Sun Mar 27 20:01:24 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 27 Mar 2005 20:01:24 -0600 Subject: [llvm-commits] CVS: llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp Message-ID: <200503280201.UAA27754@zion.cs.uiuc.edu> Changes in directory llvm/projects/Stacker/lib/compiler: StackerCompiler.cpp updated: 1.11 -> 1.12 --- Log message: Rename createPromoteMemoryToRegister() to createPromoteMemoryToRegisterPass() to be consistent with other pass creation functions. --- Diffs of the changes: (+1 -1) StackerCompiler.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp diff -u llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.11 llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.12 --- llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp:1.11 Wed Oct 6 23:10:36 2004 +++ llvm/projects/Stacker/lib/compiler/StackerCompiler.cpp Sun Mar 27 20:01:12 2005 @@ -331,7 +331,7 @@ // Merge & remove BBs Passes.add(createCFGSimplificationPass()); // Memory To Register - Passes.add(createPromoteMemoryToRegister()); + Passes.add(createPromoteMemoryToRegisterPass()); // Compile silly sequences Passes.add(createInstructionCombiningPass()); // Make sure everything is still good. From alkis at cs.uiuc.edu Sun Mar 27 20:01:24 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 27 Mar 2005 20:01:24 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Scalar.h Message-ID: <200503280201.UAA27760@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: Scalar.h updated: 1.53 -> 1.54 --- Log message: Rename createPromoteMemoryToRegister() to createPromoteMemoryToRegisterPass() to be consistent with other pass creation functions. --- Diffs of the changes: (+1 -1) Scalar.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.53 llvm/include/llvm/Transforms/Scalar.h:1.54 --- llvm/include/llvm/Transforms/Scalar.h:1.53 Thu Mar 3 22:04:26 2005 +++ llvm/include/llvm/Transforms/Scalar.h Sun Mar 27 20:01:12 2005 @@ -160,7 +160,7 @@ // %Y = load int* %X // ret int %Y // -FunctionPass *createPromoteMemoryToRegister(); +FunctionPass *createPromoteMemoryToRegisterPass(); //===----------------------------------------------------------------------===// From alkis at cs.uiuc.edu Sun Mar 27 20:01:24 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 27 Mar 2005 20:01:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/Mem2Reg.cpp Message-ID: <200503280201.UAA27766@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: Mem2Reg.cpp updated: 1.12 -> 1.13 --- Log message: Rename createPromoteMemoryToRegister() to createPromoteMemoryToRegisterPass() to be consistent with other pass creation functions. --- Diffs of the changes: (+1 -2) Mem2Reg.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/Transforms/Scalar/Mem2Reg.cpp diff -u llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.12 llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.13 --- llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.12 Sun Sep 19 23:43:15 2004 +++ llvm/lib/Transforms/Scalar/Mem2Reg.cpp Sun Mar 27 20:01:12 2005 @@ -76,7 +76,6 @@ // createPromoteMemoryToRegister - Provide an entry point to create this pass. // -FunctionPass *llvm::createPromoteMemoryToRegister() { +FunctionPass *llvm::createPromoteMemoryToRegisterPass() { return new PromotePass(); } - From alkis at cs.uiuc.edu Sun Mar 27 20:46:30 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 27 Mar 2005 20:46:30 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.h Compiler.cpp Class.h Class.cpp Message-ID: <200503280246.UAA28214@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.h updated: 1.5 -> 1.6 Compiler.cpp updated: 1.259 -> 1.260 Class.h updated: 1.11 -> 1.12 Class.cpp updated: 1.11 -> 1.12 --- Log message: Resolve and cache field descriptors as well. --- Diffs of the changes: (+44 -20) Class.cpp | 21 +++++++++++++++++++-- Class.h | 3 ++- Compiler.cpp | 38 +++++++++++++++++++++----------------- Resolver.h | 2 ++ 4 files changed, 44 insertions(+), 20 deletions(-) Index: llvm-java/lib/Compiler/Resolver.h diff -u llvm-java/lib/Compiler/Resolver.h:1.5 llvm-java/lib/Compiler/Resolver.h:1.6 --- llvm-java/lib/Compiler/Resolver.h:1.5 Sat Mar 26 18:04:10 2005 +++ llvm-java/lib/Compiler/Resolver.h Sun Mar 27 20:46:19 2005 @@ -46,6 +46,8 @@ return classMap_.insert(i, std::make_pair(clazz.getName(), clazz)); } + friend class Class; + public: static std::string canonicalizeClassName(const std::string& className) { if (className[0] == '[') Index: llvm-java/lib/Compiler/Compiler.cpp diff -u llvm-java/lib/Compiler/Compiler.cpp:1.259 llvm-java/lib/Compiler/Compiler.cpp:1.260 --- llvm-java/lib/Compiler/Compiler.cpp:1.259 Sat Mar 26 22:44:51 2005 +++ llvm-java/lib/Compiler/Compiler.cpp Sun Mar 27 20:46:19 2005 @@ -796,10 +796,10 @@ ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); const std::string& className = fieldRef->getClass()->getName()->str(); - GlobalVariable* global = - getStaticField(class_->getClass(fieldRef->getClassIndex()), - nameAndType->getName()->str(), - resolver_->getType(nameAndType->getDescriptor()->str())); + GlobalVariable* global = getStaticField( + class_->getClassForClass(fieldRef->getClassIndex()), + nameAndType->getName()->str(), + class_->getClassForDescriptor(nameAndType->getDescriptorIndex())); assert(global && "Cannot find global for static field!"); @@ -810,12 +810,13 @@ /// super clases, or any of the interfaces it implements. GlobalVariable* getStaticField(const Class* clazz, const std::string& name, - const Type* type) { + const Class* fieldClass) { emitStaticInitializers(clazz->getClassFile()); std::string globalName = clazz->getClassFile()->getThisClass()->getName()->str() + '/' + name; DEBUG(std::cerr << "Looking up global: " << globalName << '\n'); + const Type* type = fieldClass->getType(); if (GlobalVariable* g = module_->getGlobalVariable(globalName, type)) return g; @@ -851,7 +852,7 @@ class_->getClassFile()->getConstantFieldRef(index); ConstantNameAndType* nameAndType = fieldRef->getNameAndType(); return getField( - class_->getClass(fieldRef->getClassIndex()), + class_->getClassForClass(fieldRef->getClassIndex()), nameAndType->getName()->str(), ptr); } @@ -1100,7 +1101,9 @@ for (unsigned i = 0, e = fields.size(); i != e; ++i) { Field* field = fields[i]; if (field->isStatic()) { - const Type* globalTy = resolver_->getType(field->getDescriptor()->str()); + const Class* fieldClass = + clazz->getClassForDescriptor(field->getDescriptorIndex()); + const Type* globalTy = fieldClass->getType(); // A java field can be final/constant even if it has a // dynamic initializer. Because LLVM does not currently // support these semantics, we consider constants only @@ -1633,8 +1636,9 @@ void do_putfield(unsigned index) { ConstantFieldRef* fieldRef = class_->getClassFile()->getConstantFieldRef(index); - const Type* type = - resolver_->getType(fieldRef->getNameAndType()->getDescriptor()->str()); + const Class* fieldClass = class_->getClassForDescriptor( + fieldRef->getNameAndType()->getDescriptorIndex()); + const Type* type = fieldClass->getType(); Value* v = pop(type); Value* p = pop(resolver_->getObjectBaseRefType()); Value* fp = getField(index, p); @@ -1686,7 +1690,7 @@ const std::string& className = methodRef->getClass()->getName()->str(); - const Class* clazz = class_->getClass(methodRef->getClassIndex()); + const Class* clazz = class_->getClassForClass(methodRef->getClassIndex()); const VTableInfo* vi = getVTableInfoGeneric(clazz); const std::string& methodDescr = @@ -1728,7 +1732,7 @@ const std::string& methodDescr = methodName + nameAndType->getDescriptor()->str(); std::string funcName = className + '/' + methodDescr; - const Class* clazz = class_->getClass(methodRef->getClassIndex()); + const Class* clazz = class_->getClassForClass(methodRef->getClassIndex()); const FunctionType* funcTy = cast( resolver_->getType(nameAndType->getDescriptor()->str(), true)); @@ -1740,7 +1744,7 @@ void do_invokestatic(unsigned index) { ConstantMethodRef* methodRef = class_->getClassFile()->getConstantMethodRef(index); - const Class* clazz = class_->getClass(methodRef->getClassIndex()); + const Class* clazz = class_->getClassForClass(methodRef->getClassIndex()); emitStaticInitializers(clazz->getClassFile()); Method* method = getMethod(methodRef); Function* function = getFunction(method); @@ -1767,7 +1771,7 @@ const std::string& className = methodRef->getClass()->getName()->str(); - const Class* clazz = class_->getClass(methodRef->getClassIndex()); + const Class* clazz = class_->getClassForClass(methodRef->getClassIndex()); const VTableInfo* vi = getVTableInfoGeneric(clazz); const std::string& methodDescr = @@ -1840,7 +1844,7 @@ } void do_new(unsigned index) { - const Class* clazz = class_->getClass(index); + const Class* clazz = class_->getClassForClass(index); emitStaticInitializers(clazz->getClassFile()); const VTableInfo& vi = getVTableInfo(clazz); @@ -1929,7 +1933,7 @@ void do_anewarray(unsigned index) { Value* count = pop(Type::UIntTy); - const Class* clazz = class_->getClass(index); + const Class* clazz = class_->getClassForClass(index); const Class* arrayClass = resolver_->getArrayClass(clazz); const VTableInfo* vi = getVTableInfoGeneric(arrayClass); @@ -1951,7 +1955,7 @@ } void do_checkcast(unsigned index) { - const Class* clazz = class_->getClass(index); + const Class* clazz = class_->getClassForClass(index); const VTableInfo* vi = getVTableInfoGeneric(clazz); Value* objRef = pop(resolver_->getObjectBaseRefType()); @@ -1968,7 +1972,7 @@ } void do_instanceof(unsigned index) { - const Class* clazz = class_->getClass(index); + const Class* clazz = class_->getClassForClass(index); const VTableInfo* vi = getVTableInfoGeneric(clazz); Value* objRef = pop(resolver_->getObjectBaseRefType()); Index: llvm-java/lib/Compiler/Class.h diff -u llvm-java/lib/Compiler/Class.h:1.11 llvm-java/lib/Compiler/Class.h:1.12 --- llvm-java/lib/Compiler/Class.h:1.11 Sat Mar 26 22:20:22 2005 +++ llvm-java/lib/Compiler/Class.h Sun Mar 27 20:46:19 2005 @@ -88,7 +88,8 @@ int getFieldIndex(const std::string& name) const; llvm::Constant* getConstant(unsigned index) const; - const Class* getClass(unsigned index) const; + const Class* getClassForClass(unsigned index) const; + const Class* getClassForDescriptor(unsigned index) const; }; } } // namespace llvm::Java Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.11 llvm-java/lib/Compiler/Class.cpp:1.12 --- llvm-java/lib/Compiler/Class.cpp:1.11 Sat Mar 26 22:20:22 2005 +++ llvm-java/lib/Compiler/Class.cpp Sun Mar 27 20:46:19 2005 @@ -121,7 +121,8 @@ // For each of the interfaces we implement, load it and add that // interface and all the interfaces it inherits from. for (unsigned i = 0, e = classFile_->getNumInterfaces(); i != e; ++i) { - const Class* interface = getClass(classFile_->getInterfaceIndex(i)); + const Class* interface = + getClassForClass(classFile_->getInterfaceIndex(i)); interfaces_.push_back(interface); for (unsigned j = 0, f = interface->getNumInterfaces(); j != f; ++j) interfaces_.push_back(interface->getInterface(j)); @@ -210,7 +211,7 @@ return static_cast(resolvedConstantPool_[index]); } -const Class* Class::getClass(unsigned index) const +const Class* Class::getClassForClass(unsigned index) const { assert(classFile_ && "No constant pool!"); assert(dynamic_cast(classFile_->getConstant(index)) && @@ -225,3 +226,19 @@ return static_cast(resolvedConstantPool_[index]); } + +const Class* Class::getClassForDescriptor(unsigned index) const +{ + assert(classFile_ && "No constant pool!"); + assert(dynamic_cast(classFile_->getConstant(index)) && + "Not an index to a descriptor reference!"); + + // If we haven't resolved this constant already, do so now. + if (!resolvedConstantPool_[index]) { + ConstantUtf8* jc = classFile_->getConstantUtf8(index); + resolvedConstantPool_[index] = + const_cast(resolver_->getClassForDesc(jc->str())); + } + + return static_cast(resolvedConstantPool_[index]); +} From alkis at cs.uiuc.edu Sun Mar 27 20:48:36 2005 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun, 27 Mar 2005 20:48:36 -0600 Subject: [llvm-commits] CVS: llvm-java/lib/Compiler/Resolver.h Class.cpp Message-ID: <200503280248.UAA28257@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/Compiler: Resolver.h updated: 1.6 -> 1.7 Class.cpp updated: 1.12 -> 1.13 --- Log message: Remove unneeded function now that we can resolve field descriptors. --- Diffs of the changes: (+5 -6) Class.cpp | 7 ++++--- Resolver.h | 4 +--- 2 files changed, 5 insertions(+), 6 deletions(-) Index: llvm-java/lib/Compiler/Resolver.h diff -u llvm-java/lib/Compiler/Resolver.h:1.6 llvm-java/lib/Compiler/Resolver.h:1.7 --- llvm-java/lib/Compiler/Resolver.h:1.6 Sun Mar 27 20:46:19 2005 +++ llvm-java/lib/Compiler/Resolver.h Sun Mar 27 20:48:25 2005 @@ -76,9 +76,7 @@ const Class* getClass(const std::string& className) { return getClassForDesc(canonicalizeClassName(className)); } - const Class* getClass(const Field& field) { - return getClassForDesc(field.getDescriptor()->str()); - } + const Class* getClass(JType type); const Class* getArrayClass(const Class* clazz) { Index: llvm-java/lib/Compiler/Class.cpp diff -u llvm-java/lib/Compiler/Class.cpp:1.12 llvm-java/lib/Compiler/Class.cpp:1.13 --- llvm-java/lib/Compiler/Class.cpp:1.12 Sun Mar 27 20:46:19 2005 +++ llvm-java/lib/Compiler/Class.cpp Sun Mar 27 20:48:25 2005 @@ -157,9 +157,10 @@ // Then we add the rest of the fields. const Fields& fields = classFile_->getFields(); for (unsigned i = 0, e = fields.size(); i != e; ++i) { - Field& field = *fields[i]; - if (!field.isStatic()) - addField(field.getName()->str(), resolver_->getClass(field)->getType()); + Field* field = fields[i]; + if (!field->isStatic()) + addField(field->getName()->str(), + getClassForDescriptor(field->getDescriptorIndex())->getType()); } } From jeffc at jolt-lang.org Sun Mar 27 20:52:39 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sun, 27 Mar 2005 20:52:39 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/LinkAllPasses.h Message-ID: <200503280252.UAA28289@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: LinkAllPasses.h updated: 1.15 -> 1.16 --- Log message: Fix VC++ build breakage --- Diffs of the changes: (+1 -1) LinkAllPasses.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/include/llvm/Transforms/LinkAllPasses.h diff -u llvm/include/llvm/Transforms/LinkAllPasses.h:1.15 llvm/include/llvm/Transforms/LinkAllPasses.h:1.16 --- llvm/include/llvm/Transforms/LinkAllPasses.h:1.15 Fri Jan 28 01:29:15 2005 +++ llvm/include/llvm/Transforms/LinkAllPasses.h Sun Mar 27 20:52:28 2005 @@ -98,7 +98,7 @@ (void) llvm::createPREPass(); (void) llvm::createProfileLoaderPass(); (void) llvm::createProfilePathsPass(); - (void) llvm::createPromoteMemoryToRegister(); + (void) llvm::createPromoteMemoryToRegisterPass(); (void) llvm::createPruneEHPass(); (void) llvm::createRaiseAllocationsPass(); (void) llvm::createRaisePointerReferencesPass(); From lattner at cs.uiuc.edu Sun Mar 27 22:04:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 27 Mar 2005 22:04:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/Andersens.cpp Message-ID: <200503280404.j2S448Jc027069@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: Andersens.cpp updated: 1.13 -> 1.14 --- Log message: Make anders-aa much more precise by not being completely pessimistic about external functions. Teach it about a few important ones. --- Diffs of the changes: (+39 -1) Andersens.cpp | 40 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 39 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/IPA/Andersens.cpp diff -u llvm/lib/Analysis/IPA/Andersens.cpp:1.13 llvm/lib/Analysis/IPA/Andersens.cpp:1.14 --- llvm/lib/Analysis/IPA/Andersens.cpp:1.13 Sun Mar 27 16:03:46 2005 +++ llvm/lib/Analysis/IPA/Andersens.cpp Sun Mar 27 22:03:52 2005 @@ -92,6 +92,7 @@ } /// getValue - Return the LLVM value corresponding to this node. + /// Value *getValue() const { return Val; } typedef std::vector::const_iterator iterator; @@ -302,7 +303,9 @@ Node *getNodeForConstantPointer(Constant *C); Node *getNodeForConstantPointerTarget(Constant *C); void AddGlobalInitializerConstraints(Node *N, Constant *C); + void AddConstraintsForNonInternalLinkage(Function *F); + bool AddConstraintsForExternalFunction(Function *F); void AddConstraintsForCall(CallSite CS, Function *F); @@ -354,6 +357,7 @@ return AliasAnalysis::alias(V1, V1Size, V2, V2Size); } + /// getMustAlias - We can provide must alias information if we know that a /// pointer can only point to a specific function or the null pointer. /// Unfortunately we cannot determine must-alias information for global @@ -551,6 +555,9 @@ } } +/// AddConstraintsForNonInternalLinkage - If this function does not have +/// internal linkage, realize that we can't trust anything passed into or +/// returned by this function. void Andersens::AddConstraintsForNonInternalLinkage(Function *F) { for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) if (isa(I->getType())) @@ -560,6 +567,35 @@ &GraphNodes[UniversalSet])); } +/// AddConstraintsForExternalFunction - If this is a call to a "known" function, +/// add the constraints an return false. If this is a call to an unknown +/// function, return true. +bool Andersens::AddConstraintsForExternalFunction(Function *F) { + assert(F->isExternal() && "Not an external function!"); + + // These functions don't induce any points-to constraints. + if (F->getName() == "printf" || F->getName() == "fprintf" || + F->getName() == "open" || F->getName() == "fopen" || + F->getName() == "atoi" || + F->getName() == "llvm.memset" || F->getName() == "memcmp" || + F->getName() == "read" || F->getName() == "write") + return false; + + // These functions do induce points-to edges. + if (F->getName() == "llvm.memcpy" || F->getName() == "llvm.memmove") { + Function::arg_iterator Dst = F->arg_begin(), Src = Dst; + // Note: this is a poor approximation, this says Dest = Src, instead of + // *Dest = *Src. + ++Src; + Constraints.push_back(Constraint(Constraint::Copy, getNode(Dst), + getNode(Src))); + return false; + } + + return true; +} + + /// CollectConstraints - This stage scans the program, adding a constraint to /// the Constraints list for each instruction in the program that induces a @@ -615,7 +651,9 @@ // allocation in the body of the function and a node to represent all // pointer values defined by instructions and used as operands. visit(F); - } else { + } else if (AddConstraintsForExternalFunction(F)) { + // If we don't "know" about this function, assume the worst. + // External functions that return pointers return the universal set. if (isa(F->getFunctionType()->getReturnType())) Constraints.push_back(Constraint(Constraint::Copy, From brukman at cs.uiuc.edu Sun Mar 27 22:32:23 2005 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun, 27 Mar 2005 22:32:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/Andersens.cpp Message-ID: <200503280432.WAA29038@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: Andersens.cpp updated: 1.14 -> 1.15 --- Log message: Fix grammar --- Diffs of the changes: (+1 -1) Andersens.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/IPA/Andersens.cpp diff -u llvm/lib/Analysis/IPA/Andersens.cpp:1.14 llvm/lib/Analysis/IPA/Andersens.cpp:1.15 --- llvm/lib/Analysis/IPA/Andersens.cpp:1.14 Sun Mar 27 22:03:52 2005 +++ llvm/lib/Analysis/IPA/Andersens.cpp Sun Mar 27 22:32:12 2005 @@ -568,7 +568,7 @@ } /// AddConstraintsForExternalFunction - If this is a call to a "known" function, -/// add the constraints an return false. If this is a call to an unknown +/// add the constraints and return false. If this is a call to an unknown /// function, return true. bool Andersens::AddConstraintsForExternalFunction(Function *F) { assert(F->isExternal() && "Not an external function!");