From lattner at cs.uiuc.edu Mon Dec 22 13:25:28 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 22 13:25:28 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200312220953.DAA13036@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.49 -> 1.50 --- Log message: Don't mind me, I'm just refactoring away. This patch makes room for LFTR, but contains no functionality changes. --- Diffs of the changes: (+128 -88) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.49 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.50 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.49 Sun Dec 21 23:02:01 2003 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Dec 22 03:53:29 2003 @@ -52,6 +52,9 @@ return TD->getTypeSize(Ty); // Must be a pointer } + Value *ComputeAuxIndVarValue(InductionVariable &IV, Value *CIV); + void ReplaceIndVar(InductionVariable &IV, Value *Counter); + bool runOnLoop(Loop *L); virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -192,104 +195,141 @@ DEBUG(IV->print(std::cerr)); - while (isa(AfterPHIIt)) ++AfterPHIIt; - // Don't modify the canonical indvar or unrecognized indvars... if (IV != Canonical && IV->InductionType != InductionVariable::Unknown) { - const Type *IVTy = IV->Phi->getType(); - if (isa(IVTy)) // If indexing into a pointer, make the - IVTy = TD->getIntPtrType(); // index the appropriate type. - - Instruction *Val = IterCount; - if (!isa(IV->Step) || // If the step != 1 - !cast(IV->Step)->equalsInt(1)) { - - // If the types are not compatible, insert a cast now... - if (Val->getType() != IVTy) - Val = new CastInst(Val, IVTy, Val->getName(), AfterPHIIt); - if (IV->Step->getType() != IVTy) - IV->Step = new CastInst(IV->Step, IVTy, IV->Step->getName(), - AfterPHIIt); + ReplaceIndVar(*IV, IterCount); + Changed = true; + ++NumRemoved; + } + } - Val = BinaryOperator::create(Instruction::Mul, Val, IV->Step, - IV->Phi->getName()+"-scale", AfterPHIIt); - } + return Changed; +} - // If this is a pointer indvar... - if (isa(IV->Phi->getType())) { - std::vector Idx; - // FIXME: this should not be needed when we fix PR82! - if (Val->getType() != Type::LongTy) - Val = new CastInst(Val, Type::LongTy, Val->getName(), AfterPHIIt); - Idx.push_back(Val); - Val = new GetElementPtrInst(IV->Start, Idx, - IV->Phi->getName()+"-offset", - AfterPHIIt); - - } else if (!isa(IV->Start) || // If Start != 0... - !cast(IV->Start)->isNullValue()) { - // If the types are not compatible, insert a cast now... - if (Val->getType() != IVTy) - Val = new CastInst(Val, IVTy, Val->getName(), AfterPHIIt); - if (IV->Start->getType() != IVTy) - IV->Start = new CastInst(IV->Start, IVTy, IV->Start->getName(), - AfterPHIIt); - - // Insert the instruction after the phi nodes... - Val = BinaryOperator::create(Instruction::Add, Val, IV->Start, - IV->Phi->getName()+"-offset", AfterPHIIt); - } +/// ComputeAuxIndVarValue - Given an auxillary induction variable, compute and +/// return a value which will always be equal to the induction variable PHI, but +/// is based off of the canonical induction variable CIV. +/// +Value *IndVarSimplify::ComputeAuxIndVarValue(InductionVariable &IV, Value *CIV){ + Instruction *Phi = IV.Phi; + const Type *IVTy = Phi->getType(); + if (isa(IVTy)) // If indexing into a pointer, make the + IVTy = TD->getIntPtrType(); // index the appropriate type. - // If the PHI node has a different type than val is, insert a cast now... - if (Val->getType() != IV->Phi->getType()) - Val = new CastInst(Val, IV->Phi->getType(), Val->getName(), AfterPHIIt); - + BasicBlock::iterator AfterPHIIt = Phi; + while (isa(AfterPHIIt)) ++AfterPHIIt; + + Value *Val = CIV; + if (Val->getType() != IVTy) + Val = new CastInst(Val, IVTy, Val->getName(), AfterPHIIt); + + if (!isa(IV.Step) || // If the step != 1 + !cast(IV.Step)->equalsInt(1)) { + + // If the types are not compatible, insert a cast now... + if (IV.Step->getType() != IVTy) + IV.Step = new CastInst(IV.Step, IVTy, IV.Step->getName(), AfterPHIIt); + + Val = BinaryOperator::create(Instruction::Mul, Val, IV.Step, + Phi->getName()+"-scale", AfterPHIIt); + } + + // If this is a pointer indvar... + if (isa(Phi->getType())) { + std::vector Idx; + // FIXME: this should not be needed when we fix PR82! + if (Val->getType() != Type::LongTy) + Val = new CastInst(Val, Type::LongTy, Val->getName(), AfterPHIIt); + Idx.push_back(Val); + Val = new GetElementPtrInst(IV.Start, Idx, + Phi->getName()+"-offset", + AfterPHIIt); + + } else if (!isa(IV.Start) || // If Start != 0... + !cast(IV.Start)->isNullValue()) { + // If the types are not compatible, insert a cast now... + if (IV.Start->getType() != IVTy) + IV.Start = new CastInst(IV.Start, IVTy, IV.Start->getName(), + AfterPHIIt); + + // Insert the instruction after the phi nodes... + Val = BinaryOperator::create(Instruction::Add, Val, IV.Start, + Phi->getName()+"-offset", AfterPHIIt); + } + + // If the PHI node has a different type than val is, insert a cast now... + if (Val->getType() != Phi->getType()) + Val = new CastInst(Val, Phi->getType(), Val->getName(), AfterPHIIt); + + // Move the PHI name to it's new equivalent value... + std::string OldName = Phi->getName(); + Phi->setName(""); + Val->setName(OldName); + + return Val; +} + + +// ReplaceIndVar - Replace all uses of the specified induction variable with +// expressions computed from the specified loop iteration counter variable. +// Return true if instructions were deleted. +void IndVarSimplify::ReplaceIndVar(InductionVariable &IV, Value *CIV) { + Value *IndVarVal = 0; + PHINode *Phi = IV.Phi; + + assert(Phi->getNumOperands() == 4 && + "Only expect induction variables in canonical loops!"); + + // Remember the incoming values used by the PHI node + std::vector PHIOps; + PHIOps.reserve(2); + PHIOps.push_back(Phi->getIncomingValue(0)); + PHIOps.push_back(Phi->getIncomingValue(1)); + + // Delete all of the operands of the PHI node... FIXME, this should be more + // intelligent. + Phi->dropAllReferences(); + + // Now that we are rid of unneeded uses of the PHI node, replace any remaining + // ones with the appropriate code using the canonical induction variable. + while (!Phi->use_empty()) { + Instruction *U = cast(Phi->use_back()); + + // TODO: Perform LFTR here if possible + if (0) { + + } else { // Replace all uses of the old PHI node with the new computed value... - IV->Phi->replaceAllUsesWith(Val); + if (IndVarVal == 0) + IndVarVal = ComputeAuxIndVarValue(IV, CIV); + U->replaceUsesOfWith(Phi, IndVarVal); + } + } - // Move the PHI name to it's new equivalent value... - std::string OldName = IV->Phi->getName(); - IV->Phi->setName(""); - Val->setName(OldName); - - // Get the incoming values used by the PHI node - std::vector PHIOps; - PHIOps.reserve(IV->Phi->getNumIncomingValues()); - for (unsigned i = 0, e = IV->Phi->getNumIncomingValues(); i != e; ++i) - PHIOps.push_back(IV->Phi->getIncomingValue(i)); - - // Delete the old, now unused, phi node... - Header->getInstList().erase(IV->Phi); - - // If the PHI is the last user of any instructions for computing PHI nodes - // that are irrelevant now, delete those instructions. - while (!PHIOps.empty()) { - Instruction *MaybeDead = dyn_cast(PHIOps.back()); - PHIOps.pop_back(); - - if (MaybeDead && isInstructionTriviallyDead(MaybeDead)) { - PHIOps.insert(PHIOps.end(), MaybeDead->op_begin(), - MaybeDead->op_end()); - MaybeDead->getParent()->getInstList().erase(MaybeDead); - - // Erase any duplicates entries in the PHIOps list. - std::vector::iterator It = - std::find(PHIOps.begin(), PHIOps.end(), MaybeDead); - while (It != PHIOps.end()) { - PHIOps.erase(It); - It = std::find(PHIOps.begin(), PHIOps.end(), MaybeDead); - } - - // Erasing the instruction could invalidate the AfterPHI iterator! - AfterPHIIt = Header->begin(); - } + // If the PHI is the last user of any instructions for computing PHI nodes + // that are irrelevant now, delete those instructions. + while (!PHIOps.empty()) { + Instruction *MaybeDead = dyn_cast(PHIOps.back()); + PHIOps.pop_back(); + + if (MaybeDead && isInstructionTriviallyDead(MaybeDead) && + (!isa(MaybeDead) || + MaybeDead->getParent() != Phi->getParent())) { + PHIOps.insert(PHIOps.end(), MaybeDead->op_begin(), + MaybeDead->op_end()); + MaybeDead->getParent()->getInstList().erase(MaybeDead); + + // Erase any duplicates entries in the PHIOps list. + std::vector::iterator It = + std::find(PHIOps.begin(), PHIOps.end(), MaybeDead); + while (It != PHIOps.end()) { + PHIOps.erase(It); + It = std::find(PHIOps.begin(), PHIOps.end(), MaybeDead); } - - Changed = true; - ++NumRemoved; } } - return Changed; + // Delete the old, now unused, phi node... + Phi->getParent()->getInstList().erase(Phi); } From vadve at cs.uiuc.edu Mon Dec 22 13:25:38 2003 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Mon Dec 22 13:25:38 2003 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200312221852.MAA02440@psmith.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.93 -> 1.94 --- Log message: Fix paragraph on outside contributions. --- Diffs of the changes: (+5 -5) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.93 llvm-www/www-index.html:1.94 --- llvm-www/www-index.html:1.93 Wed Dec 17 17:02:40 2003 +++ llvm-www/www-index.html Mon Dec 22 12:52:44 2003 @@ -61,15 +61,15 @@ even if you only have a semester in a University course.

-

LLVM was originally a product of the LLVM is a product of the Lifelong Code Optimization Project, led by Vikram Adve in the Department of Computer Science at the - University of Illinois, - Urbana-Champaign. Since our initial public release, however, our - scope has expanded to include contributions from several other people! + University of Illinois, + Urbana-Champaign. Since our public release, LLVM grown to include + contributions from several other people! We welcome external contributions, so please send e-mail to llvmdev at cs.uiuc.edu if you are interested in contributing code to the LLVM infrastructure.

Want to learn more?
From criswell at cs.uiuc.edu Mon Dec 22 13:26:28 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Dec 22 13:26:28 2003 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/ArchiveReader.cpp Message-ID: <200312221623.KAA02113@choi.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: ArchiveReader.cpp updated: 1.12 -> 1.13 --- Log message: Reverted back to revision 1.11. The previous fix doesn't really fix anything; it just causes the bug to go dormant. --- Diffs of the changes: (+3 -12) Index: llvm/lib/Bytecode/Reader/ArchiveReader.cpp diff -u llvm/lib/Bytecode/Reader/ArchiveReader.cpp:1.12 llvm/lib/Bytecode/Reader/ArchiveReader.cpp:1.13 --- llvm/lib/Bytecode/Reader/ArchiveReader.cpp:1.12 Sat Dec 20 16:37:29 2003 +++ llvm/lib/Bytecode/Reader/ArchiveReader.cpp Mon Dec 22 10:22:49 2003 @@ -122,17 +122,8 @@ while (endp[-1] == ' ') --endp; } - - // - // We now have the beginning and the end of the object name. - // Convert this into a dynamically allocated std::string to pass - // to the routines that create the Module object. We do this - // (I think) because the created Module object will outlive this function, - // but statically declared std::string's won't. - // std::string MemberName (startp, endp); - std::string * FullMemberName; - FullMemberName = new std::string (ArchiveName + "(" + MemberName + ")"); + std::string FullMemberName = ArchiveName + "(" + MemberName + ")"; switch (getObjectType(Hdr, MemberData, MemberSize)) { case SVR4LongFilename: @@ -142,7 +133,7 @@ break; case UserObject: { Module *M = ParseBytecodeBuffer(MemberData, MemberSize, - *(FullMemberName), ErrorStr); + FullMemberName, ErrorStr); if (!M) return true; Objects.push_back(M); break; @@ -153,7 +144,7 @@ break; default: std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: " - << *(FullMemberName) << "\n"; + << FullMemberName << "\n"; break; // Just ignore unknown files. } From alkis at cs.uiuc.edu Mon Dec 22 13:26:43 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Dec 22 13:26:43 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervals.cpp Message-ID: <200312221354.HAA06680@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervals.cpp updated: 1.14 -> 1.15 --- Log message: Fix crash when compiling twolf. --- Diffs of the changes: (+2 -1) Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.14 llvm/lib/CodeGen/LiveIntervals.cpp:1.15 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.14 Sun Dec 21 14:19:10 2003 +++ llvm/lib/CodeGen/LiveIntervals.cpp Mon Dec 22 07:54:29 2003 @@ -146,7 +146,8 @@ unsigned liveBlockIndex = it->first; MachineBasicBlock* liveBlock = it->second; if (liveBlockIndex < vi.AliveBlocks.size() && - vi.AliveBlocks[liveBlockIndex]) { + vi.AliveBlocks[liveBlockIndex] && + !liveBlock->empty()) { unsigned start = getInstructionIndex(liveBlock->front()); unsigned end = getInstructionIndex(liveBlock->back()) + 1; interval->addRange(start, end); From brukman at cs.uiuc.edu Mon Dec 22 17:15:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Dec 22 17:15:02 2003 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200312222314.RAA07214@zion.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.94 -> 1.95 --- Log message: * `has grown' instead of `grown' * Wrap code (as much as possible) at 80 columns --- Diffs of the changes: (+5 -2) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.94 llvm-www/www-index.html:1.95 --- llvm-www/www-index.html:1.94 Mon Dec 22 12:52:44 2003 +++ llvm-www/www-index.html Mon Dec 22 17:14:04 2003 @@ -67,9 +67,12 @@ href="http://www-faculty.cs.uiuc.edu/~vadve/">Vikram Adve in the Department of Computer Science at the University of Illinois, - Urbana-Champaign. Since our public release, LLVM grown to include + Urbana-Champaign. Since our public release, LLVM has grown to include contributions from several other people! We welcome external contributions, so please send e-mail to llvmdev at cs.uiuc.edu if you are interested in contributing code to the LLVM infrastructure. + href="/cvsweb/cvsweb.cgi/llvm/CREDITS.TXT?rev=HEAD&content-type=text/x-cvsweb-markup">several + other people! We welcome external contributions, so please send e-mail + to llvmdev at cs.uiuc.edu if you are + interested in contributing code to the LLVM infrastructure.

Want to learn more?
From lattner at cs.uiuc.edu Mon Dec 22 17:50:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 22 17:50:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/ConstantMerge.cpp Message-ID: <200312222349.RAA07970@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: ConstantMerge.cpp updated: 1.24 -> 1.25 --- Log message: Fix memory corruption bug PR193 --- Diffs of the changes: (+26 -20) Index: llvm/lib/Transforms/IPO/ConstantMerge.cpp diff -u llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.24 llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.25 --- llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.24 Fri Nov 21 15:54:21 2003 +++ llvm/lib/Transforms/IPO/ConstantMerge.cpp Mon Dec 22 17:49:36 2003 @@ -40,8 +40,15 @@ bool ConstantMerge::run(Module &M) { std::map CMap; - bool MadeChanges = false; - + + // Replacements - This vector contains a list of replacements to perform. + std::vector > Replacements; + + // First pass: identify all globals that can be merged together, filling in + // the Replacements vector. We cannot do the replacement in this pass because + // doing so may cause initializers of other globals to be rewritten, + // invalidating the Constant* pointers in CMap. + // for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV) // Only process constants with initializers if (GV->isConstant() && GV->hasInitializer()) { @@ -54,28 +61,27 @@ CMap.insert(I, std::make_pair(Init, GV)); } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate! // Make all uses of the duplicate constant use the canonical version... - GV->replaceAllUsesWith(I->second); - - // Delete the global value from the module... and back up iterator to - // not skip the next global... - GV = --M.getGlobalList().erase(GV); - - ++NumMerged; - MadeChanges = true; + Replacements.push_back(std::make_pair(GV, I->second)); } else if (I->second->hasInternalLinkage()) { // Make all uses of the duplicate constant use the canonical version... - I->second->replaceAllUsesWith(GV); - - // Delete the global value from the module... and back up iterator to - // not skip the next global... - M.getGlobalList().erase(I->second); + Replacements.push_back(std::make_pair(I->second, GV)); I->second = GV; - - ++NumMerged; - MadeChanges = true; } } - return MadeChanges; -} + if (Replacements.empty()) return false; + CMap.clear(); + // Now that we have figured out which replacements must be made, do them all + // now. This avoid invalidating the pointers in CMap, which are unneeded now. + for (unsigned i = 0, e = Replacements.size(); i != e; ++i) { + // Eliminate any uses of the dead global... + Replacements[i].first->replaceAllUsesWith(Replacements[i].second); + + // Delete the global value from the module... + M.getGlobalList().erase(Replacements[i].first); + } + + NumMerged += Replacements.size(); + return true; +} From lattner at cs.uiuc.edu Mon Dec 22 17:57:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 22 17:57:01 2003 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200312222356.RAA22711@choi.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.93 -> 1.94 --- Log message: bug fixed --- Diffs of the changes: (+3 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.93 llvm/docs/ReleaseNotes.html:1.94 --- llvm/docs/ReleaseNotes.html:1.93 Sun Dec 21 22:06:24 2003 +++ llvm/docs/ReleaseNotes.html Mon Dec 22 17:56:37 2003 @@ -151,6 +151,8 @@ infrequent crash
  • [indvars] Induction variable canonicalization always makes 32-bit indvars
  • +
  • [constantmerge] Merging globals can +cause use of invalid pointers!
  • @@ -596,7 +598,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2003/12/22 04:06:24 $ + Last modified: $Date: 2003/12/22 23:56:37 $ From lattner at cs.uiuc.edu Mon Dec 22 17:58:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 22 17:58:01 2003 Subject: [llvm-commits] CVS: llvm-www/releases/1.1/docs/ReleaseNotes.html Message-ID: <200312222357.RAA22968@choi.cs.uiuc.edu> Changes in directory llvm-www/releases/1.1/docs: ReleaseNotes.html updated: 1.6 -> 1.7 --- Log message: Bug found --- Diffs of the changes: (+3 -1) Index: llvm-www/releases/1.1/docs/ReleaseNotes.html diff -u llvm-www/releases/1.1/docs/ReleaseNotes.html:1.6 llvm-www/releases/1.1/docs/ReleaseNotes.html:1.7 --- llvm-www/releases/1.1/docs/ReleaseNotes.html:1.6 Sun Dec 21 22:06:38 2003 +++ llvm-www/releases/1.1/docs/ReleaseNotes.html Mon Dec 22 17:57:01 2003 @@ -383,6 +383,8 @@ infrequent crash
  • [indvars] Induction variable canonicalization always makes 32-bit indvars
  • +
  • [constantmerge] Merging globals can +cause use of invalid pointers!
  • @@ -741,7 +743,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2003/12/22 04:06:38 $ + Last modified: $Date: 2003/12/22 23:57:01 $ From lattner at cs.uiuc.edu Tue Dec 23 00:45:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 00:45:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/Expressions.cpp Message-ID: <200312230644.AAA11981@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: Expressions.cpp updated: 1.38 -> 1.39 --- Log message: Finegrainify namespacification --- Diffs of the changes: (+42 -42) Index: llvm/lib/Analysis/Expressions.cpp diff -u llvm/lib/Analysis/Expressions.cpp:1.38 llvm/lib/Analysis/Expressions.cpp:1.39 --- llvm/lib/Analysis/Expressions.cpp:1.38 Tue Nov 11 16:41:31 2003 +++ llvm/lib/Analysis/Expressions.cpp Tue Dec 23 00:44:41 2003 @@ -17,8 +17,7 @@ #include "llvm/Analysis/Expressions.h" #include "llvm/ConstantHandling.h" #include "llvm/Function.h" - -namespace llvm { +using namespace llvm; ExprType::ExprType(Value *Val) { if (Val) @@ -53,27 +52,28 @@ } - -class DefVal { - const ConstantInt * const Val; - const Type * const Ty; -protected: - inline DefVal(const ConstantInt *val, const Type *ty) : Val(val), Ty(ty) {} -public: - inline const Type *getType() const { return Ty; } - inline const ConstantInt *getVal() const { return Val; } - inline operator const ConstantInt * () const { return Val; } - inline const ConstantInt *operator->() const { return Val; } -}; - -struct DefZero : public DefVal { - inline DefZero(const ConstantInt *val, const Type *ty) : DefVal(val, ty) {} - inline DefZero(const ConstantInt *val) : DefVal(val, val->getType()) {} -}; - -struct DefOne : public DefVal { - inline DefOne(const ConstantInt *val, const Type *ty) : DefVal(val, ty) {} -}; +namespace { + class DefVal { + const ConstantInt * const Val; + const Type * const Ty; + protected: + inline DefVal(const ConstantInt *val, const Type *ty) : Val(val), Ty(ty) {} + public: + inline const Type *getType() const { return Ty; } + inline const ConstantInt *getVal() const { return Val; } + inline operator const ConstantInt * () const { return Val; } + inline const ConstantInt *operator->() const { return Val; } + }; + + struct DefZero : public DefVal { + inline DefZero(const ConstantInt *val, const Type *ty) : DefVal(val, ty) {} + inline DefZero(const ConstantInt *val) : DefVal(val, val->getType()) {} + }; + + struct DefOne : public DefVal { + inline DefOne(const ConstantInt *val, const Type *ty) : DefVal(val, ty) {} + }; +} // getUnsignedConstant - Return a constant value of the specified type. If the @@ -127,13 +127,13 @@ return ResultI; } -inline const ConstantInt *operator+(const DefZero &L, const DefZero &R) { +static inline const ConstantInt *operator+(const DefZero &L, const DefZero &R) { if (L == 0) return R; if (R == 0) return L; return Add(L, R, false); } -inline const ConstantInt *operator+(const DefOne &L, const DefOne &R) { +static inline const ConstantInt *operator+(const DefOne &L, const DefOne &R) { if (L == 0) { if (R == 0) return getUnsignedConstant(2, L.getType()); @@ -158,8 +158,8 @@ // 3. If DefOne is true, a null return value indicates a value of 1, if DefOne // is false, a null return value indicates a value of 0. // -inline const ConstantInt *Mul(const ConstantInt *Arg1, - const ConstantInt *Arg2, bool DefOne) { +static inline const ConstantInt *Mul(const ConstantInt *Arg1, + const ConstantInt *Arg2, bool DefOne) { assert(Arg1 && Arg2 && "No null arguments should exist now!"); assert(Arg1->getType() == Arg2->getType() && "Types must be compatible!"); @@ -177,18 +177,20 @@ return ResultI; } -inline const ConstantInt *operator*(const DefZero &L, const DefZero &R) { - if (L == 0 || R == 0) return 0; - return Mul(L, R, false); -} -inline const ConstantInt *operator*(const DefOne &L, const DefZero &R) { - if (R == 0) return getUnsignedConstant(0, L.getType()); - if (L == 0) return R->equalsInt(1) ? 0 : R.getVal(); - return Mul(L, R, true); -} -inline const ConstantInt *operator*(const DefZero &L, const DefOne &R) { - if (L == 0 || R == 0) return L.getVal(); - return Mul(R, L, false); +namespace { + inline const ConstantInt *operator*(const DefZero &L, const DefZero &R) { + if (L == 0 || R == 0) return 0; + return Mul(L, R, false); + } + inline const ConstantInt *operator*(const DefOne &L, const DefZero &R) { + if (R == 0) return getUnsignedConstant(0, L.getType()); + if (L == 0) return R->equalsInt(1) ? 0 : R.getVal(); + return Mul(L, R, true); + } + inline const ConstantInt *operator*(const DefZero &L, const DefOne &R) { + if (L == 0 || R == 0) return L.getVal(); + return Mul(R, L, false); + } } // handleAddition - Add two expressions together, creating a new expression that @@ -237,7 +239,7 @@ // Note that this analysis cannot get into infinite loops because it treats PHI // nodes as being an unknown linear expression. // -ExprType ClassifyExpression(Value *Expr) { +ExprType llvm::ClassifyExpression(Value *Expr) { assert(Expr != 0 && "Can't classify a null expression!"); if (Expr->getType() == Type::FloatTy || Expr->getType() == Type::DoubleTy) return Expr; // FIXME: Can't handle FP expressions @@ -354,5 +356,3 @@ // Otherwise, I don't know anything about this value! return I; } - -} // End llvm namespace From lattner at cs.uiuc.edu Tue Dec 23 01:44:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 01:44:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp LevelRaise.cpp Message-ID: <200312230743.BAA13884@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: ExprTypeConvert.cpp updated: 1.84 -> 1.85 LevelRaise.cpp updated: 1.89 -> 1.90 --- Log message: Remove extraneous #include finegrainify namespacification --- Diffs of the changes: (+11 -16) Index: llvm/lib/Transforms/ExprTypeConvert.cpp diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.84 llvm/lib/Transforms/ExprTypeConvert.cpp:1.85 --- llvm/lib/Transforms/ExprTypeConvert.cpp:1.84 Fri Nov 28 23:31:25 2003 +++ llvm/lib/Transforms/ExprTypeConvert.cpp Tue Dec 23 01:43:38 2003 @@ -22,8 +22,7 @@ #include "Support/STLExtras.h" #include "Support/Debug.h" #include - -namespace llvm { +using namespace llvm; static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty, ValueTypeCache &ConvertedTypes, @@ -142,7 +141,7 @@ // ExpressionConvertibleToType - Return true if it is possible -bool ExpressionConvertibleToType(Value *V, const Type *Ty, +bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty, ValueTypeCache &CTMap, const TargetData &TD) { // Expression type must be holdable in a register. if (!Ty->isFirstClassType()) @@ -330,8 +329,8 @@ } -Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC, - const TargetData &TD) { +Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty, + ValueMapCache &VMC, const TargetData &TD) { if (V->getType() == Ty) return V; // Already where we need to be? ValueMapCache::ExprMapTy::iterator VMCI = VMC.ExprMap.find(V); @@ -564,9 +563,9 @@ // ValueConvertibleToType - Return true if it is possible -bool ValueConvertibleToType(Value *V, const Type *Ty, - ValueTypeCache &ConvertedTypes, - const TargetData &TD) { +bool llvm::ValueConvertibleToType(Value *V, const Type *Ty, + ValueTypeCache &ConvertedTypes, + const TargetData &TD) { ValueTypeCache::iterator I = ConvertedTypes.find(V); if (I != ConvertedTypes.end()) return I->second == Ty; ConvertedTypes[V] = Ty; @@ -894,8 +893,8 @@ } -void ConvertValueToNewType(Value *V, Value *NewVal, ValueMapCache &VMC, - const TargetData &TD) { +void llvm::ConvertValueToNewType(Value *V, Value *NewVal, ValueMapCache &VMC, + const TargetData &TD) { ValueHandle VH(VMC, V); unsigned NumUses = V->use_size(); @@ -1302,4 +1301,3 @@ } } -} // End llvm namespace Index: llvm/lib/Transforms/LevelRaise.cpp diff -u llvm/lib/Transforms/LevelRaise.cpp:1.89 llvm/lib/Transforms/LevelRaise.cpp:1.90 --- llvm/lib/Transforms/LevelRaise.cpp:1.89 Thu Dec 11 15:47:37 2003 +++ llvm/lib/Transforms/LevelRaise.cpp Tue Dec 23 01:43:38 2003 @@ -20,15 +20,13 @@ #include "llvm/iMemory.h" #include "llvm/Pass.h" #include "llvm/ConstantHandling.h" -#include "llvm/Analysis/Expressions.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "Support/CommandLine.h" #include "Support/Debug.h" #include "Support/Statistic.h" #include "Support/STLExtras.h" #include - -namespace llvm { +using namespace llvm; // StartInst - This enables the -raise-start-inst=foo option to cause the level // raising pass to start at instruction "foo", which is immensely useful for @@ -87,7 +85,7 @@ } -Pass *createRaisePointerReferencesPass() { +Pass *llvm::createRaisePointerReferencesPass() { return new RPR(); } @@ -614,4 +612,3 @@ return Changed; } -} // End llvm namespace From lattner at cs.uiuc.edu Tue Dec 23 01:48:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 01:48:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200312230747.BAA13904@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.50 -> 1.51 --- Log message: More minor non-functional changes. This now computes the exit condition, though it doesn't do anything with it. --- Diffs of the changes: (+52 -15) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.50 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.51 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.50 Mon Dec 22 03:53:29 2003 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Tue Dec 23 01:47:09 2003 @@ -14,6 +14,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "indvar" #include "llvm/Transforms/Scalar.h" #include "llvm/Constants.h" #include "llvm/Type.h" @@ -34,15 +35,16 @@ class IndVarSimplify : public FunctionPass { LoopInfo *Loops; TargetData *TD; + bool Changed; public: virtual bool runOnFunction(Function &) { Loops = &getAnalysis(); TD = &getAnalysis(); - + Changed = false; + // Induction Variables live in the header nodes of loops - bool Changed = false; for (unsigned i = 0, e = Loops->getTopLevelLoops().size(); i != e; ++i) - Changed |= runOnLoop(Loops->getTopLevelLoops()[i]); + runOnLoop(Loops->getTopLevelLoops()[i]); return Changed; } @@ -55,7 +57,7 @@ Value *ComputeAuxIndVarValue(InductionVariable &IV, Value *CIV); void ReplaceIndVar(InductionVariable &IV, Value *Counter); - bool runOnLoop(Loop *L); + void runOnLoop(Loop *L); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); // Need pointer size @@ -73,11 +75,10 @@ } -bool IndVarSimplify::runOnLoop(Loop *Loop) { +void IndVarSimplify::runOnLoop(Loop *Loop) { // Transform all subloops before this loop... - bool Changed = false; for (unsigned i = 0, e = Loop->getSubLoops().size(); i != e; ++i) - Changed |= runOnLoop(Loop->getSubLoops()[i]); + runOnLoop(Loop->getSubLoops()[i]); // Get the header node for this loop. All of the phi nodes that could be // induction variables must live in this basic block. @@ -95,7 +96,7 @@ // AfterPHIIt now points to first non-phi instruction... // If there are no phi nodes in this basic block, there can't be indvars... - if (IndVars.empty()) return Changed; + if (IndVars.empty()) return; // Loop over the induction variables, looking for a canonical induction // variable, and checking to make sure they are not all unknown induction @@ -125,7 +126,42 @@ } // No induction variables, bail early... don't add a canonical indvar - if (MaxSize == 0) return Changed; + if (MaxSize == 0) return; + + + // Figure out what the exit condition of the loop is. We can currently only + // handle loops with a single exit. If we cannot figure out what the + // termination condition is, we leave this variable set to null. + // + SetCondInst *TermCond = 0; + if (Loop->getExitBlocks().size() == 1) { + // Get ExitingBlock - the basic block in the loop which contains the branch + // out of the loop. + BasicBlock *Exit = Loop->getExitBlocks()[0]; + pred_iterator PI = pred_begin(Exit); + assert(PI != pred_end(Exit) && "Should have one predecessor in loop!"); + BasicBlock *ExitingBlock = *PI; + assert(++PI == pred_end(Exit) && "Exit block should have one pred!"); + assert(Loop->isLoopExit(ExitingBlock) && "Exiting block is not loop exit!"); + + // Since the block is in the loop, yet branches out of it, we know that the + // block must end with multiple destination terminator. Which means it is + // either a conditional branch, a switch instruction, or an invoke. + if (BranchInst *BI = dyn_cast(ExitingBlock->getTerminator())) { + assert(BI->isConditional() && "Unconditional branch has multiple succs?"); + TermCond = dyn_cast(BI->getCondition()); + } else { + // NOTE: if people actually exit loops with switch instructions, we could + // handle them, but I don't think this is important enough to spend time + // thinking about. + assert(isa(ExitingBlock->getTerminator()) || + isa(ExitingBlock->getTerminator()) && + "Unknown multi-successor terminator!"); + } + } + + if (TermCond) + DEBUG(std::cerr << "INDVAR: Found termination condition: " << *TermCond); // Okay, we want to convert other induction variables to use a canonical // indvar. If we don't have one, add one now... @@ -172,15 +208,18 @@ Canonical = &IndVars.back(); ++NumInserted; Changed = true; + DEBUG(std::cerr << "INDVAR: Inserted canonical iv: " << *PN); } else { // If we have a canonical induction variable, make sure that it is the first // one in the basic block. if (&Header->front() != Canonical->Phi) Header->getInstList().splice(Header->begin(), Header->getInstList(), Canonical->Phi); + DEBUG(std::cerr << "IndVar: Existing canonical iv used: " + << *Canonical->Phi); } - DEBUG(std::cerr << "Induction variables:\n"); + DEBUG(std::cerr << "INDVAR: Replacing Induction variables:\n"); // Get the current loop iteration count, which is always the value of the // canonical phi node... @@ -202,8 +241,6 @@ ++NumRemoved; } } - - return Changed; } /// ComputeAuxIndVarValue - Given an auxillary induction variable, compute and @@ -269,7 +306,6 @@ return Val; } - // ReplaceIndVar - Replace all uses of the specified induction variable with // expressions computed from the specified loop iteration counter variable. // Return true if instructions were deleted. @@ -286,8 +322,9 @@ PHIOps.push_back(Phi->getIncomingValue(0)); PHIOps.push_back(Phi->getIncomingValue(1)); - // Delete all of the operands of the PHI node... FIXME, this should be more - // intelligent. + // Delete all of the operands of the PHI node... so that the to-be-deleted PHI + // node does not cause any expressions to be computed that would not otherwise + // be. Phi->dropAllReferences(); // Now that we are rid of unneeded uses of the PHI node, replace any remaining From lattner at cs.uiuc.edu Tue Dec 23 02:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 02:04:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Expressions.h Message-ID: <200312230803.CAA17048@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Expressions.h updated: 1.9 -> 1.10 --- Log message: Rename ClassifyExpression -> ClassifyExpr --- Diffs of the changes: (+6 -6) Index: llvm/include/llvm/Analysis/Expressions.h diff -u llvm/include/llvm/Analysis/Expressions.h:1.9 llvm/include/llvm/Analysis/Expressions.h:1.10 --- llvm/include/llvm/Analysis/Expressions.h:1.9 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Analysis/Expressions.h Tue Dec 23 02:03:40 2003 @@ -9,8 +9,8 @@ // // This file defines a package of expression analysis utilties: // -// ClassifyExpression: Analyze an expression to determine the complexity of the -// expression, and which other variables it depends on. +// ClassifyExpr: Analyze an expression to determine the complexity of the +// expression, and which other variables it depends on. // //===----------------------------------------------------------------------===// @@ -25,10 +25,10 @@ struct ExprType; -// ClassifyExpression: Analyze an expression to determine the complexity of the -// expression, and which other values it depends on. -// -ExprType ClassifyExpression(Value *Expr); +/// ClassifyExpr: Analyze an expression to determine the complexity of the +/// expression, and which other values it depends on. +/// +ExprType ClassifyExpr(Value *Expr); // ExprType - Represent an expression of the form CONST*VAR+CONST // or simpler. The expression form that yields the least information about the From lattner at cs.uiuc.edu Tue Dec 23 02:05:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 02:05:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp TransformInternals.cpp Message-ID: <200312230804.CAA17075@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: ExprTypeConvert.cpp updated: 1.85 -> 1.86 TransformInternals.cpp updated: 1.41 -> 1.42 --- Log message: rename ClassifyExpression -> ClassifyExpr --- Diffs of the changes: (+3 -3) Index: llvm/lib/Transforms/ExprTypeConvert.cpp diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.85 llvm/lib/Transforms/ExprTypeConvert.cpp:1.86 --- llvm/lib/Transforms/ExprTypeConvert.cpp:1.85 Tue Dec 23 01:43:38 2003 +++ llvm/lib/Transforms/ExprTypeConvert.cpp Tue Dec 23 02:04:08 2003 @@ -52,7 +52,7 @@ if (!Ty->isSized()) return false; // Can only alloc something with a size // Analyze the number of bytes allocated... - ExprType Expr = ClassifyExpression(MI->getArraySize()); + ExprType Expr = ClassifyExpr(MI->getArraySize()); // Get information about the base datatype being allocated, before & after int ReqTypeSize = TD.getTypeSize(Ty); @@ -89,7 +89,7 @@ BasicBlock::iterator It = BB->end(); // Analyze the number of bytes allocated... - ExprType Expr = ClassifyExpression(MI->getArraySize()); + ExprType Expr = ClassifyExpr(MI->getArraySize()); const PointerType *AllocTy = cast(Ty); const Type *ElType = AllocTy->getElementType(); Index: llvm/lib/Transforms/TransformInternals.cpp diff -u llvm/lib/Transforms/TransformInternals.cpp:1.41 llvm/lib/Transforms/TransformInternals.cpp:1.42 --- llvm/lib/Transforms/TransformInternals.cpp:1.41 Tue Nov 11 16:41:33 2003 +++ llvm/lib/Transforms/TransformInternals.cpp Tue Dec 23 02:04:08 2003 @@ -104,7 +104,7 @@ // See if the cast is of an integer expression that is either a constant, // or a value scaled by some amount with a possible offset. // - ExprType Expr = ClassifyExpression(OffsetVal); + ExprType Expr = ClassifyExpr(OffsetVal); // Get the offset and scale values if they exists... // A scale of zero with Expr.Var != 0 means a scale of 1. From lattner at cs.uiuc.edu Tue Dec 23 02:05:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 02:05:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/Expressions.cpp InductionVariable.cpp Message-ID: <200312230804.CAA17065@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: Expressions.cpp updated: 1.39 -> 1.40 InductionVariable.cpp updated: 1.33 -> 1.34 --- Log message: rename ClassifyExpression -> ClassifyExpr --- Diffs of the changes: (+16 -16) Index: llvm/lib/Analysis/Expressions.cpp diff -u llvm/lib/Analysis/Expressions.cpp:1.39 llvm/lib/Analysis/Expressions.cpp:1.40 --- llvm/lib/Analysis/Expressions.cpp:1.39 Tue Dec 23 00:44:41 2003 +++ llvm/lib/Analysis/Expressions.cpp Tue Dec 23 02:04:02 2003 @@ -233,13 +233,13 @@ } -// ClassifyExpression: Analyze an expression to determine the complexity of the -// expression, and which other values it depends on. +// ClassifyExpr: Analyze an expression to determine the complexity of the +// expression, and which other values it depends on. // // Note that this analysis cannot get into infinite loops because it treats PHI // nodes as being an unknown linear expression. // -ExprType llvm::ClassifyExpression(Value *Expr) { +ExprType llvm::ClassifyExpr(Value *Expr) { assert(Expr != 0 && "Can't classify a null expression!"); if (Expr->getType() == Type::FloatTy || Expr->getType() == Type::DoubleTy) return Expr; // FIXME: Can't handle FP expressions @@ -266,14 +266,14 @@ switch (I->getOpcode()) { // Handle each instruction type separately case Instruction::Add: { - ExprType Left (ClassifyExpression(I->getOperand(0))); - ExprType Right(ClassifyExpression(I->getOperand(1))); + ExprType Left (ClassifyExpr(I->getOperand(0))); + ExprType Right(ClassifyExpr(I->getOperand(1))); return handleAddition(Left, Right, I); } // end case Instruction::Add case Instruction::Sub: { - ExprType Left (ClassifyExpression(I->getOperand(0))); - ExprType Right(ClassifyExpression(I->getOperand(1))); + ExprType Left (ClassifyExpr(I->getOperand(0))); + ExprType Right(ClassifyExpr(I->getOperand(1))); ExprType RightNeg = negate(Right, I); if (RightNeg.Var == I && !RightNeg.Offset && !RightNeg.Scale) return I; // Could not negate value... @@ -281,9 +281,9 @@ } // end case Instruction::Sub case Instruction::Shl: { - ExprType Right(ClassifyExpression(I->getOperand(1))); + ExprType Right(ClassifyExpr(I->getOperand(1))); if (Right.ExprTy != ExprType::Constant) break; - ExprType Left(ClassifyExpression(I->getOperand(0))); + ExprType Left(ClassifyExpr(I->getOperand(0))); if (Right.Offset == 0) return Left; // shl x, 0 = x assert(Right.Offset->getType() == Type::UByteTy && "Shift amount must always be a unsigned byte!"); @@ -308,8 +308,8 @@ } // end case Instruction::Shl case Instruction::Mul: { - ExprType Left (ClassifyExpression(I->getOperand(0))); - ExprType Right(ClassifyExpression(I->getOperand(1))); + ExprType Left (ClassifyExpr(I->getOperand(0))); + ExprType Right(ClassifyExpr(I->getOperand(1))); if (Left.ExprTy > Right.ExprTy) std::swap(Left, Right); // Make left be simpler than right @@ -323,7 +323,7 @@ } // end case Instruction::Mul case Instruction::Cast: { - ExprType Src(ClassifyExpression(I->getOperand(0))); + ExprType Src(ClassifyExpr(I->getOperand(0))); const Type *DestTy = I->getType(); if (isa(DestTy)) DestTy = Type::ULongTy; // Pointer types are represented as ulong Index: llvm/lib/Analysis/InductionVariable.cpp diff -u llvm/lib/Analysis/InductionVariable.cpp:1.33 llvm/lib/Analysis/InductionVariable.cpp:1.34 --- llvm/lib/Analysis/InductionVariable.cpp:1.33 Sun Dec 21 23:26:29 2003 +++ llvm/lib/Analysis/InductionVariable.cpp Tue Dec 23 02:04:02 2003 @@ -89,8 +89,8 @@ Value *V2 = Phi->getIncomingValue(1); if (L == 0) { // No loop information? Base everything on expression analysis - ExprType E1 = ClassifyExpression(V1); - ExprType E2 = ClassifyExpression(V2); + ExprType E1 = ClassifyExpr(V1); + ExprType E2 = ClassifyExpr(V2); if (E1.ExprTy > E2.ExprTy) // Make E1 be the simpler expression std::swap(E1, E2); @@ -152,7 +152,7 @@ } if (Step == 0) { // Unrecognized step value... - ExprType StepE = ClassifyExpression(V2); + ExprType StepE = ClassifyExpr(V2); if (StepE.ExprTy != ExprType::Linear || StepE.Var != Phi) return; @@ -160,7 +160,7 @@ if (isa(ETy)) ETy = Type::ULongTy; Step = (Value*)(StepE.Offset ? StepE.Offset : ConstantInt::get(ETy, 0)); } else { // We were able to get a step value, simplify with expr analysis - ExprType StepE = ClassifyExpression(Step); + ExprType StepE = ClassifyExpr(Step); if (StepE.ExprTy == ExprType::Linear && StepE.Offset == 0) { // No offset from variable? Grab the variable Step = StepE.Var; From lattner at cs.uiuc.edu Tue Dec 23 03:42:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 03:42:01 2003 Subject: [llvm-commits] CVS: llvm/tools/analyze/AnalysisWrappers.cpp Message-ID: <200312230941.DAA06862@zion.cs.uiuc.edu> Changes in directory llvm/tools/analyze: AnalysisWrappers.cpp updated: 1.7 -> 1.8 --- Log message: Rename method --- Diffs of the changes: (+1 -1) Index: llvm/tools/analyze/AnalysisWrappers.cpp diff -u llvm/tools/analyze/AnalysisWrappers.cpp:1.7 llvm/tools/analyze/AnalysisWrappers.cpp:1.8 --- llvm/tools/analyze/AnalysisWrappers.cpp:1.7 Tue Nov 11 16:41:34 2003 +++ llvm/tools/analyze/AnalysisWrappers.cpp Tue Dec 23 03:41:45 2003 @@ -80,7 +80,7 @@ OS << *I; if ((*I)->getType() == Type::VoidTy) continue; - ExprType R = ClassifyExpression(*I); + ExprType R = ClassifyExpr(*I); if (R.Var == *I) continue; // Doesn't tell us anything OS << "\t\tExpr ="; From criswell at cs.uiuc.edu Tue Dec 23 11:38:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Dec 23 11:38:02 2003 Subject: [llvm-commits] CVS: llvm/tools/gccld/Linker.cpp Message-ID: <200312231737.LAA01683@choi.cs.uiuc.edu> Changes in directory llvm/tools/gccld: Linker.cpp updated: 1.19 -> 1.20 --- Log message: Modified the linker so that it always links in an object from an archive that defines the symbol "main." This is a hack that ensures that programs that place their main function in a library and then link it in (i.e. Apache 2.x) get their main function linked in. There is probably a more correct way to do this, but this works for now. --- Diffs of the changes: (+21 -11) Index: llvm/tools/gccld/Linker.cpp diff -u llvm/tools/gccld/Linker.cpp:1.19 llvm/tools/gccld/Linker.cpp:1.20 --- llvm/tools/gccld/Linker.cpp:1.19 Fri Nov 28 01:44:09 2003 +++ llvm/tools/gccld/Linker.cpp Tue Dec 23 11:37:06 2003 @@ -200,17 +200,27 @@ const std::set &DefSymbols = DefinedSymbols[i]; bool ObjectRequired = false; - for (std::set::iterator I = UndefinedSymbols.begin(), - E = UndefinedSymbols.end(); I != E; ++I) - if (DefSymbols.count(*I)) { - if (Verbose) - std::cerr << " Found object '" - << Objects[i]->getModuleIdentifier () - << "' providing symbol '" << *I << "'...\n"; - ObjectRequired = true; - break; - } - + + // + // If the object defines main(), then it is automatically required. + // Otherwise, look to see if it defines a symbol that is currently + // undefined. + // + if ((DefSymbols.find ("main")) == DefSymbols.end()) { + for (std::set::iterator I = UndefinedSymbols.begin(), + E = UndefinedSymbols.end(); I != E; ++I) + if (DefSymbols.count(*I)) { + if (Verbose) + std::cerr << " Found object '" + << Objects[i]->getModuleIdentifier () + << "' providing symbol '" << *I << "'...\n"; + ObjectRequired = true; + break; + } + } else { + ObjectRequired = true; + } + // We DO need to link this object into the program... if (ObjectRequired) { if (LinkModules(M, Objects[i], &ErrorMessage)) From alkis at cs.uiuc.edu Tue Dec 23 12:01:01 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Tue Dec 23 12:01:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200312231800.MAA08935@kain.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.17 -> 1.18 --- Log message: Change the way free regusters are computed and perform better allocation in the presence of preallocated intervals. --- Diffs of the changes: (+77 -130) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.17 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.18 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.17 Sun Dec 21 14:41:26 2003 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Tue Dec 23 12:00:33 2003 @@ -55,6 +55,7 @@ RegMask reserved_; unsigned regUse_[MRegisterInfo::FirstVirtualRegister]; + unsigned regUseBackup_[MRegisterInfo::FirstVirtualRegister]; typedef LiveIntervals::MachineBasicBlockPtrs MachineBasicBlockPtrs; MachineBasicBlockPtrs mbbs_; @@ -105,14 +106,6 @@ /// register handling helpers /// - /// reservePhysReg - reserves a physical register and spills - /// any value assigned to it if any - void reservePhysReg(unsigned reg); - - /// clearReservedPhysReg - marks pysical register as free for - /// use - void clearReservedPhysReg(unsigned reg); - /// getFreePhysReg - return a free physical register for this /// virtual register interval if we have one, otherwise return /// 0 @@ -159,6 +152,14 @@ void markPhysRegFree(unsigned physReg); void markPhysRegNotFree(unsigned physReg); + void backupRegUse() { + memcpy(regUseBackup_, regUse_, sizeof(regUseBackup_)); + } + + void restoreRegUse() { + memcpy(regUse_, regUseBackup_, sizeof(regUseBackup_)); + } + void printVirt2PhysMap() const { std::cerr << "allocated registers:\n"; for (Virt2PhysMap::const_iterator @@ -212,6 +213,7 @@ v2pMap_.clear(); v2ssMap_.clear(); memset(regUse_, 0, sizeof(regUse_)); + memset(regUseBackup_, 0, sizeof(regUseBackup_)); DEBUG( unsigned i = 0; @@ -257,19 +259,37 @@ DEBUG(printIntervals("\tactive", active_.begin(), active_.end())); DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end())); - for (MRegisterInfo::regclass_iterator c = mri_->regclass_begin(); - c != mri_->regclass_end(); ++c) { - const TargetRegisterClass* rc = *c; - DEBUG(printFreeRegs("\tfree registers", rc)); - } - processActiveIntervals(i); processInactiveIntervals(i); + backupRegUse(); + + // for every interval in inactive we overlap mark the register + // as not free + for (IntervalPtrs::iterator j = inactive_.begin(); + j != inactive_.end(); ++j) { + unsigned reg = (*j)->reg; + if (reg >= MRegisterInfo::FirstVirtualRegister) + reg = v2pMap_[reg]; + + if (i->overlaps(**j)) { + markPhysRegNotFree(reg); + } + } + + // for every pre-allocated interval in unhandled we overlap + // mark the register as not free + for (Intervals::const_iterator j = i + 1; j != e; ++j) { + if (j->reg < MRegisterInfo::FirstVirtualRegister && + i->overlaps(*j)) + markPhysRegNotFree(j->reg); + } + DEBUG(std::cerr << "\tallocating current interval:\n"); // if this register is preallocated reserve it if (i->reg < MRegisterInfo::FirstVirtualRegister) { - reservePhysReg(i->reg); + restoreRegUse(); + markPhysRegNotFree(i->reg); active_.push_back(&*i); } // otherwise we are allocating a virtual register. try to find @@ -281,6 +301,7 @@ assignStackSlotAtInterval(i); } else { + restoreRegUse(); assignVirt2PhysReg(i->reg, physReg); active_.push_back(&*i); } @@ -290,24 +311,10 @@ for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) { unsigned reg = (*i)->reg; DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); - if (reg < MRegisterInfo::FirstVirtualRegister) { - markPhysRegFree(reg); - } - else { - markPhysRegFree(v2pMap_[reg]); - } - } - // expire any remaining inactive intervals - for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); - ++i) { - unsigned reg = (*i)->reg; - DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); - if (reg < MRegisterInfo::FirstVirtualRegister) { - markPhysRegFree(reg); - } - else { - markPhysRegFree(v2pMap_[reg]); + if (reg >= MRegisterInfo::FirstVirtualRegister) { + reg = v2pMap_[reg]; } + markPhysRegFree(reg); } DEBUG(std::cerr << "finished register allocation\n"); @@ -413,18 +420,20 @@ // instruction if ((*i)->expiredAt(cur->start() + 1)) { DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n"); - if (reg < MRegisterInfo::FirstVirtualRegister) { - markPhysRegFree(reg); - } - else { - markPhysRegFree(v2pMap_[reg]); + if (reg >= MRegisterInfo::FirstVirtualRegister) { + reg = v2pMap_[reg]; } + markPhysRegFree(reg); // remove from active i = active_.erase(i); } // move inactive intervals to inactive list else if (!(*i)->liveAt(cur->start())) { DEBUG(std::cerr << "\t\t\tinterval " << **i << " inactive\n"); + if (reg >= MRegisterInfo::FirstVirtualRegister) { + reg = v2pMap_[reg]; + } + markPhysRegFree(reg); // add to inactive inactive_.push_back(*i); // remove from active @@ -448,18 +457,16 @@ // instruction if ((*i)->expiredAt(cur->start() + 1)) { DEBUG(std::cerr << "\t\t\tinterval " << **i << " expired\n"); - if (reg < MRegisterInfo::FirstVirtualRegister) { - markPhysRegFree(reg); - } - else { - markPhysRegFree(v2pMap_[reg]); - } // remove from inactive i = inactive_.erase(i); } // move re-activated intervals in active list else if ((*i)->liveAt(cur->start())) { DEBUG(std::cerr << "\t\t\tinterval " << **i << " active\n"); + if (reg >= MRegisterInfo::FirstVirtualRegister) { + reg = v2pMap_[reg]; + } + markPhysRegNotFree(reg); // add to active active_.push_back(*i); // remove from inactive @@ -487,18 +494,16 @@ { DEBUG(std::cerr << "\t\tassigning stack slot at interval " << *cur << ":\n"); - assert((!active_.empty() || !inactive_.empty()) && - "active and inactive sets cannot be both empty when choosing " - "a register to spill"); // set all weights to zero float regWeight[MRegisterInfo::FirstVirtualRegister]; for (unsigned i = 0; i < MRegisterInfo::FirstVirtualRegister; ++i) regWeight[i] = 0.0F; + // for each interval in active that overlaps for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) { -// if (!cur->overlaps(**i)) -// continue; + if (!cur->overlaps(**i)) + continue; unsigned reg = (*i)->reg; if (reg >= MRegisterInfo::FirstVirtualRegister) { @@ -509,10 +514,11 @@ updateWeight(regWeight, *as, (*i)->weight); } + // for each interval in inactive that overlaps for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ++i) { -// if (!cur->overlaps(**i)) -// continue; + if (!cur->overlaps(**i)) + continue; unsigned reg = (*i)->reg; if (reg >= MRegisterInfo::FirstVirtualRegister) { @@ -523,6 +529,15 @@ updateWeight(regWeight, *as, (*i)->weight); } + // for each fixed interval in unhandled that overlaps + for (Intervals::const_iterator j = cur + 1; j != li_->end(); ++j) { + if (j->reg >= MRegisterInfo::FirstVirtualRegister) + continue; + updateWeight(regWeight, j->reg, j->weight); + for (const unsigned* as = mri_->getAliasSet(j->reg); *as; ++as) + updateWeight(regWeight, *as, j->weight); + } + float minWeight = std::numeric_limits::max(); unsigned minReg = 0; const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); @@ -536,6 +551,7 @@ } if (cur->weight < minWeight) { + restoreRegUse(); DEBUG(std::cerr << "\t\t\t\tspilling : " << mri_->getName(minReg) << ", weight: " << cur->weight << '\n'); assignVirt2StackSlot(cur->reg); @@ -546,11 +562,14 @@ for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as) toSpill.insert(*as); + std::vector spilled; for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ) { unsigned reg = (*i)->reg; if (reg >= MRegisterInfo::FirstVirtualRegister && - toSpill.find(v2pMap_[reg]) != toSpill.end()) { + toSpill.find(v2pMap_[reg]) != toSpill.end() && + cur->overlaps(**i)) { + spilled.push_back(v2pMap_[reg]); DEBUG(std::cerr << "\t\t\t\tspilling : " << mri_->getName(minReg) << ", weight: " << (*i)->weight << '\n'); @@ -565,7 +584,8 @@ i != inactive_.end(); ) { unsigned reg = (*i)->reg; if (reg >= MRegisterInfo::FirstVirtualRegister && - toSpill.find(v2pMap_[reg]) != toSpill.end()) { + toSpill.find(v2pMap_[reg]) != toSpill.end() && + cur->overlaps(**i)) { DEBUG(std::cerr << "\t\t\t\tspilling : " << mri_->getName(minReg) << ", weight: " << (*i)->weight << '\n'); @@ -579,67 +599,14 @@ unsigned physReg = getFreePhysReg(cur); assert(physReg && "no free physical register after spill?"); - assignVirt2PhysReg(cur->reg, physReg); - active_.push_back(&*cur); - } -} - -void RA::reservePhysReg(unsigned physReg) -{ - DEBUG(std::cerr << "\t\t\treserving physical register: " - << mri_->getName(physReg) << '\n'); - - Regs clobbered; - clobbered.push_back(physReg); - for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) { - clobbered.push_back(*as); - } - // remove interval from active - for (IntervalPtrs::iterator i = active_.begin(), e = active_.end(); - i != e; ) { - unsigned reg = (*i)->reg; - if (reg < MRegisterInfo::FirstVirtualRegister) { - ++i; - continue; - } + restoreRegUse(); + for (unsigned i = 0; i < spilled.size(); ++i) + markPhysRegFree(spilled[i]); - if (find(clobbered.begin(), clobbered.end(), v2pMap_[reg]) != - clobbered.end()) { - i = active_.erase(i); - assignVirt2StackSlot(reg); - } - else { - ++i; - } - } - // or from inactive - for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end(); - i != e; ) { - unsigned reg = (*i)->reg; - if (reg < MRegisterInfo::FirstVirtualRegister) { - ++i; - continue; - } - - if (find(clobbered.begin(), clobbered.end(), v2pMap_[reg]) != - clobbered.end()) { - i = inactive_.erase(i); - assignVirt2StackSlot(reg); - } - else { - ++i; - } + assignVirt2PhysReg(cur->reg, physReg); + active_.push_back(&*cur); } - - markPhysRegNotFree(physReg); -} - -void RA::clearReservedPhysReg(unsigned physReg) -{ - DEBUG(std::cerr << "\t\t\tclearing reserved physical register: " - << mri_->getName(physReg) << '\n'); - markPhysRegFree(physReg); } bool RA::physRegAvailable(unsigned physReg) @@ -654,37 +621,17 @@ { DEBUG(std::cerr << "\t\tgetting free physical register: "); - // save the regUse counts because we are going to modify them - // specifically for this interval - unsigned regUseBackup[MRegisterInfo::FirstVirtualRegister]; - memcpy(regUseBackup, regUse_, sizeof(regUseBackup)); - - // for every interval in inactive we don't overlap mark the - // register as free - for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); - ++i) { - unsigned reg = (*i)->reg; - if (reg >= MRegisterInfo::FirstVirtualRegister) - reg = v2pMap_[reg]; - - if (!cur->overlaps(**i)) { - markPhysRegFree(reg); - } - } - const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); i != rc->allocation_order_end(*mf_); ++i) { unsigned reg = *i; if (!reserved_[reg] && !regUse_[reg]) { DEBUG(std::cerr << mri_->getName(reg) << '\n'); - memcpy(regUse_, regUseBackup, sizeof(regUseBackup)); return reg; } } DEBUG(std::cerr << "no free register\n"); - memcpy(regUse_, regUseBackup, sizeof(regUseBackup)); return 0; } From lattner at cs.uiuc.edu Tue Dec 23 14:06:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 14:06:01 2003 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/ParserInternals.h llvmAsmParser.y Message-ID: <200312232005.OAA24836@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: ParserInternals.h updated: 1.33 -> 1.34 llvmAsmParser.y updated: 1.143 -> 1.144 --- Log message: Minor cleanups, plug a minor memory leak --- Diffs of the changes: (+2 -5) Index: llvm/lib/AsmParser/ParserInternals.h diff -u llvm/lib/AsmParser/ParserInternals.h:1.33 llvm/lib/AsmParser/ParserInternals.h:1.34 --- llvm/lib/AsmParser/ParserInternals.h:1.33 Tue Nov 11 16:41:32 2003 +++ llvm/lib/AsmParser/ParserInternals.h Tue Dec 23 14:05:15 2003 @@ -67,8 +67,7 @@ // discriminated union. // // Note that I can't implement this class in a straight forward manner with -// constructors and stuff because it goes in a union, and GCC doesn't like -// putting classes with ctor's in unions. :( +// constructors and stuff because it goes in a union. // struct ValID { enum { Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.143 llvm/lib/AsmParser/llvmAsmParser.y:1.144 --- llvm/lib/AsmParser/llvmAsmParser.y:1.143 Wed Nov 26 01:24:58 2003 +++ llvm/lib/AsmParser/llvmAsmParser.y Tue Dec 23 14:05:15 2003 @@ -1122,10 +1122,8 @@ if (I != CurModule.GlobalRefs.end()) { V = I->second; // Placeholder already exists, use it... + $2.destroy(); } else { - // TODO: Include line number info by creating a subclass of - // TODO: GlobalVariable here that includes the said information! - // Create a placeholder for the global variable reference... GlobalVariable *GV = new GlobalVariable(PT->getElementType(), false, From criswell at cs.uiuc.edu Tue Dec 23 14:28:00 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Dec 23 14:28:00 2003 Subject: [llvm-commits] CVS: llvm/tools/gccld/Linker.cpp Message-ID: <200312232027.OAA06945@choi.cs.uiuc.edu> Changes in directory llvm/tools/gccld: Linker.cpp updated: 1.20 -> 1.21 --- Log message: Modified the logic so that library objects with main() are only linked in if the program currently has main undefined. --- Diffs of the changes: (+7 -6) Index: llvm/tools/gccld/Linker.cpp diff -u llvm/tools/gccld/Linker.cpp:1.20 llvm/tools/gccld/Linker.cpp:1.21 --- llvm/tools/gccld/Linker.cpp:1.20 Tue Dec 23 11:37:06 2003 +++ llvm/tools/gccld/Linker.cpp Tue Dec 23 14:27:14 2003 @@ -202,11 +202,14 @@ bool ObjectRequired = false; // - // If the object defines main(), then it is automatically required. - // Otherwise, look to see if it defines a symbol that is currently - // undefined. + // If the object defines main() and the program currently has main() + // undefined, then automatically link in the module. Otherwise, look to + // see if it defines a symbol that is currently undefined. // - if ((DefSymbols.find ("main")) == DefSymbols.end()) { + if ((M->getMainFunction() == NULL) && + ((DefSymbols.find ("main")) != DefSymbols.end())) { + ObjectRequired = true; + } else { for (std::set::iterator I = UndefinedSymbols.begin(), E = UndefinedSymbols.end(); I != E; ++I) if (DefSymbols.count(*I)) { @@ -217,8 +220,6 @@ ObjectRequired = true; break; } - } else { - ObjectRequired = true; } // We DO need to link this object into the program... From lattner at cs.uiuc.edu Tue Dec 23 14:40:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 14:40:01 2003 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200312232039.OAA21476@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.144 -> 1.145 --- Log message: Do not delete the type holder until after the call instruction has been constructed! --- Diffs of the changes: (+1 -1) Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.144 llvm/lib/AsmParser/llvmAsmParser.y:1.145 --- llvm/lib/AsmParser/llvmAsmParser.y:1.144 Tue Dec 23 14:05:15 2003 +++ llvm/lib/AsmParser/llvmAsmParser.y Tue Dec 23 14:39:17 2003 @@ -1828,7 +1828,6 @@ Ty = FunctionType::get($2->get(), ParamTypes, isVarArg); PFTy = PointerType::get(Ty); } - delete $2; Value *V = getVal(PFTy, $3); // Get the function we're calling... @@ -1858,6 +1857,7 @@ $$ = new CallInst(V, *$5); } + delete $2; delete $5; } | MemoryInst { From lattner at cs.uiuc.edu Tue Dec 23 16:19:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 16:19:01 2003 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200312232218.QAA04752@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.145 -> 1.146 --- Log message: Right, fix the problem with invoke instructions, not just call instructions --- Diffs of the changes: (+1 -1) Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.145 llvm/lib/AsmParser/llvmAsmParser.y:1.146 --- llvm/lib/AsmParser/llvmAsmParser.y:1.145 Tue Dec 23 14:39:17 2003 +++ llvm/lib/AsmParser/llvmAsmParser.y Tue Dec 23 16:18:36 2003 @@ -1626,7 +1626,6 @@ Ty = FunctionType::get($2->get(), ParamTypes, isVarArg); PFTy = PointerType::get(Ty); } - delete $2; Value *V = getVal(PFTy, $3); // Get the function we're calling... @@ -1657,6 +1656,7 @@ $$ = new InvokeInst(V, Normal, Except, *$5); } + delete $2; delete $5; } | UNWIND { From criswell at cs.uiuc.edu Tue Dec 23 16:23:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Dec 23 16:23:01 2003 Subject: [llvm-commits] CVS: llvm/docs/FAQ.html Message-ID: <200312232222.QAA18873@choi.cs.uiuc.edu> Changes in directory llvm/docs: FAQ.html updated: 1.17 -> 1.18 --- Log message: Corrected typo. --- Diffs of the changes: (+2 -2) Index: llvm/docs/FAQ.html diff -u llvm/docs/FAQ.html:1.17 llvm/docs/FAQ.html:1.18 --- llvm/docs/FAQ.html:1.17 Sun Dec 21 22:06:12 2003 +++ llvm/docs/FAQ.html Tue Dec 23 16:22:10 2003 @@ -437,7 +437,7 @@

    If you are using the LLVM demo page, you may often wonder what happened to all of the code that you typed in. Remember that the demo script is running the -code through the LLVM optimizers, so if you code doesn't actually do anything +code through the LLVM optimizers, so if your code doesn't actually do anything useful, it might all be deleted.

    @@ -456,7 +456,7 @@ From lattner at cs.uiuc.edu Tue Dec 23 17:26:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 17:26:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/AbstractTypeUser.h Message-ID: <200312232325.RAA07626@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: AbstractTypeUser.h updated: 1.17 -> 1.18 --- Log message: Hrm is a really nasty ommission. The lack of this destructor was causing abstract types to never be deleted, manifesting itself as many OpaqueType objects being leaked. Whoops. --- Diffs of the changes: (+2 -0) Index: llvm/include/llvm/AbstractTypeUser.h diff -u llvm/include/llvm/AbstractTypeUser.h:1.17 llvm/include/llvm/AbstractTypeUser.h:1.18 --- llvm/include/llvm/AbstractTypeUser.h:1.17 Tue Nov 11 16:41:29 2003 +++ llvm/include/llvm/AbstractTypeUser.h Tue Dec 23 17:25:21 2003 @@ -143,6 +143,8 @@ addRef(); } + ~PATypeHolder() { dropRef(); } + operator const Type *() const { return get(); } const Type *get() const; From lattner at cs.uiuc.edu Tue Dec 23 17:51:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 23 17:51:01 2003 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200312232350.RAA07934@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.94 -> 1.95 --- Log message: boog fixed --- Diffs of the changes: (+2 -3) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.94 llvm/docs/ReleaseNotes.html:1.95 --- llvm/docs/ReleaseNotes.html:1.94 Mon Dec 22 17:56:37 2003 +++ llvm/docs/ReleaseNotes.html Tue Dec 23 17:50:31 2003 @@ -120,8 +120,7 @@
  • JIT should lazily initialize global variables
  • [X86] X86 Backend never releases memory for machine code structures
  • - -
  • +
  • [vmcore] OpaqueType objects memory leak
  • @@ -598,7 +597,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2003/12/22 23:56:37 $ + Last modified: $Date: 2003/12/23 23:50:31 $ From alkis at cs.uiuc.edu Wed Dec 24 09:46:02 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Dec 24 09:46:02 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervals.cpp Message-ID: <200312241545.JAA16890@kain.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervals.cpp updated: 1.15 -> 1.16 --- Log message: Do a separate pass to compute spill weights because doing it inline with live intervals was missing registers that were used before they were defined (in the arbitrary order live intervals numbers instructions). --- Diffs of the changes: (+27 -10) Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.15 llvm/lib/CodeGen/LiveIntervals.cpp:1.16 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.15 Mon Dec 22 07:54:29 2003 +++ llvm/lib/CodeGen/LiveIntervals.cpp Wed Dec 24 09:44:53 2003 @@ -106,6 +106,33 @@ computeIntervals(); + // compute spill weights + const LoopInfo& loopInfo = getAnalysis(); + + for (MbbIndex2MbbMap::iterator + it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end(); + it != itEnd; ++it) { + MachineBasicBlock* mbb = it->second; + + unsigned loopDepth = loopInfo.getLoopDepth(mbb->getBasicBlock()); + + for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); + mi != miEnd; ++mi) { + MachineInstr* instr = *mi; + for (int i = instr->getNumOperands() - 1; i >= 0; --i) { + MachineOperand& mop = instr->getOperand(i); + + if (!mop.isVirtualRegister()) + continue; + + unsigned reg = mop.getAllocatedRegNum(); + Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg); + assert(r2iit != r2iMap_.end()); + intervals_[r2iit->second].weight += pow(10.0F, loopDepth); + } + } + } + return true; } @@ -255,8 +282,6 @@ { DEBUG(std::cerr << "computing live intervals:\n"); - const LoopInfo& loopInfo = getAnalysis(); - for (MbbIndex2MbbMap::iterator it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end(); it != itEnd; ++it) { @@ -264,8 +289,6 @@ DEBUG(std::cerr << "machine basic block: " << mbb->getBasicBlock()->getName() << "\n"); - unsigned loopDepth = loopInfo.getLoopDepth(mbb->getBasicBlock()); - for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); mi != miEnd; ++mi) { MachineInstr* instr = *mi; @@ -296,12 +319,6 @@ else handleVirtualRegisterDef(mbb, mi, reg); } - - // update weights - Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg); - if (r2iit != r2iMap_.end() && - reg >= MRegisterInfo::FirstVirtualRegister) - intervals_[r2iit->second].weight += pow(10.0F, loopDepth); } } } From alkis at cs.uiuc.edu Wed Dec 24 12:54:01 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Dec 24 12:54:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200312241853.MAA00900@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.18 -> 1.19 --- Log message: Improve debugging output when choosing a register to spill. --- Diffs of the changes: (+3 -8) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.18 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.19 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.18 Tue Dec 23 12:00:33 2003 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Wed Dec 24 12:53:31 2003 @@ -552,8 +552,7 @@ if (cur->weight < minWeight) { restoreRegUse(); - DEBUG(std::cerr << "\t\t\t\tspilling : " << mri_->getName(minReg) - << ", weight: " << cur->weight << '\n'); + DEBUG(std::cerr << "\t\t\t\tspilling : " << *cur << '\n'); assignVirt2StackSlot(cur->reg); } else { @@ -570,9 +569,7 @@ toSpill.find(v2pMap_[reg]) != toSpill.end() && cur->overlaps(**i)) { spilled.push_back(v2pMap_[reg]); - DEBUG(std::cerr << "\t\t\t\tspilling : " - << mri_->getName(minReg) << ", weight: " - << (*i)->weight << '\n'); + DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n'); assignVirt2StackSlot(reg); i = active_.erase(i); } @@ -586,9 +583,7 @@ if (reg >= MRegisterInfo::FirstVirtualRegister && toSpill.find(v2pMap_[reg]) != toSpill.end() && cur->overlaps(**i)) { - DEBUG(std::cerr << "\t\t\t\tspilling : " - << mri_->getName(minReg) << ", weight: " - << (*i)->weight << '\n'); + DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n'); assignVirt2StackSlot(reg); i = inactive_.erase(i); } From lattner at cs.uiuc.edu Thu Dec 25 13:46:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 25 13:46:00 2003 Subject: [llvm-commits] CVS: poolalloc/runtime/Makefile Message-ID: <200312251945.NAA25318@zion.cs.uiuc.edu> Changes in directory poolalloc/runtime: Makefile updated: 1.3 -> 1.4 --- Log message: Add FL2Allocator runtime --- Diffs of the changes: (+1 -1) Index: poolalloc/runtime/Makefile diff -u poolalloc/runtime/Makefile:1.3 poolalloc/runtime/Makefile:1.4 --- poolalloc/runtime/Makefile:1.3 Tue Nov 11 11:33:44 2003 +++ poolalloc/runtime/Makefile Thu Dec 25 13:45:09 2003 @@ -6,6 +6,6 @@ # # List all of the subdirectories that we will compile. # -DIRS=PoolAllocator FreeListAllocator +DIRS=PoolAllocator FreeListAllocator FL2Allocator include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Thu Dec 25 13:46:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 25 13:46:03 2003 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/ Message-ID: <200312251945.NAA25299@zion.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/poolalloc/runtime/FL2Allocator added to the repository --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Thu Dec 25 13:47:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 25 13:47:01 2003 Subject: [llvm-commits] CVS: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Makefile PoolAllocator.h Message-ID: <200312251946.NAA25339@zion.cs.uiuc.edu> Changes in directory poolalloc/runtime/FL2Allocator: FreeListAllocator.cpp added (r1.1) Makefile added (r1.1) PoolAllocator.h added (r1.1) --- Log message: initial checkin of fl2allocator for sumant --- Diffs of the changes: (+301 -0) Index: poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp diff -c /dev/null poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp:1.1 *** /dev/null Thu Dec 25 13:46:30 2003 --- poolalloc/runtime/FL2Allocator/FreeListAllocator.cpp Thu Dec 25 13:46:20 2003 *************** *** 0 **** --- 1,218 ---- + //===- FreeListAllocator.cpp - Simple linked-list based pool allocator ----===// + // + // 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 is one possible implementation of the LLVM pool allocator runtime + // library. + // + // + //===----------------------------------------------------------------------===// + + #include "PoolAllocator.h" + #include + #include + #include + + //===----------------------------------------------------------------------===// + // + // PoolSlab implementation + // + //===----------------------------------------------------------------------===// + + #define PageSize (18U*1024U) + + // PoolSlab Structure - Hold multiple objects of the current node type. + // Invariants: FirstUnused <= UsedEnd + // + struct PoolSlab { + // Next - This link is used when we need to traverse the list of slabs in a + // pool, for example, to destroy them all. + PoolSlab *Next; + + public: + static void create(PoolTy *Pool); + void destroy(); + + PoolSlab *getNext() const { return Next; } + }; + + // create - Create a new (empty) slab and add it to the end of the Pools list. + void PoolSlab::create(PoolTy *Pool) { + PoolSlab *PS = (PoolSlab*)malloc(PageSize); + + // Add the body of the slab to the free list... + FreedNodeHeader *SlabBody = (FreedNodeHeader*)(PS+1); + SlabBody->Size = PageSize-sizeof(PoolSlab)-sizeof(FreedNodeHeader); + SlabBody->NormalHeader.Next = Pool->FreeNodeList; + Pool->FreeNodeList = SlabBody; + + // Add the slab to the list... + PS->Next = Pool->Slabs; + Pool->Slabs = PS; + } + + void PoolSlab::destroy() { + free(this); + } + + + //===----------------------------------------------------------------------===// + // + // Pool allocator library implementation + // + //===----------------------------------------------------------------------===// + + // poolinit - Initialize a pool descriptor to empty + // + void poolinit(PoolTy *Pool) { + assert(Pool && "Null pool pointer passed into poolinit!\n"); + Pool->Slabs = 0; + Pool->FreeNodeList = 0; + Pool->LargeArrays = 0; + } + + // pooldestroy - Release all memory allocated for a pool + // + void pooldestroy(PoolTy *Pool) { + assert(Pool && "Null pool pointer passed in to pooldestroy!\n"); + + // Free all allocated slabs. + PoolSlab *PS = Pool->Slabs; + while (PS) { + PoolSlab *Next = PS->getNext(); + PS->destroy(); + PS = Next; + } + + // Free all of the large arrays. + LargeArrayHeader *LAH = Pool->LargeArrays; + while (LAH) { + LargeArrayHeader *Next = LAH->Next; + free(LAH); + LAH = Next; + } + } + + + void *poolalloc(PoolTy *Pool, unsigned NumBytes) { + assert(Pool && "Null pool pointer passed in to poolalloc!\n"); + if (NumBytes == 0) + NumBytes = 4; + else + NumBytes = (NumBytes+3) & ~3; // Round up to 4 bytes... + + // Fast path. In the common case, we can allocate a portion of the node at + // the front of the free list. + if (Pool->FreeNodeList) { + FreedNodeHeader *FirstNode = Pool->FreeNodeList; + unsigned FirstNodeSize = FirstNode->Size; + if (FirstNodeSize > 2*NumBytes+sizeof(NodeHeader)) { + // Put the remainder back on the list... + FreedNodeHeader *NextNodes = + (FreedNodeHeader*)((char*)FirstNode + sizeof(NodeHeader) + NumBytes); + NextNodes->Size = FirstNodeSize-NumBytes-sizeof(NodeHeader); + NextNodes->NormalHeader.Next = FirstNode->NormalHeader.Next; + Pool->FreeNodeList = NextNodes; + FirstNode->NormalHeader.ObjectSize = NumBytes; + return &FirstNode->NormalHeader+1; + } else if (FirstNodeSize > NumBytes) { + Pool->FreeNodeList = FirstNode->NormalHeader.Next; // Unlink + FirstNode->NormalHeader.ObjectSize = FirstNodeSize; + return &FirstNode->NormalHeader+1; + } + } + + // Perform a search of the free list, taking the front of the first free chunk + // that is big enough. + if (NumBytes <= PageSize-sizeof(PoolSlab)-sizeof(NodeHeader)) { + do { + FreedNodeHeader **FN = &Pool->FreeNodeList; + FreedNodeHeader *FNN = *FN; + + // Search the list for the first-fit + while (FNN && FNN->Size < NumBytes) + FN = &FNN->NormalHeader.Next, FNN = *FN; + + if (FNN) { + // We found a slab big enough. If it's a perfect fit, just unlink from + // the free list, otherwise, slice a little bit off and adjust the free + // list. + if (FNN->Size > 2*NumBytes+sizeof(NodeHeader)) { + // Put the remainder back on the list... + FreedNodeHeader *NextNodes = + (FreedNodeHeader*)((char*)FNN + sizeof(NodeHeader) + NumBytes); + NextNodes->Size = FNN->Size-NumBytes-sizeof(NodeHeader); + NextNodes->NormalHeader.Next = FNN->NormalHeader.Next; + *FN = NextNodes; + FNN->NormalHeader.ObjectSize = NumBytes; + return &FNN->NormalHeader+1; + } else { + *FN = FNN->NormalHeader.Next; // Unlink + FNN->NormalHeader.ObjectSize = FNN->Size; + return &FNN->NormalHeader+1; + } + } + + // Oops, we didn't find anything on the free list big enough! Allocate + // another slab and try again. + PoolSlab::create(Pool); + } while (1); + } + + // Otherwise, the allocation is a large array. Since we're not going to be + // able to help much for this allocation, simply pass it on to malloc. + LargeArrayHeader *LAH = (LargeArrayHeader*)malloc(sizeof(LargeArrayHeader) + + NumBytes); + LAH->Next = Pool->LargeArrays; + Pool->LargeArrays = LAH; + LAH->Prev = &Pool->LargeArrays; + LAH->Marker = ~0U; + return LAH+1; + } + + + void poolfree(PoolTy *Pool, void *Node) { + assert(Pool && "Null pool pointer passed in to poolfree!\n"); + + // Check to see how many elements were allocated to this node... + FreedNodeHeader *FNH = (FreedNodeHeader*)((char*)Node-sizeof(NodeHeader)); + unsigned Size = FNH->NormalHeader.ObjectSize; + if (Size == ~0U) { + // Must unlink from list. + fprintf(stderr, "CANNOT FREE LARGE ARRAY YET!\n"); + return; + } + + // If there are already nodes on the freelist, see if this blocks should be + // coallesced into one of the early blocks on the front of the list. This is + // a simple check that prevents many horrible forms of fragmentation. + // + if (FreedNodeHeader *CurFrontNode = Pool->FreeNodeList) { + if ((char*)FNH + sizeof(NodeHeader) + Size == (char*)CurFrontNode) { + // This node immediately preceeds the node on the front of the + // free-list. Remove the current front of the free list, replacing it + // with the current block. + FNH->Size = Size + CurFrontNode->Size+sizeof(NodeHeader); + FNH->NormalHeader.Next = CurFrontNode->NormalHeader.Next; + Pool->FreeNodeList = FNH; + return; + } + + if ((char*)CurFrontNode + sizeof(NodeHeader) + CurFrontNode->Size == + (char*)FNH) { + // This node immediately follows the node on the front of the free-list. + // No list manipulation is required. + CurFrontNode->Size += Size+sizeof(NodeHeader); + return; + } + } + + FNH->Size = Size; + FNH->NormalHeader.Next = Pool->FreeNodeList; + Pool->FreeNodeList = FNH; + } Index: poolalloc/runtime/FL2Allocator/Makefile diff -c /dev/null poolalloc/runtime/FL2Allocator/Makefile:1.1 *** /dev/null Thu Dec 25 13:46:30 2003 --- poolalloc/runtime/FL2Allocator/Makefile Thu Dec 25 13:46:20 2003 *************** *** 0 **** --- 1,9 ---- + LEVEL = ../.. + BYTECODE_LIBRARY=1 + SHARED_LIBRARY=1 + LIBRARYNAME=poolalloc_rt + + include $(LEVEL)/Makefile.common + + # Always build optimized and debug versions + all:: $(LIBNAME_OBJO) $(LIBNAME_OBJG) Index: poolalloc/runtime/FL2Allocator/PoolAllocator.h diff -c /dev/null poolalloc/runtime/FL2Allocator/PoolAllocator.h:1.1 *** /dev/null Thu Dec 25 13:46:30 2003 --- poolalloc/runtime/FL2Allocator/PoolAllocator.h Thu Dec 25 13:46:20 2003 *************** *** 0 **** --- 1,74 ---- + //===- PoolAllocator.h - Pool allocator runtime interface file --*- 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 defines the interface which is implemented by the LLVM pool + // allocator runtime library. + // + //===----------------------------------------------------------------------===// + + #ifndef POOLALLOCATOR_RUNTIME_H + #define POOLALLOCATOR_RUNTIME_H + + struct PoolSlab; + struct FreedNodeHeader; + + // NodeHeader - Each block of memory is preceeded in the the pool by one of + // these headers. If the node is allocated, the ObjectSize value is used, if + // the object is free, the 'Next' value is used. + union NodeHeader { + FreedNodeHeader *Next; + unsigned ObjectSize; + }; + + + // When objects are on the free list, we pretend they have this header. + struct FreedNodeHeader { + // NormalHeader - This is the normal node header that is on allocated or free + // blocks. + NodeHeader NormalHeader; + + // Size - This is stored in the actual data area, indicating how many bytes + // there are in the region. + unsigned Size; + }; + + + // Large Arrays are passed on to directly malloc, and are not necessarily page + // aligned. These arrays are marked by setting the object size preheader to ~0. + // LargeArrays are on their own list to allow for efficient deletion. + struct LargeArrayHeader { + LargeArrayHeader **Prev, *Next; + + // Marker: this is the ObjectSize marker which MUST BE THE LAST ELEMENT of + // this header! + unsigned Marker; + }; + + + struct PoolTy { + // Lists - the list of slabs in this pool. + PoolSlab *Slabs; + + // LargeArrays - A doubly linked list of large array chunks, dynamically + // allocated with malloc. + LargeArrayHeader *LargeArrays; + + // The list of free'd nodes. + FreedNodeHeader *FreeNodeList; + }; + + extern "C" { + void poolinit(PoolTy *Pool); + void poolmakeunfreeable(PoolTy *Pool); + void pooldestroy(PoolTy *Pool); + void *poolalloc(PoolTy *Pool, unsigned NumBytes); + void poolfree(PoolTy *Pool, void *Node); + } + + #endif From lattner at cs.uiuc.edu Thu Dec 25 23:08:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 25 23:08:01 2003 Subject: [llvm-commits] CVS: llvm/tools/lli/lli.cpp Message-ID: <200312260507.XAA27199@zion.cs.uiuc.edu> Changes in directory llvm/tools/lli: lli.cpp updated: 1.36 -> 1.37 --- Log message: update comment --- Diffs of the changes: (+3 -6) Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.36 llvm/tools/lli/lli.cpp:1.37 --- llvm/tools/lli/lli.cpp:1.36 Thu Dec 11 18:47:19 2003 +++ llvm/tools/lli/lli.cpp Thu Dec 25 23:07:35 2003 @@ -7,12 +7,9 @@ // //===----------------------------------------------------------------------===// // -// This utility provides a way to execute LLVM bytecode without static -// compilation. This consists of a very simple and slow (but portable) -// interpreter, along with capability for system specific dynamic compilers. At -// runtime, the fastest (stable) execution engine is selected to run the -// program. This means the JIT compiler for the current platform if it's -// available. +// This utility provides a simple wrapper around the LLVM Execution Engines, +// which allow the direct execution of LLVM programs through a Just-In-Time +// compiler, or through an intepreter if no JIT is available for this platform. // //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Fri Dec 26 00:13:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:13:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Message-ID: <200312260612.AAA03481@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ExecutionEngine: ExecutionEngine.h updated: 1.22 -> 1.23 --- Log message: Rename 'run' to 'runFunction' to emphasize that it is usable to run any function in a module, not just main --- Diffs of the changes: (+8 -6) Index: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h diff -u llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.22 llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.23 --- llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.22 Fri Dec 19 21:35:50 2003 +++ llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Fri Dec 26 00:12:25 2003 @@ -53,13 +53,15 @@ Module &getModule() const { return CurMod; } const TargetData &getTargetData() const { return *TD; } - /// run - Start execution with the specified function, arguments, and - /// environment. - /// - virtual GenericValue run(Function *F, - const std::vector &ArgValues) = 0; - + /// create - This is the factory method for creating an execution engine which + /// is appropriate for the current machine. static ExecutionEngine *create(ModuleProvider *MP, bool ForceInterpreter); + + /// runFunction - Execute the specified function with the specified arguments, + /// and return the result. + /// + virtual GenericValue runFunction(Function *F, + const std::vector &ArgValues) = 0; void addGlobalMapping(const GlobalValue *GV, void *Addr) { void *&CurVal = GlobalAddress[GV]; From lattner at cs.uiuc.edu Fri Dec 26 00:14:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:14:01 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/Intercept.cpp JIT.cpp JIT.h Message-ID: <200312260613.AAA03521@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: Intercept.cpp updated: 1.12 -> 1.13 JIT.cpp updated: 1.30 -> 1.31 JIT.h updated: 1.21 -> 1.22 --- Log message: No longer run atExit functions from run() rename run to runFunction Genericize the runFunction code a little bit, though it still stinks --- Diffs of the changes: (+26 -22) Index: llvm/lib/ExecutionEngine/JIT/Intercept.cpp diff -u llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.12 llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.13 --- llvm/lib/ExecutionEngine/JIT/Intercept.cpp:1.12 Fri Dec 19 19:46:27 2003 +++ llvm/lib/ExecutionEngine/JIT/Intercept.cpp Fri Dec 26 00:13:47 2003 @@ -28,7 +28,7 @@ /// calls to atexit(3), which we intercept and store in /// AtExitHandlers. /// -void JIT::runAtExitHandlers() { +static void runAtExitHandlers() { while (!AtExitHandlers.empty()) { void (*Fn)() = AtExitHandlers.back(); AtExitHandlers.pop_back(); @@ -45,7 +45,7 @@ // jit_exit - Used to intercept the "exit" library call. static void jit_exit(int Status) { - JIT::runAtExitHandlers(); // Run atexit handlers... + runAtExitHandlers(); // Run atexit handlers... exit(Status); } Index: llvm/lib/ExecutionEngine/JIT/JIT.cpp diff -u llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.30 llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.31 --- llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.30 Sat Dec 20 04:19:18 2003 +++ llvm/lib/ExecutionEngine/JIT/JIT.cpp Fri Dec 26 00:13:47 2003 @@ -51,22 +51,31 @@ /// run - Start execution with the specified function and arguments. /// -GenericValue JIT::run(Function *F, const std::vector &ArgValues) { +GenericValue JIT::runFunction(Function *F, + const std::vector &ArgValues) { assert (F && "Function *F was null at entry to run()"); + GenericValue rv; - int (*PF)(int, char **, const char **) = - (int(*)(int, char **, const char **))getPointerToFunction(F); - assert(PF != 0 && "Pointer to fn's code was null after getPointerToFunction"); + if (ArgValues.size() == 3) { + int (*PF)(int, char **, const char **) = + (int(*)(int, char **, const char **))getPointerToFunction(F); + assert(PF && "Pointer to fn's code was null after getPointerToFunction"); + + // Call the function. + int ExitCode = PF(ArgValues[0].IntVal, (char **) GVTOP (ArgValues[1]), + (const char **) GVTOP (ArgValues[2])); + + rv.IntVal = ExitCode; + } else { + // FIXME: This code should handle a couple of common cases efficiently, but + // it should also implement the general case by code-gening a new anonymous + // nullary function to call. + assert(ArgValues.size() == 1); + void (*PF)(int) = (void(*)(int))getPointerToFunction(F); + assert(PF && "Pointer to fn's code was null after getPointerToFunction"); + PF(ArgValues[0].IntVal); + } - // Call the function. - int ExitCode = PF(ArgValues[0].IntVal, (char **) GVTOP (ArgValues[1]), - (const char **) GVTOP (ArgValues[2])); - - // Run any atexit handlers now! - runAtExitHandlers(); - - GenericValue rv; - rv.IntVal = ExitCode; return rv; } Index: llvm/lib/ExecutionEngine/JIT/JIT.h diff -u llvm/lib/ExecutionEngine/JIT/JIT.h:1.21 llvm/lib/ExecutionEngine/JIT/JIT.h:1.22 --- llvm/lib/ExecutionEngine/JIT/JIT.h:1.21 Fri Dec 19 21:36:47 2003 +++ llvm/lib/ExecutionEngine/JIT/JIT.h Fri Dec 26 00:13:47 2003 @@ -50,8 +50,8 @@ /// run - Start execution with the specified function and arguments. /// - virtual GenericValue run(Function *F, - const std::vector &ArgValues); + virtual GenericValue runFunction(Function *F, + const std::vector &ArgValues); /// getPointerToNamedFunction - This method returns the address of the /// specified function by using the dlsym function call. As such it is only @@ -63,11 +63,6 @@ // which causes lazy compilation of the target function. // static void CompilationCallback(); - - /// runAtExitHandlers - Before exiting the program, at_exit functions must be - /// called. This method calls them. - /// - static void runAtExitHandlers(); /// getPointerToFunction - This returns the address of the specified function, /// compiling it if necessary. From lattner at cs.uiuc.edu Fri Dec 26 00:14:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:14:04 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp Interpreter.h Message-ID: <200312260613.AAA03495@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: Interpreter.cpp updated: 1.18 -> 1.19 Interpreter.h updated: 1.57 -> 1.58 --- Log message: No longer run atExit functions from run() rename run to runFunction --- Diffs of the changes: (+6 -10) Index: llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.18 llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.19 --- llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.18 Sun Dec 14 17:25:48 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp Fri Dec 26 00:13:05 2003 @@ -69,7 +69,7 @@ /// run - Start execution with the specified function and arguments. /// -GenericValue Interpreter::run(Function *F, +GenericValue Interpreter::runFunction(Function *F, const std::vector &ArgValues) { assert (F && "Function *F was null at entry to run()"); @@ -91,9 +91,6 @@ // Start executing the function. run(); - // Run any atexit handlers now! - runAtExitHandlers(); - GenericValue rv; rv.IntVal = ExitCode; return rv; Index: llvm/lib/ExecutionEngine/Interpreter/Interpreter.h diff -u llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.57 llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.58 --- llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.57 Wed Dec 10 18:23:28 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Interpreter.h Fri Dec 26 00:13:05 2003 @@ -92,11 +92,10 @@ Interpreter(Module *M, bool isLittleEndian, bool isLongPointer); inline ~Interpreter() { } - /// runAtExitHandlers - Run any functions registered by the - /// program's calls to atexit(3), which we intercept and store in - /// AtExitHandlers. + /// runAtExitHandlers - Run any functions registered by the program's calls to + /// atexit(3), which we intercept and store in AtExitHandlers. /// - void runAtExitHandlers (); + void runAtExitHandlers(); /// create - Create an interpreter ExecutionEngine. This can never fail. /// @@ -104,8 +103,8 @@ /// run - Start execution with the specified function and arguments. /// - virtual GenericValue run(Function *F, - const std::vector &ArgValues); + virtual GenericValue runFunction(Function *F, + const std::vector &ArgValues); /// recompileAndRelinkFunction - For the interpreter, functions are always /// up-to-date. From lattner at cs.uiuc.edu Fri Dec 26 00:15:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:15:01 2003 Subject: [llvm-commits] CVS: llvm/tools/lli/lli.cpp Message-ID: <200312260614.AAA03535@zion.cs.uiuc.edu> Changes in directory llvm/tools/lli: lli.cpp updated: 1.37 -> 1.38 --- Log message: * eliminate the -f argument to lli, as it was silly and never useful anyway * Inline callMain function * Remove hack from the ExecutionEngines where the 'run' method would automatically run atExit functions. Fixing this requires explicitly calling exit if main returns --- Diffs of the changes: (+33 -37) Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.37 llvm/tools/lli/lli.cpp:1.38 --- llvm/tools/lli/lli.cpp:1.37 Thu Dec 25 23:07:35 2003 +++ llvm/tools/lli/lli.cpp Fri Dec 26 00:14:47 2003 @@ -34,10 +34,6 @@ cl::list InputArgv(cl::ConsumeAfter, cl::desc("...")); - cl::opt - MainFunction("f", cl::desc("Function to execute"), cl::init("main"), - cl::value_desc("function name")); - cl::opt ForceInterpreter("force-interpreter", cl::desc("Force interpretation: disable JIT"), cl::init(false)); @@ -96,32 +92,6 @@ } } -/// callAsMain - Call the function named FnName from M as if its -/// signature were int main (int argc, char **argv, const char -/// **envp), using the contents of Args to determine argc & argv, and -/// the contents of EnvVars to determine envp. Returns the result -/// from calling FnName, or -1 and prints an error msg. if the named -/// function cannot be found. -/// -int callAsMain(ExecutionEngine *EE, ModuleProvider *MP, - const std::string &FnName, - const std::vector &Args, - const std::vector &EnvVars) { - Function *Fn = MP->getModule()->getNamedFunction(FnName); - if (!Fn) { - std::cerr << "Function '" << FnName << "' not found in module.\n"; - return -1; - } - std::vector GVArgs; - GenericValue GVArgc; - GVArgc.IntVal = Args.size(); - GVArgs.push_back(GVArgc); // Arg #0 = argc. - GVArgs.push_back(PTOGV(CreateArgv(EE, Args))); // Arg #1 = argv. - assert(((char **)GVTOP(GVArgs[1]))[0] && "argv[0] was null after CreateArgv"); - GVArgs.push_back(PTOGV(CreateArgv(EE, EnvVars))); // Arg #2 = envp. - return EE->run(Fn, GVArgs).IntVal; -} - //===----------------------------------------------------------------------===// // main Driver function // @@ -157,11 +127,37 @@ // Add the module's name to the start of the vector of arguments to main(). InputArgv.insert(InputArgv.begin(), InputFile); - // Run the main function! - int ExitCode = callAsMain(EE, MP, MainFunction, InputArgv, - makeStringVector(envp)); - - // Now that we are done executing the program, shut down the execution engine - delete EE; - return ExitCode; + // Call the main function from M as if its signature were: + // int main (int argc, char **argv, const char **envp) + // using the contents of Args to determine argc & argv, and the contents of + // EnvVars to determine envp. + // + Function *Fn = MP->getModule()->getMainFunction(); + if (!Fn) { + std::cerr << "'main' function not found in module.\n"; + return -1; + } + + std::vector GVArgs; + GenericValue GVArgc; + GVArgc.IntVal = InputArgv.size(); + GVArgs.push_back(GVArgc); // Arg #0 = argc. + GVArgs.push_back(PTOGV(CreateArgv(EE, InputArgv))); // Arg #1 = argv. + assert(((char **)GVTOP(GVArgs[1]))[0] && "argv[0] was null after CreateArgv"); + + std::vector EnvVars = makeStringVector(envp); + GVArgs.push_back(PTOGV(CreateArgv(EE, EnvVars))); // Arg #2 = envp. + GenericValue Result = EE->runFunction(Fn, GVArgs); + + // If the program didn't explicitly call exit, call exit now, for the program. + // This ensures that any atexit handlers get called correctly. + Function *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy, + Type::IntTy, 0); + + GVArgs.clear(); + GVArgs.push_back(Result); + EE->runFunction(Exit, GVArgs); + + std::cerr << "ERROR: exit(" << Result.IntVal << ") returned!\n"; + abort(); } From lattner at cs.uiuc.edu Fri Dec 26 00:17:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:17:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/ConstantReader.cpp Message-ID: <200312260616.AAA03546@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: ConstantReader.cpp updated: 1.65 -> 1.66 --- Log message: minor cleanups --- Diffs of the changes: (+6 -7) Index: llvm/lib/Bytecode/Reader/ConstantReader.cpp diff -u llvm/lib/Bytecode/Reader/ConstantReader.cpp:1.65 llvm/lib/Bytecode/Reader/ConstantReader.cpp:1.66 --- llvm/lib/Bytecode/Reader/ConstantReader.cpp:1.65 Wed Nov 19 11:20:42 2003 +++ llvm/lib/Bytecode/Reader/ConstantReader.cpp Fri Dec 26 00:16:00 2003 @@ -111,17 +111,16 @@ assert(Tab.size() == 0 && "should not have read type constants in before!"); // Insert a bunch of opaque types to be resolved later... - // FIXME: this is dumb Tab.reserve(NumEntries); - for (unsigned i = 0; i < NumEntries; ++i) + for (unsigned i = 0; i != NumEntries; ++i) Tab.push_back(OpaqueType::get()); // Loop through reading all of the types. Forward types will make use of the // opaque types just inserted. // - for (unsigned i = 0; i < NumEntries; ++i) { + for (unsigned i = 0; i != NumEntries; ++i) { const Type *NewTy = parseTypeConstant(Buf, EndBuf), *OldTy = Tab[i].get(); - if (NewTy == 0) throw std::string("Parsed invalid type."); + if (NewTy == 0) throw std::string("Couldn't parse type!"); BCR_TRACE(4, "#" << i << ": Read Type Constant: '" << NewTy << "' Replacing: " << OldTy << "\n"); @@ -130,10 +129,10 @@ // // Refine the abstract type to the new type. This causes all uses of the - // abstract type to use the newty. This also will cause the opaque type - // to be deleted... + // abstract type to use NewTy. This also will cause the opaque type to be + // deleted... // - ((DerivedType*)Tab[i].get())->refineAbstractTypeTo(NewTy); + cast(const_cast(OldTy))->refineAbstractTypeTo(NewTy); // This should have replace the old opaque type with the new type in the // value table... or with a preexisting type that was already in the system From lattner at cs.uiuc.edu Fri Dec 26 00:37:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:37:02 2003 Subject: [llvm-commits] CVS: llvm/tools/lli/lli.cpp Message-ID: <200312260636.AAA04979@zion.cs.uiuc.edu> Changes in directory llvm/tools/lli: lli.cpp updated: 1.38 -> 1.39 --- Log message: Simplify code --- Diffs of the changes: (+24 -42) Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.38 llvm/tools/lli/lli.cpp:1.39 --- llvm/tools/lli/lli.cpp:1.38 Fri Dec 26 00:14:47 2003 +++ llvm/tools/lli/lli.cpp Fri Dec 26 00:36:20 2003 @@ -44,52 +44,32 @@ " program"), cl::value_desc("executable")); } -static std::vector makeStringVector(char * const *envp) { - std::vector rv; - for (unsigned i = 0; envp[i]; ++i) - rv.push_back(envp[i]); - return rv; -} - static void *CreateArgv(ExecutionEngine *EE, const std::vector &InputArgv) { - if (EE->getTargetData().getPointerSize() == 8) { // 64 bit target? - PointerTy *Result = new PointerTy[InputArgv.size()+1]; - DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); - - for (unsigned i = 0; i < InputArgv.size(); ++i) { - unsigned Size = InputArgv[i].size()+1; - char *Dest = new char[Size]; - DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); - - std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); - Dest[Size-1] = 0; - - // Endian safe: Result[i] = (PointerTy)Dest; - EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i), - Type::LongTy); - } - Result[InputArgv.size()] = 0; - return Result; - } else { // 32 bit target? - int *Result = new int[InputArgv.size()+1]; - DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); - - for (unsigned i = 0; i < InputArgv.size(); ++i) { - unsigned Size = InputArgv[i].size()+1; - char *Dest = new char[Size]; - DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); + unsigned PtrSize = EE->getTargetData().getPointerSize(); + char *Result = new char[(InputArgv.size()+1)*PtrSize]; + + DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); + const Type *SBytePtr = PointerType::get(Type::SByteTy); + + for (unsigned i = 0; i != InputArgv.size(); ++i) { + unsigned Size = InputArgv[i].size()+1; + char *Dest = new char[Size]; + DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); - std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); - Dest[Size-1] = 0; + std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); + Dest[Size-1] = 0; - // Endian safe: Result[i] = (PointerTy)Dest; - EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i), - Type::IntTy); - } - Result[InputArgv.size()] = 0; // null terminate it - return Result; + // Endian safe: Result[i] = (PointerTy)Dest; + EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i*PtrSize), + SBytePtr); } + + // Null terminate it + EE->StoreValueToMemory(PTOGV(0), + (GenericValue*)(Result+InputArgv.size()*PtrSize), + SBytePtr); + return Result; } //===----------------------------------------------------------------------===// @@ -145,7 +125,9 @@ GVArgs.push_back(PTOGV(CreateArgv(EE, InputArgv))); // Arg #1 = argv. assert(((char **)GVTOP(GVArgs[1]))[0] && "argv[0] was null after CreateArgv"); - std::vector EnvVars = makeStringVector(envp); + std::vector EnvVars; + for (unsigned i = 0; envp[i]; ++i) + EnvVars.push_back(envp[i]); GVArgs.push_back(PTOGV(CreateArgv(EE, EnvVars))); // Arg #2 = envp. GenericValue Result = EE->runFunction(Fn, GVArgs); From lattner at cs.uiuc.edu Fri Dec 26 00:51:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:51:01 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/ExecutionEngine.cpp Message-ID: <200312260650.AAA10656@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine: ExecutionEngine.cpp updated: 1.42 -> 1.43 --- Log message: Factor code out of LLI --- Diffs of the changes: (+54 -0) Index: llvm/lib/ExecutionEngine/ExecutionEngine.cpp diff -u llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.42 llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.43 --- llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.42 Fri Dec 19 21:36:25 2003 +++ llvm/lib/ExecutionEngine/ExecutionEngine.cpp Fri Dec 26 00:50:30 2003 @@ -46,6 +46,60 @@ delete MP; } + +// CreateArgv - Turn a vector of strings into a nice argv style array of +// pointers to null terminated strings. +// +static void *CreateArgv(ExecutionEngine *EE, + const std::vector &InputArgv) { + unsigned PtrSize = EE->getTargetData().getPointerSize(); + char *Result = new char[(InputArgv.size()+1)*PtrSize]; + + DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); + const Type *SBytePtr = PointerType::get(Type::SByteTy); + + for (unsigned i = 0; i != InputArgv.size(); ++i) { + unsigned Size = InputArgv[i].size()+1; + char *Dest = new char[Size]; + DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); + + std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); + Dest[Size-1] = 0; + + // Endian safe: Result[i] = (PointerTy)Dest; + EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i*PtrSize), + SBytePtr); + } + + // Null terminate it + EE->StoreValueToMemory(PTOGV(0), + (GenericValue*)(Result+InputArgv.size()*PtrSize), + SBytePtr); + return Result; +} + +/// runFunctionAsMain - This is a helper function which wraps runFunction to +/// handle the common task of starting up main with the specified argc, argv, +/// and envp parameters. +int ExecutionEngine::runFunctionAsMain(Function *Fn, + const std::vector &argv, + const char * const * envp) { + std::vector GVArgs; + GenericValue GVArgc; + GVArgc.IntVal = argv.size(); + GVArgs.push_back(GVArgc); // Arg #0 = argc. + GVArgs.push_back(PTOGV(CreateArgv(this, argv))); // Arg #1 = argv. + assert(((char **)GVTOP(GVArgs[1]))[0] && "argv[0] was null after CreateArgv"); + + std::vector EnvVars; + for (unsigned i = 0; envp[i]; ++i) + EnvVars.push_back(envp[i]); + GVArgs.push_back(PTOGV(CreateArgv(this, EnvVars))); // Arg #2 = envp. + return runFunction(Fn, GVArgs).IntVal; +} + + + /// If possible, create a JIT, unless the caller specifically requests an /// Interpreter or there's an error. If even an Interpreter cannot be created, /// NULL is returned. From lattner at cs.uiuc.edu Fri Dec 26 00:51:05 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:51:05 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Message-ID: <200312260650.AAA10646@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ExecutionEngine: ExecutionEngine.h updated: 1.23 -> 1.24 --- Log message: New method --- Diffs of the changes: (+7 -0) Index: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h diff -u llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.23 llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.24 --- llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.23 Fri Dec 26 00:12:25 2003 +++ llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Fri Dec 26 00:50:15 2003 @@ -63,6 +63,13 @@ virtual GenericValue runFunction(Function *F, const std::vector &ArgValues) = 0; + /// runFunctionAsMain - This is a helper function which wraps runFunction to + /// handle the common task of starting up main with the specified argc, argv, + /// and envp parameters. + int runFunctionAsMain(Function *Fn, const std::vector &argv, + const char * const * envp); + + void addGlobalMapping(const GlobalValue *GV, void *Addr) { void *&CurVal = GlobalAddress[GV]; assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!"); From lattner at cs.uiuc.edu Fri Dec 26 00:51:07 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 26 00:51:07 2003 Subject: [llvm-commits] CVS: llvm/tools/lli/lli.cpp Message-ID: <200312260650.AAA10634@zion.cs.uiuc.edu> Changes in directory llvm/tools/lli: lli.cpp updated: 1.39 -> 1.40 --- Log message: Factor out code to ExecutionEngine --- Diffs of the changes: (+10 -50) Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.39 llvm/tools/lli/lli.cpp:1.40 --- llvm/tools/lli/lli.cpp:1.39 Fri Dec 26 00:36:20 2003 +++ llvm/tools/lli/lli.cpp Fri Dec 26 00:49:53 2003 @@ -13,17 +13,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" +#include "llvm/Type.h" #include "llvm/Bytecode/Reader.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/Target/TargetMachineImpls.h" -#include "llvm/Target/TargetData.h" #include "Support/CommandLine.h" -#include "Support/Debug.h" -#include "Support/SystemUtils.h" using namespace llvm; @@ -44,34 +40,6 @@ " program"), cl::value_desc("executable")); } -static void *CreateArgv(ExecutionEngine *EE, - const std::vector &InputArgv) { - unsigned PtrSize = EE->getTargetData().getPointerSize(); - char *Result = new char[(InputArgv.size()+1)*PtrSize]; - - DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); - const Type *SBytePtr = PointerType::get(Type::SByteTy); - - for (unsigned i = 0; i != InputArgv.size(); ++i) { - unsigned Size = InputArgv[i].size()+1; - char *Dest = new char[Size]; - DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); - - std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); - Dest[Size-1] = 0; - - // Endian safe: Result[i] = (PointerTy)Dest; - EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i*PtrSize), - SBytePtr); - } - - // Null terminate it - EE->StoreValueToMemory(PTOGV(0), - (GenericValue*)(Result+InputArgv.size()*PtrSize), - SBytePtr); - return Result; -} - //===----------------------------------------------------------------------===// // main Driver function // @@ -118,28 +86,20 @@ return -1; } - std::vector GVArgs; - GenericValue GVArgc; - GVArgc.IntVal = InputArgv.size(); - GVArgs.push_back(GVArgc); // Arg #0 = argc. - GVArgs.push_back(PTOGV(CreateArgv(EE, InputArgv))); // Arg #1 = argv. - assert(((char **)GVTOP(GVArgs[1]))[0] && "argv[0] was null after CreateArgv"); - - std::vector EnvVars; - for (unsigned i = 0; envp[i]; ++i) - EnvVars.push_back(envp[i]); - GVArgs.push_back(PTOGV(CreateArgv(EE, EnvVars))); // Arg #2 = envp. - GenericValue Result = EE->runFunction(Fn, GVArgs); + // Run main... + int Result = EE->runFunctionAsMain(Fn, InputArgv, envp); // If the program didn't explicitly call exit, call exit now, for the program. // This ensures that any atexit handlers get called correctly. Function *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy, Type::IntTy, 0); - - GVArgs.clear(); - GVArgs.push_back(Result); - EE->runFunction(Exit, GVArgs); - std::cerr << "ERROR: exit(" << Result.IntVal << ") returned!\n"; + std::vector Args; + GenericValue ResultGV; + ResultGV.IntVal = Result; + Args.push_back(ResultGV); + EE->runFunction(Exit, Args); + + std::cerr << "ERROR: exit(" << Result << ") returned!\n"; abort(); } From lattner at cs.uiuc.edu Sat Dec 27 22:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Dec 27 22:04:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200312280403.WAA28573@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: BasicAliasAnalysis.cpp updated: 1.24 -> 1.25 --- Log message: Add a note --- Diffs of the changes: (+5 -0) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.24 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.25 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.24 Thu Dec 11 17:20:16 2003 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Sat Dec 27 22:03:49 2003 @@ -11,6 +11,11 @@ // that simply implements a few identities (two different globals cannot alias, // etc), but otherwise does no analysis. // +// FIXME: This could be extended for a very simple form of mod/ref information. +// If a pointer is locally allocated (either malloc or alloca) and never passed +// into a call or stored to memory, then we know that calls will not mod/ref the +// memory. This can be important for tailcallelim. +// //===----------------------------------------------------------------------===// #include "llvm/Analysis/AliasAnalysis.h" From lattner at cs.uiuc.edu Sun Dec 28 01:20:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 01:20:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/ConstantMerge.cpp Message-ID: <200312280719.BAA28999@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: ConstantMerge.cpp updated: 1.25 -> 1.26 --- Log message: Merging constants can cause further room for improvement. Iterate until we converge --- Diffs of the changes: (+45 -35) Index: llvm/lib/Transforms/IPO/ConstantMerge.cpp diff -u llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.25 llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.26 --- llvm/lib/Transforms/IPO/ConstantMerge.cpp:1.25 Mon Dec 22 17:49:36 2003 +++ llvm/lib/Transforms/IPO/ConstantMerge.cpp Sun Dec 28 01:19:08 2003 @@ -44,44 +44,54 @@ // Replacements - This vector contains a list of replacements to perform. std::vector > Replacements; - // First pass: identify all globals that can be merged together, filling in - // the Replacements vector. We cannot do the replacement in this pass because - // doing so may cause initializers of other globals to be rewritten, - // invalidating the Constant* pointers in CMap. - // - for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV) - // Only process constants with initializers - if (GV->isConstant() && GV->hasInitializer()) { - Constant *Init = GV->getInitializer(); + bool MadeChange = false; - // Check to see if the initializer is already known... - std::map::iterator I = CMap.find(Init); - - if (I == CMap.end()) { // Nope, add it to the map - CMap.insert(I, std::make_pair(Init, GV)); - } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate! - // Make all uses of the duplicate constant use the canonical version... - Replacements.push_back(std::make_pair(GV, I->second)); - } else if (I->second->hasInternalLinkage()) { - // Make all uses of the duplicate constant use the canonical version... - Replacements.push_back(std::make_pair(I->second, GV)); - I->second = GV; + // Iterate constant merging while we are still making progress. Merging two + // constants together may allow us to merge other constants together if the + // second level constants have initializers which point to the globals that + // were just merged. + while (1) { + // First pass: identify all globals that can be merged together, filling in + // the Replacements vector. We cannot do the replacement in this pass + // because doing so may cause initializers of other globals to be rewritten, + // invalidating the Constant* pointers in CMap. + // + for (Module::giterator GV = M.gbegin(), E = M.gend(); GV != E; ++GV) + // Only process constants with initializers + if (GV->isConstant() && GV->hasInitializer()) { + Constant *Init = GV->getInitializer(); + + // Check to see if the initializer is already known... + std::map::iterator I = CMap.find(Init); + + if (I == CMap.end()) { // Nope, add it to the map + CMap.insert(I, std::make_pair(Init, GV)); + } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate! + // Make all uses of the duplicate constant use the canonical version. + Replacements.push_back(std::make_pair(GV, I->second)); + } else if (I->second->hasInternalLinkage()) { + // Make all uses of the duplicate constant use the canonical version. + Replacements.push_back(std::make_pair(I->second, GV)); + I->second = GV; + } } + + if (Replacements.empty()) + return MadeChange; + CMap.clear(); + + // Now that we have figured out which replacements must be made, do them all + // now. This avoid invalidating the pointers in CMap, which are unneeded + // now. + for (unsigned i = 0, e = Replacements.size(); i != e; ++i) { + // Eliminate any uses of the dead global... + Replacements[i].first->replaceAllUsesWith(Replacements[i].second); + + // Delete the global value from the module... + M.getGlobalList().erase(Replacements[i].first); } - - if (Replacements.empty()) return false; - CMap.clear(); - - // Now that we have figured out which replacements must be made, do them all - // now. This avoid invalidating the pointers in CMap, which are unneeded now. - for (unsigned i = 0, e = Replacements.size(); i != e; ++i) { - // Eliminate any uses of the dead global... - Replacements[i].first->replaceAllUsesWith(Replacements[i].second); - // Delete the global value from the module... - M.getGlobalList().erase(Replacements[i].first); + NumMerged += Replacements.size(); + Replacements.clear(); } - - NumMerged += Replacements.size(); - return true; } From lattner at cs.uiuc.edu Sun Dec 28 02:01:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 02:01:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/Passes.cpp Message-ID: <200312280800.CAA29076@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: Passes.cpp updated: 1.4 -> 1.5 --- Log message: finegrainify namespacification minor cleanups --- Diffs of the changes: (+7 -9) Index: llvm/lib/CodeGen/Passes.cpp diff -u llvm/lib/CodeGen/Passes.cpp:1.4 llvm/lib/CodeGen/Passes.cpp:1.5 --- llvm/lib/CodeGen/Passes.cpp:1.4 Wed Nov 19 21:32:25 2003 +++ llvm/lib/CodeGen/Passes.cpp Sun Dec 28 01:59:53 2003 @@ -1,4 +1,4 @@ -//===-- Passes.cpp - Target independent code generation passes -*- C++ -*-===// +//===-- Passes.cpp - Target independent code generation passes ------------===// // // The LLVM Compiler Infrastructure // @@ -14,8 +14,8 @@ #include "llvm/CodeGen/Passes.h" #include "Support/CommandLine.h" - -namespace llvm { +#include +using namespace llvm; namespace { enum RegAllocName { simple, local, linearscan }; @@ -31,19 +31,17 @@ cl::init(local)); } -FunctionPass *createRegisterAllocator() -{ +FunctionPass *llvm::createRegisterAllocator() { switch (RegAlloc) { + default: + std::cerr << "no register allocator selected"; + abort(); case simple: return createSimpleRegisterAllocator(); case local: return createLocalRegisterAllocator(); case linearscan: return createLinearScanRegisterAllocator(); - default: - assert(0 && "no register allocator selected"); - return 0; // not reached } } -} // End llvm namespace From lattner at cs.uiuc.edu Sun Dec 28 02:20:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 02:20:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/IntrinsicLowering.cpp Message-ID: <200312280819.CAA04247@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: IntrinsicLowering.cpp added (r1.1) --- Log message: Implement the default implementation of the intrinsic lowering class --- Diffs of the changes: (+57 -0) Index: llvm/lib/CodeGen/IntrinsicLowering.cpp diff -c /dev/null llvm/lib/CodeGen/IntrinsicLowering.cpp:1.1 *** /dev/null Sun Dec 28 02:19:51 2003 --- llvm/lib/CodeGen/IntrinsicLowering.cpp Sun Dec 28 02:19:41 2003 *************** *** 0 **** --- 1,57 ---- + //===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the default intrinsic lowering implementation. + // + //===----------------------------------------------------------------------===// + + #include "llvm/CodeGen/IntrinsicLowering.h" + #include "llvm/Constant.h" + #include "llvm/Intrinsics.h" + #include "llvm/Module.h" + #include "llvm/Type.h" + #include "llvm/iOther.h" + using namespace llvm; + + void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { + Function *Callee = CI->getCalledFunction(); + assert(Callee && "Cannot lower an indirect call!"); + + Module *M = Callee->getParent(); + + switch (Callee->getIntrinsicID()) { + case Intrinsic::not_intrinsic: + std::cerr << "Cannot lower a call to a non-intrinsic function '" + << Callee->getName() << "'!\n"; + abort(); + default: + std::cerr << "Error: Code generator does not support intrinsic function '" + << Callee->getName() << "'!\n"; + abort(); + + // The default implementation of setjmp/longjmp transforms setjmp into a + // noop that always returns zero and longjmp into a call to abort. This + // allows code that never longjmps to work correctly. + case Intrinsic::setjmp: + case Intrinsic::sigsetjmp: + if (CI->getType() != Type::VoidTy) + CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); + break; + + case Intrinsic::longjmp: + case Intrinsic::siglongjmp: + // Insert the call to abort + new CallInst(M->getOrInsertFunction("abort", Type::VoidTy, 0), "", CI); + break; + } + + assert(CI->use_empty() && + "Lowering should have eliminated any uses of the intrinsic call!"); + CI->getParent()->getInstList().erase(CI); + } From lattner at cs.uiuc.edu Sun Dec 28 02:20:05 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 02:20:05 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/IntrinsicLowering.h Message-ID: <200312280819.CAA04217@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: IntrinsicLowering.h added (r1.1) --- Log message: Add new interface that allows removal of some code from the code generators, provides for future extensibility, might help the LLVA project avoid having to hack their own LLI, and provides support required for the experimental Venus project. --- Diffs of the changes: (+63 -0) Index: llvm/include/llvm/CodeGen/IntrinsicLowering.h diff -c /dev/null llvm/include/llvm/CodeGen/IntrinsicLowering.h:1.1 *** /dev/null Sun Dec 28 02:19:23 2003 --- llvm/include/llvm/CodeGen/IntrinsicLowering.h Sun Dec 28 02:19:13 2003 *************** *** 0 **** --- 1,63 ---- + //===-- llvm/CodeGen/IntrinsicLowering.h - Intrinsic Lowering ---*- 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 defines the IntrinsicLowering interface. This interface allows + // addition of domain-specific or front-end specific intrinsics to LLVM without + // having to modify all of the target-machines to support the new intrinsic. + // Later, as desired, code generators can incrementally add support for + // particular intrinsic functions, as desired, to generate better code. + // + // If a code generator cannot handle or does not know about an intrinsic + // function, it will use the intrinsic lowering interface to change an intrinsic + // function name into a concrete function name which can be used to implement + // the functionality of the intrinsic. For example, llvm.acos can be + // implemented as a call to the math library 'acos' function if the target + // doesn't have hardware support for the intrinsic, or if it has not yet been + // implemented yet. + // + // Another use for this interface is the addition of domain-specific intrinsics. + // The default implementation of this interface would then lower the intrinsics + // to noop calls, allowing the direct execution of programs with instrumentation + // or other hooks placed in them. When a specific tool or flag is used, a + // different implementation of these interfaces may be used, which activates the + // intrinsics in some way. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_CODEGEN_INTRINSICLOWERING_H + #define LLVM_CODEGEN_INTRINSICLOWERING_H + + namespace llvm { + class CallInst; + + struct IntrinsicLowering { + + /// LowerIntrinsicCall - This method returns the LLVM function which should + /// be used to implement the specified intrinsic function call. If an + /// intrinsic function must be implemented by the code generator (such as + /// va_start), this function should print a message and abort. + /// + /// Otherwise, if an intrinsic function call can be lowered, the code to + /// implement it (often a call to a non-intrinsic function) is inserted + /// _after_ the call instruction and the call is deleted. The caller must + /// be capable of handling this kind of change. + /// + virtual void LowerIntrinsicCall(CallInst *CI) = 0; + }; + + /// DefaultIntrinsicLower - This is the default intrinsic lowering pass which + /// is used if no other one is specified. Custom intrinsic lowering + /// implementations should pass any unhandled intrinsics to this + /// implementation to allow for future extensibility. + struct DefaultIntrinsicLowering : public IntrinsicLowering { + virtual void LowerIntrinsicCall(CallInst *CI); + }; + } + + #endif From lattner at cs.uiuc.edu Sun Dec 28 02:31:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 02:31:01 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/IntrinsicLowering.cpp Message-ID: <200312280830.CAA04426@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: IntrinsicLowering.cpp updated: 1.1 -> 1.2 --- Log message: Move into the VMCore library --- Diffs of the changes: (+1 -1) Index: llvm/lib/VMCore/IntrinsicLowering.cpp diff -u llvm/lib/VMCore/IntrinsicLowering.cpp:1.1 llvm/lib/VMCore/IntrinsicLowering.cpp:1.2 --- llvm/lib/VMCore/IntrinsicLowering.cpp:1.1 Sun Dec 28 02:19:41 2003 +++ llvm/lib/VMCore/IntrinsicLowering.cpp Sun Dec 28 02:30:20 2003 @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/IntrinsicLowering.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/Constant.h" #include "llvm/Intrinsics.h" #include "llvm/Module.h" From lattner at cs.uiuc.edu Sun Dec 28 02:31:05 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 02:31:05 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/IntrinsicLowering.h Message-ID: <200312280830.CAA04416@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: IntrinsicLowering.h updated: 1.1 -> 1.2 --- Log message: Move header into top-level llvm dir --- Diffs of the changes: (+3 -3) Index: llvm/include/llvm/IntrinsicLowering.h diff -u llvm/include/llvm/IntrinsicLowering.h:1.1 llvm/include/llvm/IntrinsicLowering.h:1.2 --- llvm/include/llvm/IntrinsicLowering.h:1.1 Sun Dec 28 02:19:13 2003 +++ llvm/include/llvm/IntrinsicLowering.h Sun Dec 28 02:30:07 2003 @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/IntrinsicLowering.h - Intrinsic Lowering ---*- C++ -*-===// +//===-- llvm/IntrinsicLowering.h - Intrinsic Function Lowering --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -30,8 +30,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_INTRINSICLOWERING_H -#define LLVM_CODEGEN_INTRINSICLOWERING_H +#ifndef LLVM_INTRINSICLOWERING_H +#define LLVM_INTRINSICLOWERING_H namespace llvm { class CallInst; From lattner at cs.uiuc.edu Sun Dec 28 02:57:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 02:57:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/IntrinsicLowering.h Message-ID: <200312280856.CAA04613@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: IntrinsicLowering.h updated: 1.2 -> 1.3 --- Log message: ABC's must have virtual dtors! Shame on me! --- Diffs of the changes: (+1 -0) Index: llvm/include/llvm/IntrinsicLowering.h diff -u llvm/include/llvm/IntrinsicLowering.h:1.2 llvm/include/llvm/IntrinsicLowering.h:1.3 --- llvm/include/llvm/IntrinsicLowering.h:1.2 Sun Dec 28 02:30:07 2003 +++ llvm/include/llvm/IntrinsicLowering.h Sun Dec 28 02:55:50 2003 @@ -37,6 +37,7 @@ class CallInst; struct IntrinsicLowering { + virtual ~IntrinsicLowering() {} /// LowerIntrinsicCall - This method returns the LLVM function which should /// be used to implement the specified intrinsic function call. If an From lattner at cs.uiuc.edu Sun Dec 28 03:44:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:44:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp Message-ID: <200312280943.DAA01663@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSelection: InstrSelection.cpp updated: 1.65 -> 1.66 --- Log message: Use the intrinsic lowering functionality --- Diffs of the changes: (+44 -15) Index: llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp diff -u llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.65 llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.66 --- llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.65 Tue Nov 11 16:41:33 2003 +++ llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp Sun Dec 28 03:43:35 2003 @@ -14,11 +14,14 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/InstrSelection.h" #include "llvm/Function.h" +#include "llvm/Intrinsics.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/iPHINode.h" +#include "llvm/iOther.h" #include "llvm/Pass.h" #include "llvm/CodeGen/InstrForest.h" -#include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/InstrSelectionSupport.h" #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineFunction.h" @@ -26,13 +29,12 @@ #include "llvm/Target/TargetRegInfo.h" #include "Support/CommandLine.h" #include "Support/LeakDetector.h" -#include namespace llvm { - -std::vector -FixConstantOperandsForInstr(Instruction* vmInstr, MachineInstr* minstr, - TargetMachine& target); + std::vector + FixConstantOperandsForInstr(Instruction *I, MachineInstr *MI, + TargetMachine &TM); +} namespace { //===--------------------------------------------------------------------===// @@ -66,6 +68,7 @@ // class InstructionSelection : public FunctionPass { TargetMachine &Target; + IntrinsicLowering &IL; void InsertCodeForPhis(Function &F); void InsertPhiElimInstructions(BasicBlock *BB, const std::vector& CpVec); @@ -73,7 +76,8 @@ void PostprocessMachineCodeForTree(InstructionNode* instrNode, int ruleForNode, short* nts); public: - InstructionSelection(TargetMachine &T) : Target(T) {} + InstructionSelection(TargetMachine &TM, IntrinsicLowering &il) + : Target(TM), IL(il) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -84,7 +88,6 @@ }; } -namespace llvm { TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi, Value *s1, Value *s2, const std::string &name) @@ -118,10 +121,37 @@ LeakDetector::removeGarbageObject(this); } -} // End llvm namespace +bool InstructionSelection::runOnFunction(Function &F) { + // First pass - Walk the function, lowering any calls to intrinsic functions + // which the instruction selector cannot handle. + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) + if (CallInst *CI = dyn_cast(I++)) + if (Function *F = CI->getCalledFunction()) + switch (F->getIntrinsicID()) { +#undef va_start +#undef va_copy +#undef va_end + case Intrinsic::va_start: + case Intrinsic::va_copy: + case Intrinsic::va_end: + // We directly implement these intrinsics. Note that this knowledge + // is incestuously entangled with the code in + // SparcInstrSelection.cpp and must be updated when it is updated. + // Since ALL of the code in this library is incestuously intertwined + // with it already and sparc specific, we will live with this. + break; + default: + // All other intrinsic calls we must lower. + Instruction *Before = CI->getPrev(); + IL.LowerIntrinsicCall(CI); + if (Before) { // Move iterator to instruction after call + I = Before; ++I; + } else { + I = BB->begin(); + } + } -bool InstructionSelection::runOnFunction(Function &F) -{ // // Build the instruction trees to be given as inputs to BURG. // @@ -384,8 +414,7 @@ // createInstructionSelectionPass - Public entrypoint for instruction selection // and this file as a whole... // -FunctionPass *createInstructionSelectionPass(TargetMachine &T) { - return new InstructionSelection(T); +FunctionPass *llvm::createInstructionSelectionPass(TargetMachine &T, + IntrinsicLowering &IL) { + return new InstructionSelection(T, IL); } - -} // End llvm namespace From lattner at cs.uiuc.edu Sun Dec 28 03:44:07 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:44:07 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/InstrSelection.h Message-ID: <200312280943.DAA01591@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: InstrSelection.h updated: 1.30 -> 1.31 --- Log message: add argument --- Diffs of the changes: (+6 -4) Index: llvm/include/llvm/CodeGen/InstrSelection.h diff -u llvm/include/llvm/CodeGen/InstrSelection.h:1.30 llvm/include/llvm/CodeGen/InstrSelection.h:1.31 --- llvm/include/llvm/CodeGen/InstrSelection.h:1.30 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/CodeGen/InstrSelection.h Sun Dec 28 03:42:49 2003 @@ -19,12 +19,13 @@ namespace llvm { class Function; +class FunctionPass; class InstrForest; -class MachineInstr; class InstructionNode; -class TargetMachine; +class IntrinsicLowering; class MachineCodeForInstruction; -class FunctionPass; +class MachineInstr; +class TargetMachine; //===--------------------- Required Functions --------------------------------- // Target-dependent functions that MUST be implemented for each target. @@ -50,7 +51,8 @@ // Return a pass that performs machine dependent instruction selection. //--------------------------------------------------------------------------- -FunctionPass *createInstructionSelectionPass(TargetMachine &Target); +FunctionPass *createInstructionSelectionPass(TargetMachine &Target, + IntrinsicLowering &IL); //************************ Exported Data Types *****************************/ From lattner at cs.uiuc.edu Sun Dec 28 03:45:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:45:01 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JIT.h TargetSelect.cpp Message-ID: <200312280944.DAA02149@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JIT.h updated: 1.22 -> 1.23 TargetSelect.cpp updated: 1.1 -> 1.2 --- Log message: Pass around IntrinsicLowering instances as appropriate. Reimplement the Interpreters implementation of va_* to be more direct. --- Diffs of the changes: (+8 -5) Index: llvm/lib/ExecutionEngine/JIT/JIT.h diff -u llvm/lib/ExecutionEngine/JIT/JIT.h:1.22 llvm/lib/ExecutionEngine/JIT/JIT.h:1.23 --- llvm/lib/ExecutionEngine/JIT/JIT.h:1.22 Fri Dec 26 00:13:47 2003 +++ llvm/lib/ExecutionEngine/JIT/JIT.h Sun Dec 28 03:44:37 2003 @@ -44,9 +44,11 @@ ~JIT(); /// create - Create an return a new JIT compiler if there is one available - /// for the current target. Otherwise, return null. + /// for the current target. Otherwise, return null. If the JIT is created + /// successfully, it takes responsibility for deleting the specified + /// IntrinsicLowering implementation. /// - static ExecutionEngine *create(ModuleProvider *MP); + static ExecutionEngine *create(ModuleProvider *MP, IntrinsicLowering *IL = 0); /// run - Start execution with the specified function and arguments. /// Index: llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp diff -u llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.1 llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.2 --- llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.1 Fri Dec 19 19:46:27 2003 +++ llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp Sun Dec 28 03:44:37 2003 @@ -53,8 +53,9 @@ /// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. /// -ExecutionEngine *JIT::create(ModuleProvider *MP) { - TargetMachine* (*TargetMachineAllocator)(const Module &) = 0; +ExecutionEngine *JIT::create(ModuleProvider *MP, IntrinsicLowering *IL) { + TargetMachine* (*TargetMachineAllocator)(const Module &, + IntrinsicLowering *IL) = 0; // Allow a command-line switch to override what *should* be the default target // machine for this platform. This allows for debugging a Sparc JIT on X86 -- @@ -80,7 +81,7 @@ #endif // Allocate a target... - TargetMachine *Target = TargetMachineAllocator(*MP->getModule()); + TargetMachine *Target = TargetMachineAllocator(*MP->getModule(), IL); assert(Target && "Could not allocate target machine!"); // If the target supports JIT code generation, return a new JIT now. From lattner at cs.uiuc.edu Sun Dec 28 03:45:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:45:03 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp ExternalFunctions.cpp Interpreter.cpp Interpreter.h Message-ID: <200312280944.DAA02160@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: Execution.cpp updated: 1.118 -> 1.119 ExternalFunctions.cpp updated: 1.71 -> 1.72 Interpreter.cpp updated: 1.19 -> 1.20 Interpreter.h updated: 1.58 -> 1.59 --- Log message: Pass around IntrinsicLowering instances as appropriate. Reimplement the Interpreters implementation of va_* to be more direct. --- Diffs of the changes: (+58 -41) Index: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.118 llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.119 --- llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.118 Thu Dec 11 23:13:05 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Sun Dec 28 03:44:36 2003 @@ -12,11 +12,12 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "interpreter" - #include "Interpreter.h" -#include "llvm/Instructions.h" -#include "llvm/DerivedTypes.h" #include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/IntrinsicLowering.h" +#include "llvm/Intrinsics.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "Support/Statistic.h" #include "Support/Debug.h" @@ -25,15 +26,15 @@ namespace { Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed"); -} -namespace llvm { Interpreter *TheEE = 0; } + //===----------------------------------------------------------------------===// // Value Manipulation code //===----------------------------------------------------------------------===// + static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, const Type *Ty); static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2, @@ -764,6 +765,36 @@ void Interpreter::visitCallSite(CallSite CS) { ExecutionContext &SF = ECStack.back(); + + // Check to see if this is an intrinsic function call... + if (Function *F = CS.getCalledFunction()) + switch (F->getIntrinsicID()) { + case Intrinsic::va_start: // va_start: implemented by getFirstVarArg() + SetValue(CS.getInstruction(), getFirstVarArg(), SF); + return; + case Intrinsic::va_end: // va_end is a noop for the interpreter + return; + case Intrinsic::va_copy: // va_copy: dest = src + SetValue(CS.getInstruction(), getOperandValue(*CS.arg_begin(), SF), SF); + return; + default: + // If it is an unknown intrinsic function, using the intrinsic lowering + // class to transform it into hopefully tasty LLVM code. + // + Instruction *Prev = CS.getInstruction()->getPrev(); + BasicBlock *Parent = CS.getInstruction()->getParent(); + IL->LowerIntrinsicCall(cast(CS.getInstruction())); + + // Restore the CurInst pointer to the first instruction newly inserted, if + // any. + if (!Prev) { + SF.CurInst = Parent->begin(); + } else { + SF.CurInst = Prev; + ++SF.CurInst; + } + } + SF.Caller = CS; std::vector ArgVals; const unsigned NumArgs = SF.Caller.arg_size(); Index: llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.71 llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.72 --- llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp:1.71 Sun Dec 14 17:25:48 2003 +++ llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp Sun Dec 28 03:44:37 2003 @@ -676,28 +676,6 @@ return GV; } -//===----------------------------------------------------------------------===// -// LLVM Intrinsic Functions... -//===----------------------------------------------------------------------===// - -// llvm.va_start() - Implement the va_start operation... -GenericValue llvm_va_start(FunctionType *F, const vector &Args) { - assert(Args.size() == 0); - return TheInterpreter->getFirstVarArg(); -} - -// void llvm.va_end( *) - Implement the va_end operation... -GenericValue llvm_va_end(FunctionType *F, const vector &Args) { - assert(Args.size() == 1); - return GenericValue(); // Noop! -} - -// llvm.va_copy() - Implement the va_copy operation... -GenericValue llvm_va_copy(FunctionType *F, const vector &Args) { - assert(Args.size() == 1); - return Args[0]; -} - } // End extern "C" @@ -749,9 +727,5 @@ FuncNames["lle_X_ungetc"] = lle_X_ungetc; FuncNames["lle_X_fprintf"] = lle_X_fprintf; FuncNames["lle_X_freopen"] = lle_X_freopen; - - FuncNames["lle_X_llvm.va_start"]= llvm_va_start; - FuncNames["lle_X_llvm.va_end"] = llvm_va_end; - FuncNames["lle_X_llvm.va_copy"] = llvm_va_copy; } Index: llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.19 llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.20 --- llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp:1.19 Fri Dec 26 00:13:05 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp Sun Dec 28 03:44:37 2003 @@ -14,13 +14,14 @@ //===----------------------------------------------------------------------===// #include "Interpreter.h" -#include "llvm/Module.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/DerivedTypes.h" +#include "llvm/Module.h" using namespace llvm; /// create - Create a new interpreter object. This can never fail. /// -ExecutionEngine *Interpreter::create(Module *M){ +ExecutionEngine *Interpreter::create(Module *M, IntrinsicLowering *IL) { bool isLittleEndian = false; switch (M->getEndianness()) { case Module::LittleEndian: isLittleEndian = true; break; @@ -41,22 +42,29 @@ break; } - return new Interpreter(M, isLittleEndian, isLongPointer); + return new Interpreter(M, isLittleEndian, isLongPointer, IL); } //===----------------------------------------------------------------------===// // Interpreter ctor - Initialize stuff // -Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer) - : ExecutionEngine(M), ExitCode(0), +Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer, + IntrinsicLowering *il) + : ExecutionEngine(M), ExitCode(0), TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4, - isLongPointer ? 8 : 4) { + isLongPointer ? 8 : 4), IL(il) { setTargetData(TD); // Initialize the "backend" initializeExecutionEngine(); initializeExternalFunctions(); emitGlobals(); + + if (IL == 0) IL = new DefaultIntrinsicLowering(); +} + +Interpreter::~Interpreter() { + delete IL; } void Interpreter::runAtExitHandlers () { Index: llvm/lib/ExecutionEngine/Interpreter/Interpreter.h diff -u llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.58 llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.59 --- llvm/lib/ExecutionEngine/Interpreter/Interpreter.h:1.58 Fri Dec 26 00:13:05 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Interpreter.h Sun Dec 28 03:44:37 2003 @@ -79,6 +79,7 @@ class Interpreter : public ExecutionEngine, public InstVisitor { int ExitCode; // The exit code to be returned by the lli util TargetData TD; + IntrinsicLowering *IL; // The runtime stack of executing code. The top of the stack is the current // function record. @@ -89,17 +90,20 @@ std::vector AtExitHandlers; public: - Interpreter(Module *M, bool isLittleEndian, bool isLongPointer); - inline ~Interpreter() { } + Interpreter(Module *M, bool isLittleEndian, bool isLongPointer, + IntrinsicLowering *IL); + ~Interpreter(); /// runAtExitHandlers - Run any functions registered by the program's calls to /// atexit(3), which we intercept and store in AtExitHandlers. /// void runAtExitHandlers(); - /// create - Create an interpreter ExecutionEngine. This can never fail. + /// create - Create an interpreter ExecutionEngine. This can never fail. The + /// specified IntrinsicLowering implementation will be deleted when the + /// Interpreter execution engine is destroyed. /// - static ExecutionEngine *create(Module *M); + static ExecutionEngine *create(Module *M, IntrinsicLowering *IL); /// run - Start execution with the specified function and arguments. /// From lattner at cs.uiuc.edu Sun Dec 28 03:45:07 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:45:07 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/ExecutionEngine.cpp Message-ID: <200312280944.DAA02131@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine: ExecutionEngine.cpp updated: 1.43 -> 1.44 --- Log message: Pass around IntrinsicLowering instances as appropriate. Reimplement the Interpreters implementation of va_* to be more direct. --- Diffs of the changes: (+8 -4) Index: llvm/lib/ExecutionEngine/ExecutionEngine.cpp diff -u llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.43 llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.44 --- llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.43 Fri Dec 26 00:50:30 2003 +++ llvm/lib/ExecutionEngine/ExecutionEngine.cpp Sun Dec 28 03:44:36 2003 @@ -17,6 +17,7 @@ #include "JIT/JIT.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" @@ -105,20 +106,23 @@ /// NULL is returned. /// ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP, - bool ForceInterpreter) { + bool ForceInterpreter, + IntrinsicLowering *IL) { ExecutionEngine *EE = 0; - // Unless the interpreter was explicitly selected, make a JIT. + // Unless the interpreter was explicitly selected, try making a JIT. if (!ForceInterpreter) - EE = JIT::create(MP); + EE = JIT::create(MP, IL); // If we can't make a JIT, make an interpreter instead. try { if (EE == 0) - EE = Interpreter::create(MP->materializeModule()); + EE = Interpreter::create(MP->materializeModule(), IL); } catch (...) { EE = 0; } + + if (EE == 0) delete IL; return EE; } From lattner at cs.uiuc.edu Sun Dec 28 03:47:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:47:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcInstrSelection.cpp SparcJITInfo.h SparcTargetMachine.cpp SparcTargetMachine.h Message-ID: <200312280946.DAA02779@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcInstrSelection.cpp updated: 1.128 -> 1.129 SparcJITInfo.h updated: 1.1 -> 1.2 SparcTargetMachine.cpp updated: 1.95 -> 1.96 SparcTargetMachine.h updated: 1.2 -> 1.3 --- Log message: Eliminate some code that is not needed now that we have the intrinsic lowering pass --- Diffs of the changes: (+30 -58) Index: llvm/lib/Target/Sparc/SparcInstrSelection.cpp diff -u llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.128 llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.129 --- llvm/lib/Target/Sparc/SparcInstrSelection.cpp:1.128 Wed Dec 17 16:04:00 2003 +++ llvm/lib/Target/Sparc/SparcInstrSelection.cpp Sun Dec 28 03:46:33 2003 @@ -1393,11 +1393,12 @@ // instead of a regular call. If not that kind of intrinsic, do nothing. // Returns true if code was generated, otherwise false. // -bool CodeGenIntrinsic(Intrinsic::ID iid, CallInst &callInstr, - TargetMachine &target, - std::vector& mvec) -{ +static bool CodeGenIntrinsic(Intrinsic::ID iid, CallInst &callInstr, + TargetMachine &target, + std::vector& mvec) { switch (iid) { + default: + assert(0 && "Unknown intrinsic function call should have been lowered!"); case Intrinsic::va_start: { // Get the address of the first incoming vararg argument on the stack bool ignore; @@ -1422,47 +1423,6 @@ addReg(callInstr.getOperand(1)). addRegDef(&callInstr)); return true; - - case Intrinsic::sigsetjmp: - case Intrinsic::setjmp: { - // act as if we return 0 - unsigned g0 = target.getRegInfo().getZeroRegNum(); - mvec.push_back(BuildMI(V9::ORr,3).addMReg(g0).addMReg(g0) - .addReg(&callInstr, MOTy::Def)); - return true; - } - - case Intrinsic::siglongjmp: - case Intrinsic::longjmp: { - // call abort() - Module* M = callInstr.getParent()->getParent()->getParent(); - const FunctionType *voidvoidFuncTy = - FunctionType::get(Type::VoidTy, std::vector(), false); - Function *F = M->getOrInsertFunction("abort", voidvoidFuncTy); - assert(F && "Unable to get or create `abort' function declaration"); - - // Create hidden virtual register for return address with type void* - TmpInstruction* retAddrReg = - new TmpInstruction(MachineCodeForInstruction::get(&callInstr), - PointerType::get(Type::VoidTy), &callInstr); - - // Use a descriptor to pass information about call arguments - // to the register allocator. This descriptor will be "owned" - // and freed automatically when the MachineCodeForInstruction - // object for the callInstr goes away. - CallArgsDescriptor* argDesc = - new CallArgsDescriptor(&callInstr, retAddrReg, false, false); - - MachineInstr* callMI = BuildMI(V9::CALL, 1).addPCDisp(F); - callMI->addImplicitRef(retAddrReg, /*isDef*/ true); - - mvec.push_back(callMI); - mvec.push_back(BuildMI(V9::NOP, 0)); - return true; - } - - default: - return false; } } Index: llvm/lib/Target/Sparc/SparcJITInfo.h diff -u llvm/lib/Target/Sparc/SparcJITInfo.h:1.1 llvm/lib/Target/Sparc/SparcJITInfo.h:1.2 --- llvm/lib/Target/Sparc/SparcJITInfo.h:1.1 Fri Dec 19 19:21:59 2003 +++ llvm/lib/Target/Sparc/SparcJITInfo.h Sun Dec 28 03:46:33 2003 @@ -18,10 +18,13 @@ namespace llvm { class TargetMachine; + class IntrinsicLowering; + class SparcJITInfo : public TargetJITInfo { TargetMachine &TM; + IntrinsicLowering &IL; public: - SparcJITInfo(TargetMachine &tm) : TM(tm) {} + SparcJITInfo(TargetMachine &tm, IntrinsicLowering &il) : TM(tm), IL(il) {} /// addPassesToJITCompile - Add passes to the specified pass manager to /// implement a fast dynamic compiler for this target. Return true if this Index: llvm/lib/Target/Sparc/SparcTargetMachine.cpp diff -u llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.95 llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.96 --- llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.95 Sun Dec 21 21:47:58 2003 +++ llvm/lib/Target/Sparc/SparcTargetMachine.cpp Sun Dec 28 03:46:33 2003 @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Function.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/PassManager.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/CodeGen/InstrSelection.h" @@ -114,13 +115,18 @@ } -SparcTargetMachine::SparcTargetMachine() +SparcTargetMachine::SparcTargetMachine(IntrinsicLowering *il) : TargetMachine("UltraSparc-Native", false), + IL(il ? il : new DefaultIntrinsicLowering()), schedInfo(*this), regInfo(*this), frameInfo(*this), cacheInfo(*this), - jitInfo(*this) { + jitInfo(*this, *IL) { +} + +SparcTargetMachine::~SparcTargetMachine() { + delete IL; } // addPassesToEmitAssembly - This method controls the entire code generation @@ -165,7 +171,7 @@ PM.add(new PrintFunctionPass("Input code to instr. selection:\n", &std::cerr)); - PM.add(createInstructionSelectionPass(*this)); + PM.add(createInstructionSelectionPass(*this, *IL)); if (!DisableSched) PM.add(createInstructionSchedulingWithSSAPass(*this)); @@ -187,7 +193,7 @@ // function has been emitted. // PM.add(createAsmPrinterPass(Out, *this)); - PM.add(createSparcMachineCodeDestructionPass()); // Free stuff no longer needed + PM.add(createSparcMachineCodeDestructionPass()); // Free mem no longer needed // Emit bytecode to the assembly file into its special section next if (EmitMappingInfo) @@ -232,7 +238,7 @@ //PM.add(createLICMPass()); //PM.add(createGCSEPass()); - PM.add(createInstructionSelectionPass(TM)); + PM.add(createInstructionSelectionPass(TM, IL)); PM.add(getRegisterAllocator(TM)); PM.add(createPrologEpilogInsertionPass()); @@ -246,6 +252,7 @@ // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface) //---------------------------------------------------------------------------- -TargetMachine *llvm::allocateSparcTargetMachine(const Module &M) { - return new SparcTargetMachine(); +TargetMachine *llvm::allocateSparcTargetMachine(const Module &M, + IntrinsicLowering *IL) { + return new SparcTargetMachine(IL); } Index: llvm/lib/Target/Sparc/SparcTargetMachine.h diff -u llvm/lib/Target/Sparc/SparcTargetMachine.h:1.2 llvm/lib/Target/Sparc/SparcTargetMachine.h:1.3 --- llvm/lib/Target/Sparc/SparcTargetMachine.h:1.2 Fri Dec 19 19:21:59 2003 +++ llvm/lib/Target/Sparc/SparcTargetMachine.h Sun Dec 28 03:46:33 2003 @@ -7,15 +7,13 @@ // //===----------------------------------------------------------------------===// // -// This file declares the primary interface to machine description for the -// UltraSPARC. +// This file declares the top-level UltraSPARC target machine. // //===----------------------------------------------------------------------===// #ifndef SPARC_TARGETMACHINE_H #define SPARC_TARGETMACHINE_H -#include "llvm/PassManager.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetMachine.h" #include "SparcInstrInfo.h" @@ -25,8 +23,11 @@ #include "SparcJITInfo.h" namespace llvm { + class PassManager; + class IntrinsicLowering; class SparcTargetMachine : public TargetMachine { + IntrinsicLowering *IL; SparcInstrInfo instrInfo; SparcSchedInfo schedInfo; SparcRegInfo regInfo; @@ -34,8 +35,9 @@ SparcCacheInfo cacheInfo; SparcJITInfo jitInfo; public: - SparcTargetMachine(); - + SparcTargetMachine(IntrinsicLowering *IL); + ~SparcTargetMachine(); + virtual const TargetInstrInfo &getInstrInfo() const { return instrInfo; } virtual const TargetSchedInfo &getSchedInfo() const { return schedInfo; } virtual const TargetRegInfo &getRegInfo() const { return regInfo; } From lattner at cs.uiuc.edu Sun Dec 28 03:48:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:48:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectPattern.cpp InstSelectSimple.cpp X86.h X86JITInfo.h X86TargetMachine.cpp X86TargetMachine.h Message-ID: <200312280947.DAA03305@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectPattern.cpp updated: 1.5 -> 1.6 InstSelectSimple.cpp updated: 1.145 -> 1.146 X86.h updated: 1.23 -> 1.24 X86JITInfo.h updated: 1.1 -> 1.2 X86TargetMachine.cpp updated: 1.42 -> 1.43 X86TargetMachine.h updated: 1.19 -> 1.20 --- Log message: implement support for the intrinsic lowering functionality --- Diffs of the changes: (+78 -36) Index: llvm/lib/Target/X86/InstSelectPattern.cpp diff -u llvm/lib/Target/X86/InstSelectPattern.cpp:1.5 llvm/lib/Target/X86/InstSelectPattern.cpp:1.6 --- llvm/lib/Target/X86/InstSelectPattern.cpp:1.5 Tue Nov 11 16:41:33 2003 +++ llvm/lib/Target/X86/InstSelectPattern.cpp Sun Dec 28 03:47:19 2003 @@ -27,8 +27,7 @@ // Include the generated instruction selector... #include "X86GenInstrSelector.inc" - -namespace llvm { +using namespace llvm; namespace { struct ISel : public FunctionPass, SelectionDAGTargetBuilder { @@ -120,8 +119,7 @@ /// into a machine code representation using pattern matching and a machine /// description file. /// -FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM) { +FunctionPass *llvm::createX86PatternInstructionSelector(TargetMachine &TM, + IntrinsicLowering &IL) { return new ISel(TM); } - -} // End llvm namespace Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.145 llvm/lib/Target/X86/InstSelectSimple.cpp:1.146 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.145 Sun Dec 21 10:47:43 2003 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Sun Dec 28 03:47:19 2003 @@ -19,6 +19,7 @@ #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/Pass.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -28,8 +29,7 @@ #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/InstVisitor.h" - -namespace llvm { +using namespace llvm; /// BMI - A special BuildMI variant that takes an iterator to insert the /// instruction at as well as a basic block. This is the version for when you @@ -59,6 +59,7 @@ namespace { struct ISel : public FunctionPass, InstVisitor { TargetMachine &TM; + IntrinsicLowering &IL; MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling int VarArgsFrameIndex; // FrameIndex for start of varargs area @@ -68,12 +69,17 @@ // MBBMap - Mapping between LLVM BB -> Machine BB std::map MBBMap; - ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {} + ISel(TargetMachine &tm, IntrinsicLowering &il) + : TM(tm), IL(il), F(0), BB(0) {} /// runOnFunction - Top level implementation of instruction selection for /// the entire function. /// bool runOnFunction(Function &Fn) { + // First pass over the function, lower any unknown intrinsic functions + // with the IntrinsicLowering class. + LowerUnknownIntrinsicFunctionCalls(Fn); + F = &MachineFunction::construct(&Fn, TM); // Create all of the machine basic blocks for the function... @@ -111,6 +117,11 @@ BB = MBBMap[&LLVM_BB]; } + /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the + /// function, lowering any calls to unknown intrinsic functions into the + /// equivalent LLVM code. + void LowerUnknownIntrinsicFunctionCalls(Function &F); + /// LoadArgumentsToVirtualRegs - Load all of the arguments to this function /// from the stack into virtual registers. /// @@ -1087,6 +1098,33 @@ } +/// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the +/// function, lowering any calls to unknown intrinsic functions into the +/// equivalent LLVM code. +void ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) { + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) + if (CallInst *CI = dyn_cast(I++)) + if (Function *F = CI->getCalledFunction()) + switch (F->getIntrinsicID()) { + case Intrinsic::va_start: + case Intrinsic::va_copy: + case Intrinsic::va_end: + // We directly implement these intrinsics + break; + default: + // All other intrinsic calls we must lower. + Instruction *Before = CI->getPrev(); + IL.LowerIntrinsicCall(CI); + if (Before) { // Move iterator to instruction after call + I = Before; ++I; + } else { + I = BB->begin(); + } + } + +} + void ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { unsigned TmpReg1, TmpReg2; switch (ID) { @@ -1103,17 +1141,7 @@ return; case Intrinsic::va_end: return; // Noop on X86 - case Intrinsic::longjmp: - case Intrinsic::siglongjmp: - BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("abort", true); - return; - - case Intrinsic::setjmp: - case Intrinsic::sigsetjmp: - // Setjmp always returns zero... - BuildMI(BB, X86::MOVir32, 1, getReg(CI)).addZImm(0); - return; - default: assert(0 && "Unknown intrinsic for X86!"); + default: assert(0 && "Error: unknown intrinsics should have been lowered!"); } } @@ -2167,8 +2195,7 @@ /// into a machine code representation is a very simple peep-hole fashion. The /// generated code sucks but the implementation is nice and simple. /// -FunctionPass *createX86SimpleInstructionSelector(TargetMachine &TM) { - return new ISel(TM); +FunctionPass *llvm::createX86SimpleInstructionSelector(TargetMachine &TM, + IntrinsicLowering &IL) { + return new ISel(TM, IL); } - -} // End llvm namespace Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.23 llvm/lib/Target/X86/X86.h:1.24 --- llvm/lib/Target/X86/X86.h:1.23 Fri Dec 12 23:36:21 2003 +++ llvm/lib/Target/X86/X86.h Sun Dec 28 03:47:19 2003 @@ -21,18 +21,21 @@ class TargetMachine; class FunctionPass; +class IntrinsicLowering; /// createX86SimpleInstructionSelector - This pass converts an LLVM function /// into a machine code representation in a very simple peep-hole fashion. The /// generated code sucks but the implementation is nice and simple. /// -FunctionPass *createX86SimpleInstructionSelector(TargetMachine &TM); +FunctionPass *createX86SimpleInstructionSelector(TargetMachine &TM, + IntrinsicLowering &IL); /// createX86PatternInstructionSelector - This pass converts an LLVM function /// into a machine code representation using pattern matching and a machine /// description file. /// -FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM); +FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM, + IntrinsicLowering &IL); /// createX86SSAPeepholeOptimizerPass - Create a pass to perform SSA-based X86 /// specific peephole optimizations. Index: llvm/lib/Target/X86/X86JITInfo.h diff -u llvm/lib/Target/X86/X86JITInfo.h:1.1 llvm/lib/Target/X86/X86JITInfo.h:1.2 --- llvm/lib/Target/X86/X86JITInfo.h:1.1 Fri Dec 19 19:22:04 2003 +++ llvm/lib/Target/X86/X86JITInfo.h Sun Dec 28 03:47:19 2003 @@ -18,10 +18,13 @@ namespace llvm { class TargetMachine; + class IntrinsicLowering; + class X86JITInfo : public TargetJITInfo { TargetMachine &TM; + IntrinsicLowering &IL; public: - X86JITInfo(TargetMachine &tm) : TM(tm) {} + X86JITInfo(TargetMachine &tm, IntrinsicLowering &il) : TM(tm), IL(il) {} /// addPassesToJITCompile - Add passes to the specified pass manager to /// implement a fast dynamic compiler for this target. Return true if this Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.42 llvm/lib/Target/X86/X86TargetMachine.cpp:1.43 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.42 Sat Dec 20 10:22:59 2003 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Sun Dec 28 03:47:19 2003 @@ -13,6 +13,7 @@ #include "X86TargetMachine.h" #include "X86.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Target/TargetMachineImpls.h" @@ -29,23 +30,30 @@ cl::opt NoPatternISel("disable-pattern-isel", cl::init(true), cl::desc("Use the 'simple' X86 instruction selector")); cl::opt NoSSAPeephole("disable-ssa-peephole", cl::init(true), - cl::desc("Disable the ssa-based peephole optimizer (defaults to disabled)")); + cl::desc("Disable the ssa-based peephole optimizer " + "(defaults to disabled)")); } // allocateX86TargetMachine - Allocate and return a subclass of TargetMachine // that implements the X86 backend. // -TargetMachine *llvm::allocateX86TargetMachine(const Module &M) { - return new X86TargetMachine(M); +TargetMachine *llvm::allocateX86TargetMachine(const Module &M, + IntrinsicLowering *IL) { + return new X86TargetMachine(M, IL); } /// X86TargetMachine ctor - Create an ILP32 architecture model /// -X86TargetMachine::X86TargetMachine(const Module &M) +X86TargetMachine::X86TargetMachine(const Module &M, IntrinsicLowering *il) : TargetMachine("X86", true, 4, 4, 4, 4, 4), + IL(il ? il : new DefaultIntrinsicLowering()), FrameInfo(TargetFrameInfo::StackGrowsDown, 8/*16 for SSE*/, 4), - JITInfo(*this) { + JITInfo(*this, *IL) { +} + +X86TargetMachine::~X86TargetMachine() { + delete IL; } @@ -64,9 +72,9 @@ PM.add(createCFGSimplificationPass()); if (NoPatternISel) - PM.add(createX86SimpleInstructionSelector(*this)); + PM.add(createX86SimpleInstructionSelector(*this, *IL)); else - PM.add(createX86PatternInstructionSelector(*this)); + PM.add(createX86PatternInstructionSelector(*this, *IL)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) @@ -119,9 +127,9 @@ PM.add(createCFGSimplificationPass()); if (NoPatternISel) - PM.add(createX86SimpleInstructionSelector(TM)); + PM.add(createX86SimpleInstructionSelector(TM, IL)); else - PM.add(createX86PatternInstructionSelector(TM)); + PM.add(createX86PatternInstructionSelector(TM, IL)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.19 llvm/lib/Target/X86/X86TargetMachine.h:1.20 --- llvm/lib/Target/X86/X86TargetMachine.h:1.19 Fri Dec 19 19:22:04 2003 +++ llvm/lib/Target/X86/X86TargetMachine.h Sun Dec 28 03:47:19 2003 @@ -21,13 +21,16 @@ #include "X86JITInfo.h" namespace llvm { +class IntrinsicLowering; class X86TargetMachine : public TargetMachine { + IntrinsicLowering *IL; X86InstrInfo InstrInfo; TargetFrameInfo FrameInfo; X86JITInfo JITInfo; public: - X86TargetMachine(const Module &M); + X86TargetMachine(const Module &M, IntrinsicLowering *IL); + ~X86TargetMachine(); virtual const X86InstrInfo &getInstrInfo() const { return InstrInfo; } virtual const TargetFrameInfo &getFrameInfo() const { return FrameInfo; } From lattner at cs.uiuc.edu Sun Dec 28 03:49:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:49:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Message-ID: <200312280948.DAA03957@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ExecutionEngine: ExecutionEngine.h updated: 1.24 -> 1.25 --- Log message: We may now pass IntrinsicLowering implementations into these methods --- Diffs of the changes: (+5 -2) Index: llvm/include/llvm/ExecutionEngine/ExecutionEngine.h diff -u llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.24 llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.25 --- llvm/include/llvm/ExecutionEngine/ExecutionEngine.h:1.24 Fri Dec 26 00:50:15 2003 +++ llvm/include/llvm/ExecutionEngine/ExecutionEngine.h Sun Dec 28 03:48:17 2003 @@ -30,6 +30,7 @@ class ModuleProvider; class TargetData; class Type; +class IntrinsicLowering; class ExecutionEngine { Module &CurMod; @@ -54,8 +55,10 @@ const TargetData &getTargetData() const { return *TD; } /// create - This is the factory method for creating an execution engine which - /// is appropriate for the current machine. - static ExecutionEngine *create(ModuleProvider *MP, bool ForceInterpreter); + /// is appropriate for the current machine. If specified, the + /// IntrinsicLowering implementation should be allocated on the heap. + static ExecutionEngine *create(ModuleProvider *MP, bool ForceInterpreter, + IntrinsicLowering *IL = 0); /// runFunction - Execute the specified function with the specified arguments, /// and return the result. From lattner at cs.uiuc.edu Sun Dec 28 03:49:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:49:04 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachineImpls.h Message-ID: <200312280948.DAA03962@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachineImpls.h updated: 1.7 -> 1.8 --- Log message: We may now pass IntrinsicLowering implementations into these methods --- Diffs of the changes: (+19 -15) Index: llvm/include/llvm/Target/TargetMachineImpls.h diff -u llvm/include/llvm/Target/TargetMachineImpls.h:1.7 llvm/include/llvm/Target/TargetMachineImpls.h:1.8 --- llvm/include/llvm/Target/TargetMachineImpls.h:1.7 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Target/TargetMachineImpls.h Sun Dec 28 03:48:17 2003 @@ -17,21 +17,25 @@ namespace llvm { -class TargetMachine; -class Module; - -// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine -// that implements the Sparc backend. -// -TargetMachine *allocateSparcTargetMachine(const Module &M); - -// allocateX86TargetMachine - Allocate and return a subclass of TargetMachine -// that implements the X86 backend. The X86 target machine can run in -// "emulation" mode, where it is capable of emulating machines of larger pointer -// size and different endianness if desired. -// -TargetMachine *allocateX86TargetMachine(const Module &M); - + class TargetMachine; + class Module; + class IntrinsicLowering; + + // allocateSparcTargetMachine - Allocate and return a subclass of + // TargetMachine that implements the Sparc backend. This takes ownership of + // the IntrinsicLowering pointer, deleting it when the target machine is + // destroyed. + // + TargetMachine *allocateSparcTargetMachine(const Module &M, + IntrinsicLowering *IL = 0); + + // allocateX86TargetMachine - Allocate and return a subclass of TargetMachine + // that implements the X86 backend. This takes ownership of the + // IntrinsicLowering pointer, deleting it when the target machine is + // destroyed. + // + TargetMachine *allocateX86TargetMachine(const Module &M, + IntrinsicLowering *IL = 0); } // End llvm namespace #endif From lattner at cs.uiuc.edu Sun Dec 28 03:52:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:52:01 2003 Subject: [llvm-commits] CVS: llvm/tools/lli/lli.cpp Message-ID: <200312280951.DAA06650@zion.cs.uiuc.edu> Changes in directory llvm/tools/lli: lli.cpp updated: 1.40 -> 1.41 --- Log message: Pass extra arguments around n stuph --- Diffs of the changes: (+1 -2) Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.40 llvm/tools/lli/lli.cpp:1.41 --- llvm/tools/lli/lli.cpp:1.40 Fri Dec 26 00:49:53 2003 +++ llvm/tools/lli/lli.cpp Sun Dec 28 03:51:04 2003 @@ -57,8 +57,7 @@ exit(1); } - ExecutionEngine *EE = - ExecutionEngine::create(MP, ForceInterpreter); + ExecutionEngine *EE = ExecutionEngine::create(MP, ForceInterpreter); assert(EE && "Couldn't create an ExecutionEngine, not even an interpreter?"); // If the user specifically requested an argv[0] to pass into the program, do From lattner at cs.uiuc.edu Sun Dec 28 03:52:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:52:04 2003 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200312280951.DAA06649@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.87 -> 1.88 --- Log message: Pass extra arguments around n stuph --- Diffs of the changes: (+3 -2) Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.87 llvm/tools/llc/llc.cpp:1.88 --- llvm/tools/llc/llc.cpp:1.87 Tue Nov 11 16:41:34 2003 +++ llvm/tools/llc/llc.cpp Sun Dec 28 03:51:04 2003 @@ -78,7 +78,8 @@ // Allocate target machine. First, check whether the user has // explicitly specified an architecture to compile for. - TargetMachine* (*TargetMachineAllocator)(const Module&) = 0; + TargetMachine* (*TargetMachineAllocator)(const Module&, + IntrinsicLowering *) = 0; switch (Arch) { case x86: TargetMachineAllocator = allocateX86TargetMachine; @@ -112,7 +113,7 @@ } break; } - std::auto_ptr target(TargetMachineAllocator(mod)); + std::auto_ptr target(TargetMachineAllocator(mod, 0)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); const TargetData &TD = Target.getTargetData(); From lattner at cs.uiuc.edu Sun Dec 28 03:54:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:54:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp Message-ID: <200312280953.DAA07729@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSelection: InstrSelection.cpp updated: 1.66 -> 1.67 --- Log message: Whoops, don't try to lower non intrinsic calls --- Diffs of the changes: (+1 -0) Index: llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp diff -u llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.66 llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.67 --- llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.66 Sun Dec 28 03:43:35 2003 +++ llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp Sun Dec 28 03:53:23 2003 @@ -132,6 +132,7 @@ #undef va_start #undef va_copy #undef va_end + case Intrinsic::not_intrinsic: case Intrinsic::va_start: case Intrinsic::va_copy: case Intrinsic::va_end: From lattner at cs.uiuc.edu Sun Dec 28 03:54:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 03:54:04 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200312280953.DAA07726@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.146 -> 1.147 --- Log message: Whoops, don't try to lower non intrinsic calls --- Diffs of the changes: (+1 -0) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.146 llvm/lib/Target/X86/InstSelectSimple.cpp:1.147 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.146 Sun Dec 28 03:47:19 2003 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Sun Dec 28 03:53:23 2003 @@ -1107,6 +1107,7 @@ if (CallInst *CI = dyn_cast(I++)) if (Function *F = CI->getCalledFunction()) switch (F->getIntrinsicID()) { + case Intrinsic::not_intrinsic: case Intrinsic::va_start: case Intrinsic::va_copy: case Intrinsic::va_end: From alkis at cs.uiuc.edu Sun Dec 28 11:36:01 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Dec 28 11:36:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h Message-ID: <200312281735.LAA20745@kain.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.52 -> 1.53 --- Log message: Add TargetInstrInfo::isMoveInstr() to support coalescing in register allocation. --- Diffs of the changes: (+10 -0) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.52 llvm/include/llvm/Target/TargetInstrInfo.h:1.53 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.52 Tue Nov 11 16:41:31 2003 +++ llvm/include/llvm/Target/TargetInstrInfo.h Sun Dec 28 11:35:08 2003 @@ -214,6 +214,16 @@ return get(Opcode).Flags & M_TERMINATOR_FLAG; } + // + // Return true if the instruction is a register to register move and + // leave the source and dest operands in the passed parameters. + // + virtual bool isMoveInstr(const MachineInstr& MI, + unsigned& sourceReg, + unsigned& destReg) const { + return false; + } + // Check if an instruction can be issued before its operands are ready, // or if a subsequent instruction that uses its result can be issued // before the results are ready. From alkis at cs.uiuc.edu Sun Dec 28 11:36:05 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Dec 28 11:36:05 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.h X86InstrInfo.cpp Message-ID: <200312281735.LAA20743@kain.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.h updated: 1.29 -> 1.30 X86InstrInfo.cpp updated: 1.17 -> 1.18 --- Log message: Add TargetInstrInfo::isMoveInstr() to support coalescing in register allocation. --- Diffs of the changes: (+23 -0) Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.29 llvm/lib/Target/X86/X86InstrInfo.h:1.30 --- llvm/lib/Target/X86/X86InstrInfo.h:1.29 Fri Dec 19 19:22:04 2003 +++ llvm/lib/Target/X86/X86InstrInfo.h Sun Dec 28 11:35:07 2003 @@ -169,6 +169,14 @@ /// MachineInstr* createNOPinstr() const; + // + // Return true if the instruction is a register to register move and + // leave the source and dest operands in the passed parameters. + // + virtual bool isMoveInstr(const MachineInstr& MI, + unsigned& sourceReg, + unsigned& destReg) const; + /// isNOPinstr - not having a special NOP opcode, we need to know if a given /// instruction is interpreted as an `official' NOP instr, i.e., there may be /// more than one way to `do nothing' but only one canonical way to slack off. Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.17 llvm/lib/Target/X86/X86InstrInfo.cpp:1.18 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.17 Tue Nov 11 16:41:33 2003 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Sun Dec 28 11:35:07 2003 @@ -51,3 +51,18 @@ return false; } +bool X86InstrInfo::isMoveInstr(const MachineInstr& MI, + unsigned& sourceReg, + unsigned& destReg) const { + MachineOpCode oc = MI.getOpcode(); + if (oc == X86::MOVrr8 || oc == X86::MOVrr16 || oc == X86::MOVrr32) { + assert(MI.getNumOperands() == 2 && + MI.getOperand(0).isRegister() && + MI.getOperand(1).isRegister() && + "invalid register-register move instruction"); + sourceReg = MI.getOperand(1).getAllocatedRegNum(); + destReg = MI.getOperand(0).getAllocatedRegNum(); + return true; + } + return false; +} From alkis at cs.uiuc.edu Sun Dec 28 11:59:01 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Dec 28 11:59:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp LiveIntervals.cpp Message-ID: <200312281758.LAA20893@kain.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.19 -> 1.20 LiveIntervals.cpp updated: 1.16 -> 1.17 --- Log message: Add coalescing to register allocator. A hint is added to each interval which denotes the register we would like to be assigned to (virtual or physical). In register allocation, if this hint exists and we can map it to a physical register (it is either a physical register or it is a virtual register that already got assigned to a physical one) we use that register if it is available instead of a random one in the free pool. --- Diffs of the changes: (+29 -2) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.19 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.20 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.19 Wed Dec 24 12:53:31 2003 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Sun Dec 28 11:58:18 2003 @@ -615,8 +615,19 @@ unsigned RA::getFreePhysReg(Intervals::const_iterator cur) { DEBUG(std::cerr << "\t\tgetting free physical register: "); - const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); + + if (unsigned reg = cur->hint) { + if (reg >= MRegisterInfo::FirstVirtualRegister && + v2pMap_.find(reg) != v2pMap_.end()) + reg = v2pMap_[reg]; + if (reg && reg < MRegisterInfo::FirstVirtualRegister && + mri_->getRegClass(reg) == rc && !regUse_[reg]) { + DEBUG(std::cerr << mri_->getName(reg) << '\n'); + return reg; + } + } + for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); i != rc->allocation_order_end(*mf_); ++i) { unsigned reg = *i; Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.16 llvm/lib/CodeGen/LiveIntervals.cpp:1.17 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.16 Wed Dec 24 09:44:53 2003 +++ llvm/lib/CodeGen/LiveIntervals.cpp Sun Dec 28 11:58:18 2003 @@ -108,6 +108,7 @@ // compute spill weights const LoopInfo& loopInfo = getAnalysis(); + const TargetInstrInfo& tii = tm_->getInstrInfo(); for (MbbIndex2MbbMap::iterator it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end(); @@ -130,6 +131,21 @@ assert(r2iit != r2iMap_.end()); intervals_[r2iit->second].weight += pow(10.0F, loopDepth); } + + // add hints for coalescing + unsigned src, dst; + if (tii.isMoveInstr(*instr, src, dst)) { + if (src >= MRegisterInfo::FirstVirtualRegister) { + Reg2IntervalMap::iterator r2iit = r2iMap_.find(src); + assert(r2iit != r2iMap_.end()); + intervals_[r2iit->second].hint = dst; + } + if (dst >= MRegisterInfo::FirstVirtualRegister) { + Reg2IntervalMap::iterator r2iit = r2iMap_.find(dst); + assert(r2iit != r2iMap_.end()); + intervals_[r2iit->second].hint = src; + } + } } } @@ -329,7 +345,7 @@ } LiveIntervals::Interval::Interval(unsigned r) - : reg(r), + : reg(r), hint(0), weight((r < MRegisterInfo::FirstVirtualRegister ? std::numeric_limits::max() : 0.0F)) { From alkis at cs.uiuc.edu Sun Dec 28 11:59:05 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Dec 28 11:59:05 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/LiveIntervals.h Message-ID: <200312281758.LAA20895@kain.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveIntervals.h updated: 1.7 -> 1.8 --- Log message: Add coalescing to register allocator. A hint is added to each interval which denotes the register we would like to be assigned to (virtual or physical). In register allocation, if this hint exists and we can map it to a physical register (it is either a physical register or it is a virtual register that already got assigned to a physical one) we use that register if it is available instead of a random one in the free pool. --- Diffs of the changes: (+1 -0) Index: llvm/include/llvm/CodeGen/LiveIntervals.h diff -u llvm/include/llvm/CodeGen/LiveIntervals.h:1.7 llvm/include/llvm/CodeGen/LiveIntervals.h:1.8 --- llvm/include/llvm/CodeGen/LiveIntervals.h:1.7 Sun Dec 21 14:19:10 2003 +++ llvm/include/llvm/CodeGen/LiveIntervals.h Sun Dec 28 11:58:18 2003 @@ -38,6 +38,7 @@ typedef std::pair Range; typedef std::vector Ranges; unsigned reg; // the register of this interval + unsigned hint; float weight; // weight of this interval (number of uses // * 10^loopDepth) Ranges ranges; // the ranges this register is valid From alkis at cs.uiuc.edu Sun Dec 28 12:05:00 2003 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sun Dec 28 12:05:00 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp Message-ID: <200312281804.MAA20948@kain.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocLinearScan.cpp updated: 1.20 -> 1.21 --- Log message: Reserve ECX and EDI instead of EBX and EDI. Since EBX is a callee saved register it has a longer free range than ECX (which is defined every time there is a fnuction call) which makes ECX a better register to reserve. --- Diffs of the changes: (+8 -8) Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.20 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.21 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.20 Sun Dec 28 11:58:18 2003 +++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Sun Dec 28 12:03:52 2003 @@ -238,17 +238,17 @@ // aliasing) number of temp registers to reserve so that we have 2 // registers for each register class available. - // reserve R32: EDI, EBX, - // R16: DI, BX, - // R8: BH, BL + // reserve R8: CH, CL + // R16: CX, DI, + // R32: ECX, EDI, // RFP: FP5, FP6 reserved_.assign(MRegisterInfo::FirstVirtualRegister, false); - reserved_[19] = true; /* EDI */ - reserved_[17] = true; /* EBX */ + reserved_[ 8] = true; /* CH */ + reserved_[ 9] = true; /* CL */ + reserved_[10] = true; /* CX */ reserved_[12] = true; /* DI */ - reserved_[ 7] = true; /* BX */ - reserved_[ 4] = true; /* BH */ - reserved_[ 5] = true; /* BL */ + reserved_[18] = true; /* ECX */ + reserved_[19] = true; /* EDI */ reserved_[28] = true; /* FP5 */ reserved_[29] = true; /* FP6 */ From lattner at cs.uiuc.edu Sun Dec 28 15:23:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:23:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/InstrSelection.h Message-ID: <200312282122.PAA29929@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: InstrSelection.h updated: 1.31 -> 1.32 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+1 -7) Index: llvm/include/llvm/CodeGen/InstrSelection.h diff -u llvm/include/llvm/CodeGen/InstrSelection.h:1.31 llvm/include/llvm/CodeGen/InstrSelection.h:1.32 --- llvm/include/llvm/CodeGen/InstrSelection.h:1.31 Sun Dec 28 03:42:49 2003 +++ llvm/include/llvm/CodeGen/InstrSelection.h Sun Dec 28 15:22:35 2003 @@ -22,7 +22,6 @@ class FunctionPass; class InstrForest; class InstructionNode; -class IntrinsicLowering; class MachineCodeForInstruction; class MachineInstr; class TargetMachine; @@ -40,8 +39,6 @@ extern bool ThisIsAChainRule (int eruleno); -//************************ Exported Functions ******************************/ - //--------------------------------------------------------------------------- // Function: createInstructionSelectionPass @@ -51,11 +48,8 @@ // Return a pass that performs machine dependent instruction selection. //--------------------------------------------------------------------------- -FunctionPass *createInstructionSelectionPass(TargetMachine &Target, - IntrinsicLowering &IL); - +FunctionPass *createInstructionSelectionPass(TargetMachine &Target); -//************************ Exported Data Types *****************************/ //--------------------------------------------------------------------------- From lattner at cs.uiuc.edu Sun Dec 28 15:23:05 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:23:05 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/IntrinsicLowering.h Message-ID: <200312282122.PAA29931@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: IntrinsicLowering.h updated: 1.3 -> 1.4 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+2 -0) Index: llvm/include/llvm/IntrinsicLowering.h diff -u llvm/include/llvm/IntrinsicLowering.h:1.3 llvm/include/llvm/IntrinsicLowering.h:1.4 --- llvm/include/llvm/IntrinsicLowering.h:1.3 Sun Dec 28 02:55:50 2003 +++ llvm/include/llvm/IntrinsicLowering.h Sun Dec 28 15:22:35 2003 @@ -33,6 +33,8 @@ #ifndef LLVM_INTRINSICLOWERING_H #define LLVM_INTRINSICLOWERING_H +#include "llvm/Intrinsics.h" + namespace llvm { class CallInst; From lattner at cs.uiuc.edu Sun Dec 28 15:23:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:23:08 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachine.h Message-ID: <200312282122.PAA29930@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.41 -> 1.42 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+12 -8) Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.41 llvm/include/llvm/Target/TargetMachine.h:1.42 --- llvm/include/llvm/Target/TargetMachine.h:1.41 Fri Dec 19 19:21:37 2003 +++ llvm/include/llvm/Target/TargetMachine.h Sun Dec 28 15:22:35 2003 @@ -31,6 +31,7 @@ class FunctionPassManager; class PassManager; class Pass; +class IntrinsicLowering; //===----------------------------------------------------------------------===// /// @@ -40,24 +41,27 @@ /// class TargetMachine { const std::string Name; - const TargetData DataLayout; // Calculates type size & alignment + const TargetData DataLayout; // Calculates type size & alignment + IntrinsicLowering *IL; // Specifies how to lower intrinsic calls TargetMachine(const TargetMachine&); // DO NOT IMPLEMENT void operator=(const TargetMachine&); // DO NOT IMPLEMENT -protected: - TargetMachine(const std::string &name, // Can only create subclasses... +protected: // Can only create subclasses... + TargetMachine(const std::string &name, IntrinsicLowering *IL, bool LittleEndian = false, unsigned char PtrSize = 8, unsigned char PtrAl = 8, unsigned char DoubleAl = 8, unsigned char FloatAl = 4, unsigned char LongAl = 8, unsigned char IntAl = 4, - unsigned char ShortAl = 2, unsigned char ByteAl = 1) - : Name(name), DataLayout(name, LittleEndian, - PtrSize, PtrAl, DoubleAl, FloatAl, LongAl, - IntAl, ShortAl, ByteAl) {} + unsigned char ShortAl = 2, unsigned char ByteAl = 1); public: - virtual ~TargetMachine() {} + virtual ~TargetMachine(); const std::string &getName() const { return Name; } + + // getIntrinsicLowering - This method returns a reference to an + // IntrinsicLowering instance which should be used by the code generator to + // lower unknown intrinsic functions to the equivalent LLVM expansion. + IntrinsicLowering &getIntrinsicLowering() const { return *IL; } // Interfaces to the major aspects of target machine information: // -- Instruction opcode and operand information From lattner at cs.uiuc.edu Sun Dec 28 15:24:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:24:01 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/IntrinsicLowering.cpp Message-ID: <200312282123.PAA30037@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: IntrinsicLowering.cpp updated: 1.2 -> 1.3 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+0 -1) Index: llvm/lib/VMCore/IntrinsicLowering.cpp diff -u llvm/lib/VMCore/IntrinsicLowering.cpp:1.2 llvm/lib/VMCore/IntrinsicLowering.cpp:1.3 --- llvm/lib/VMCore/IntrinsicLowering.cpp:1.2 Sun Dec 28 02:30:20 2003 +++ llvm/lib/VMCore/IntrinsicLowering.cpp Sun Dec 28 15:23:38 2003 @@ -13,7 +13,6 @@ #include "llvm/IntrinsicLowering.h" #include "llvm/Constant.h" -#include "llvm/Intrinsics.h" #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/iOther.h" From lattner at cs.uiuc.edu Sun Dec 28 15:24:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:24:04 2003 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Message-ID: <200312282123.PAA30011@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/Interpreter: Execution.cpp updated: 1.119 -> 1.120 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+0 -1) Index: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp diff -u llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.119 llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.120 --- llvm/lib/ExecutionEngine/Interpreter/Execution.cpp:1.119 Sun Dec 28 03:44:36 2003 +++ llvm/lib/ExecutionEngine/Interpreter/Execution.cpp Sun Dec 28 15:23:38 2003 @@ -17,7 +17,6 @@ #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicLowering.h" -#include "llvm/Intrinsics.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "Support/Statistic.h" #include "Support/Debug.h" From lattner at cs.uiuc.edu Sun Dec 28 15:24:07 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:24:07 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectPattern.cpp InstSelectSimple.cpp X86.h X86JITInfo.h X86TargetMachine.cpp X86TargetMachine.h Message-ID: <200312282123.PAA30045@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectPattern.cpp updated: 1.6 -> 1.7 InstSelectSimple.cpp updated: 1.147 -> 1.148 X86.h updated: 1.24 -> 1.25 X86JITInfo.h updated: 1.2 -> 1.3 X86TargetMachine.cpp updated: 1.43 -> 1.44 X86TargetMachine.h updated: 1.20 -> 1.21 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+16 -31) Index: llvm/lib/Target/X86/InstSelectPattern.cpp diff -u llvm/lib/Target/X86/InstSelectPattern.cpp:1.6 llvm/lib/Target/X86/InstSelectPattern.cpp:1.7 --- llvm/lib/Target/X86/InstSelectPattern.cpp:1.6 Sun Dec 28 03:47:19 2003 +++ llvm/lib/Target/X86/InstSelectPattern.cpp Sun Dec 28 15:23:38 2003 @@ -119,7 +119,6 @@ /// into a machine code representation using pattern matching and a machine /// description file. /// -FunctionPass *llvm::createX86PatternInstructionSelector(TargetMachine &TM, - IntrinsicLowering &IL) { +FunctionPass *llvm::createX86PatternInstructionSelector(TargetMachine &TM) { return new ISel(TM); } Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.147 llvm/lib/Target/X86/InstSelectSimple.cpp:1.148 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.147 Sun Dec 28 03:53:23 2003 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Sun Dec 28 15:23:38 2003 @@ -18,7 +18,6 @@ #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" #include "llvm/IntrinsicLowering.h" #include "llvm/Pass.h" #include "llvm/CodeGen/MachineConstantPool.h" @@ -59,7 +58,6 @@ namespace { struct ISel : public FunctionPass, InstVisitor { TargetMachine &TM; - IntrinsicLowering &IL; MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling int VarArgsFrameIndex; // FrameIndex for start of varargs area @@ -69,8 +67,7 @@ // MBBMap - Mapping between LLVM BB -> Machine BB std::map MBBMap; - ISel(TargetMachine &tm, IntrinsicLowering &il) - : TM(tm), IL(il), F(0), BB(0) {} + ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {} /// runOnFunction - Top level implementation of instruction selection for /// the entire function. @@ -1116,7 +1113,7 @@ default: // All other intrinsic calls we must lower. Instruction *Before = CI->getPrev(); - IL.LowerIntrinsicCall(CI); + TM.getIntrinsicLowering().LowerIntrinsicCall(CI); if (Before) { // Move iterator to instruction after call I = Before; ++I; } else { @@ -2196,7 +2193,6 @@ /// into a machine code representation is a very simple peep-hole fashion. The /// generated code sucks but the implementation is nice and simple. /// -FunctionPass *llvm::createX86SimpleInstructionSelector(TargetMachine &TM, - IntrinsicLowering &IL) { - return new ISel(TM, IL); +FunctionPass *llvm::createX86SimpleInstructionSelector(TargetMachine &TM) { + return new ISel(TM); } Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.24 llvm/lib/Target/X86/X86.h:1.25 --- llvm/lib/Target/X86/X86.h:1.24 Sun Dec 28 03:47:19 2003 +++ llvm/lib/Target/X86/X86.h Sun Dec 28 15:23:38 2003 @@ -27,15 +27,13 @@ /// into a machine code representation in a very simple peep-hole fashion. The /// generated code sucks but the implementation is nice and simple. /// -FunctionPass *createX86SimpleInstructionSelector(TargetMachine &TM, - IntrinsicLowering &IL); +FunctionPass *createX86SimpleInstructionSelector(TargetMachine &TM); /// createX86PatternInstructionSelector - This pass converts an LLVM function /// into a machine code representation using pattern matching and a machine /// description file. /// -FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM, - IntrinsicLowering &IL); +FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM); /// createX86SSAPeepholeOptimizerPass - Create a pass to perform SSA-based X86 /// specific peephole optimizations. Index: llvm/lib/Target/X86/X86JITInfo.h diff -u llvm/lib/Target/X86/X86JITInfo.h:1.2 llvm/lib/Target/X86/X86JITInfo.h:1.3 --- llvm/lib/Target/X86/X86JITInfo.h:1.2 Sun Dec 28 03:47:19 2003 +++ llvm/lib/Target/X86/X86JITInfo.h Sun Dec 28 15:23:38 2003 @@ -22,9 +22,8 @@ class X86JITInfo : public TargetJITInfo { TargetMachine &TM; - IntrinsicLowering &IL; public: - X86JITInfo(TargetMachine &tm, IntrinsicLowering &il) : TM(tm), IL(il) {} + X86JITInfo(TargetMachine &tm) : TM(tm) {} /// addPassesToJITCompile - Add passes to the specified pass manager to /// implement a fast dynamic compiler for this target. Return true if this @@ -37,7 +36,7 @@ /// overwriting OLD with a branch to NEW. This is used for self-modifying /// code. /// - virtual void replaceMachineCodeForFunction (void *Old, void *New); + virtual void replaceMachineCodeForFunction(void *Old, void *New); /// getJITStubForFunction - Create or return a stub for the specified /// function. This stub acts just like the specified function, except that Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.43 llvm/lib/Target/X86/X86TargetMachine.cpp:1.44 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.43 Sun Dec 28 03:47:19 2003 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Sun Dec 28 15:23:38 2003 @@ -45,15 +45,10 @@ /// X86TargetMachine ctor - Create an ILP32 architecture model /// -X86TargetMachine::X86TargetMachine(const Module &M, IntrinsicLowering *il) - : TargetMachine("X86", true, 4, 4, 4, 4, 4), - IL(il ? il : new DefaultIntrinsicLowering()), +X86TargetMachine::X86TargetMachine(const Module &M, IntrinsicLowering *IL) + : TargetMachine("X86", IL, true, 4, 4, 4, 4, 4), FrameInfo(TargetFrameInfo::StackGrowsDown, 8/*16 for SSE*/, 4), - JITInfo(*this, *IL) { -} - -X86TargetMachine::~X86TargetMachine() { - delete IL; + JITInfo(*this) { } @@ -72,9 +67,9 @@ PM.add(createCFGSimplificationPass()); if (NoPatternISel) - PM.add(createX86SimpleInstructionSelector(*this, *IL)); + PM.add(createX86SimpleInstructionSelector(*this)); else - PM.add(createX86PatternInstructionSelector(*this, *IL)); + PM.add(createX86PatternInstructionSelector(*this)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) @@ -127,9 +122,9 @@ PM.add(createCFGSimplificationPass()); if (NoPatternISel) - PM.add(createX86SimpleInstructionSelector(TM, IL)); + PM.add(createX86SimpleInstructionSelector(TM)); else - PM.add(createX86PatternInstructionSelector(TM, IL)); + PM.add(createX86PatternInstructionSelector(TM)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.20 llvm/lib/Target/X86/X86TargetMachine.h:1.21 --- llvm/lib/Target/X86/X86TargetMachine.h:1.20 Sun Dec 28 03:47:19 2003 +++ llvm/lib/Target/X86/X86TargetMachine.h Sun Dec 28 15:23:38 2003 @@ -24,13 +24,11 @@ class IntrinsicLowering; class X86TargetMachine : public TargetMachine { - IntrinsicLowering *IL; X86InstrInfo InstrInfo; TargetFrameInfo FrameInfo; X86JITInfo JITInfo; public: X86TargetMachine(const Module &M, IntrinsicLowering *IL); - ~X86TargetMachine(); virtual const X86InstrInfo &getInstrInfo() const { return InstrInfo; } virtual const TargetFrameInfo &getFrameInfo() const { return FrameInfo; } From lattner at cs.uiuc.edu Sun Dec 28 15:24:10 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:24:10 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp Message-ID: <200312282123.PAA30002@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSelection: InstrSelection.cpp updated: 1.67 -> 1.68 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+4 -8) Index: llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp diff -u llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.67 llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.68 --- llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp:1.67 Sun Dec 28 03:53:23 2003 +++ llvm/lib/CodeGen/InstrSelection/InstrSelection.cpp Sun Dec 28 15:23:38 2003 @@ -16,7 +16,6 @@ #include "llvm/CodeGen/InstrSelection.h" #include "llvm/Function.h" -#include "llvm/Intrinsics.h" #include "llvm/IntrinsicLowering.h" #include "llvm/iPHINode.h" #include "llvm/iOther.h" @@ -68,7 +67,6 @@ // class InstructionSelection : public FunctionPass { TargetMachine &Target; - IntrinsicLowering &IL; void InsertCodeForPhis(Function &F); void InsertPhiElimInstructions(BasicBlock *BB, const std::vector& CpVec); @@ -76,8 +74,7 @@ void PostprocessMachineCodeForTree(InstructionNode* instrNode, int ruleForNode, short* nts); public: - InstructionSelection(TargetMachine &TM, IntrinsicLowering &il) - : Target(TM), IL(il) {} + InstructionSelection(TargetMachine &TM) : Target(TM) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -145,7 +142,7 @@ default: // All other intrinsic calls we must lower. Instruction *Before = CI->getPrev(); - IL.LowerIntrinsicCall(CI); + Target.getIntrinsicLowering().LowerIntrinsicCall(CI); if (Before) { // Move iterator to instruction after call I = Before; ++I; } else { @@ -415,7 +412,6 @@ // createInstructionSelectionPass - Public entrypoint for instruction selection // and this file as a whole... // -FunctionPass *llvm::createInstructionSelectionPass(TargetMachine &T, - IntrinsicLowering &IL) { - return new InstructionSelection(T, IL); +FunctionPass *llvm::createInstructionSelectionPass(TargetMachine &TM) { + return new InstructionSelection(TM); } From lattner at cs.uiuc.edu Sun Dec 28 15:24:14 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:24:14 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetMachine.cpp Message-ID: <200312282123.PAA30012@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetMachine.cpp updated: 1.20 -> 1.21 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+25 -17) Index: llvm/lib/Target/TargetMachine.cpp diff -u llvm/lib/Target/TargetMachine.cpp:1.20 llvm/lib/Target/TargetMachine.cpp:1.21 --- llvm/lib/Target/TargetMachine.cpp:1.20 Tue Nov 11 16:41:33 2003 +++ llvm/lib/Target/TargetMachine.cpp Sun Dec 28 15:23:38 2003 @@ -15,20 +15,33 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetCacheInfo.h" #include "llvm/Type.h" +#include "llvm/IntrinsicLowering.h" +using namespace llvm; -namespace llvm { - -//--------------------------------------------------------------------------- -// class TargetMachine -// -// Purpose: -// Machine description. -// //--------------------------------------------------------------------------- +// TargetMachine Class +// +TargetMachine::TargetMachine(const std::string &name, IntrinsicLowering *il, + bool LittleEndian, + unsigned char PtrSize, unsigned char PtrAl, + unsigned char DoubleAl, unsigned char FloatAl, + unsigned char LongAl, unsigned char IntAl, + unsigned char ShortAl, unsigned char ByteAl) + : Name(name), DataLayout(name, LittleEndian, + PtrSize, PtrAl, DoubleAl, FloatAl, LongAl, + IntAl, ShortAl, ByteAl) { + IL = il ? il : new DefaultIntrinsicLowering(); +} + + + +TargetMachine::~TargetMachine() { + delete IL; +} + + -// function TargetMachine::findOptimalStorageSize -// unsigned TargetMachine::findOptimalStorageSize(const Type *Ty) const { // All integer types smaller than ints promote to 4 byte integers. if (Ty->isIntegral() && Ty->getPrimitiveSize() < 4) @@ -39,11 +52,8 @@ //--------------------------------------------------------------------------- -// class TargetCacheInfo -// -// Purpose: -// Describes properties of the target cache architecture. -//--------------------------------------------------------------------------- +// TargetCacheInfo Class +// void TargetCacheInfo::Initialize() { numLevels = 2; @@ -51,5 +61,3 @@ cacheSizes.push_back(1 << 15); cacheSizes.push_back(1 << 20); cacheAssoc.push_back(1); cacheAssoc.push_back(4); } - -} // End llvm namespace From lattner at cs.uiuc.edu Sun Dec 28 15:24:17 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 15:24:17 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcJITInfo.h SparcTargetMachine.cpp SparcTargetMachine.h Message-ID: <200312282123.PAA30024@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcJITInfo.h updated: 1.2 -> 1.3 SparcTargetMachine.cpp updated: 1.96 -> 1.97 SparcTargetMachine.h updated: 1.3 -> 1.4 --- Log message: Clean up a lot of the code I added yesterday by exposing the IntrinsicLowering implementation from the TargetMachine directly. --- Diffs of the changes: (+5 -15) Index: llvm/lib/Target/Sparc/SparcJITInfo.h diff -u llvm/lib/Target/Sparc/SparcJITInfo.h:1.2 llvm/lib/Target/Sparc/SparcJITInfo.h:1.3 --- llvm/lib/Target/Sparc/SparcJITInfo.h:1.2 Sun Dec 28 03:46:33 2003 +++ llvm/lib/Target/Sparc/SparcJITInfo.h Sun Dec 28 15:23:38 2003 @@ -18,13 +18,11 @@ namespace llvm { class TargetMachine; - class IntrinsicLowering; class SparcJITInfo : public TargetJITInfo { TargetMachine &TM; - IntrinsicLowering &IL; public: - SparcJITInfo(TargetMachine &tm, IntrinsicLowering &il) : TM(tm), IL(il) {} + SparcJITInfo(TargetMachine &tm) : TM(tm) {} /// addPassesToJITCompile - Add passes to the specified pass manager to /// implement a fast dynamic compiler for this target. Return true if this Index: llvm/lib/Target/Sparc/SparcTargetMachine.cpp diff -u llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.96 llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.97 --- llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.96 Sun Dec 28 03:46:33 2003 +++ llvm/lib/Target/Sparc/SparcTargetMachine.cpp Sun Dec 28 15:23:38 2003 @@ -116,17 +116,12 @@ SparcTargetMachine::SparcTargetMachine(IntrinsicLowering *il) - : TargetMachine("UltraSparc-Native", false), - IL(il ? il : new DefaultIntrinsicLowering()), + : TargetMachine("UltraSparc-Native", il, false), schedInfo(*this), regInfo(*this), frameInfo(*this), cacheInfo(*this), - jitInfo(*this, *IL) { -} - -SparcTargetMachine::~SparcTargetMachine() { - delete IL; + jitInfo(*this) { } // addPassesToEmitAssembly - This method controls the entire code generation @@ -171,7 +166,7 @@ PM.add(new PrintFunctionPass("Input code to instr. selection:\n", &std::cerr)); - PM.add(createInstructionSelectionPass(*this, *IL)); + PM.add(createInstructionSelectionPass(*this)); if (!DisableSched) PM.add(createInstructionSchedulingWithSSAPass(*this)); @@ -238,7 +233,7 @@ //PM.add(createLICMPass()); //PM.add(createGCSEPass()); - PM.add(createInstructionSelectionPass(TM, IL)); + PM.add(createInstructionSelectionPass(TM)); PM.add(getRegisterAllocator(TM)); PM.add(createPrologEpilogInsertionPass()); Index: llvm/lib/Target/Sparc/SparcTargetMachine.h diff -u llvm/lib/Target/Sparc/SparcTargetMachine.h:1.3 llvm/lib/Target/Sparc/SparcTargetMachine.h:1.4 --- llvm/lib/Target/Sparc/SparcTargetMachine.h:1.3 Sun Dec 28 03:46:33 2003 +++ llvm/lib/Target/Sparc/SparcTargetMachine.h Sun Dec 28 15:23:38 2003 @@ -24,10 +24,8 @@ namespace llvm { class PassManager; - class IntrinsicLowering; class SparcTargetMachine : public TargetMachine { - IntrinsicLowering *IL; SparcInstrInfo instrInfo; SparcSchedInfo schedInfo; SparcRegInfo regInfo; @@ -36,7 +34,6 @@ SparcJITInfo jitInfo; public: SparcTargetMachine(IntrinsicLowering *IL); - ~SparcTargetMachine(); virtual const TargetInstrInfo &getInstrInfo() const { return instrInfo; } virtual const TargetSchedInfo &getSchedInfo() const { return schedInfo; } From lattner at cs.uiuc.edu Sun Dec 28 17:05:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 17:05:01 2003 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200312282304.RAA30641@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.14 -> 1.15 --- Log message: What do you know, we actually do accomplish some things around here :) --- Diffs of the changes: (+1 -12) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.14 llvm/docs/OpenProjects.html:1.15 --- llvm/docs/OpenProjects.html:1.14 Fri Nov 14 11:34:38 2003 +++ llvm/docs/OpenProjects.html Sun Dec 28 17:04:17 2003 @@ -101,10 +101,6 @@ daily report. It could use the following improvements:

      -
    1. Graphs - It would be great to have gnuplot graphs to keep track of how the - tree is changing over time. We already gather a several statistics, it - just necessary to add the script-fu to gnuplotize it.
    2. -
    3. Regression tests - We should run the regression tests in addition to the program tests...
    @@ -166,11 +162,6 @@ would also then have to implement the reader for this index in gccld. -
  • Improve the efficiency of the bytecode loader/writer
  • - -
  • Extend the FunctionPassManager to use a ModuleProvider to stream functions - in on demand. This would improve the efficiency of the JIT.
  • -
  • Rework the PassManager to be more flexible
  • Some transformations and analyses only work on reducible flow graphs. It @@ -266,8 +257,6 @@
    1. Implement a Dependence Analysis Infrastructure
      - Design some way to represent and query dep analysis
    2. -
    3. Implement a faster Dominator Set Construction Algorithm
      - - A linear time or nearly so algorithm
    4. Implement a strength reduction pass
    5. Value range propagation pass
    6. Implement an unswitching pass
    7. @@ -313,7 +302,7 @@
      Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2003/11/14 17:34:38 $ + Last modified: $Date: 2003/12/28 23:04:17 $ From lattner at cs.uiuc.edu Sun Dec 28 23:07:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 23:07:01 2003 Subject: [llvm-commits] CVS: llvm/include/Support/StringExtras.h Message-ID: <200312290506.XAA31363@zion.cs.uiuc.edu> Changes in directory llvm/include/Support: StringExtras.h updated: 1.11 -> 1.12 --- Log message: add new function --- Diffs of the changes: (+10 -0) Index: llvm/include/Support/StringExtras.h diff -u llvm/include/Support/StringExtras.h:1.11 llvm/include/Support/StringExtras.h:1.12 --- llvm/include/Support/StringExtras.h:1.11 Sun Nov 16 14:21:13 2003 +++ llvm/include/Support/StringExtras.h Sun Dec 28 23:06:38 2003 @@ -97,6 +97,16 @@ return Buffer; } + +/// getToken - This function extracts one token from source, ignoring any +/// leading characters that appear in the Delimiters string, and ending the +/// token at any of the characters that appear in the Delimiters string. If +/// there are no tokens in the source string, an empty string is returned. +/// The Source source string is updated in place to remove the returned string +/// and any delimiter prefix from it. +std::string getToken(std::string &Source, + const char *Delimiters = " \t\n\v\f\r"); + } // End llvm namespace #endif From lattner at cs.uiuc.edu Sun Dec 28 23:08:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 28 23:08:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Support/StringExtras.cpp Message-ID: <200312290507.XAA31393@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: StringExtras.cpp added (r1.1) --- Log message: implement new getToken function --- Diffs of the changes: (+43 -0) Index: llvm/lib/Support/StringExtras.cpp diff -c /dev/null llvm/lib/Support/StringExtras.cpp:1.1 *** /dev/null Sun Dec 28 23:07:12 2003 --- llvm/lib/Support/StringExtras.cpp Sun Dec 28 23:07:02 2003 *************** *** 0 **** --- 1,43 ---- + //===-- StringExtras.cpp - Implement the StringExtras header --------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the StringExtras.h header + // + //===----------------------------------------------------------------------===// + + #include "Support/StringExtras.h" + using namespace llvm; + + /// getToken - This function extracts one token from source, ignoring any + /// leading characters that appear in the Delimiters string, and ending the + /// token at any of the characters that appear in the Delimiters string. If + /// there are no tokens in the source string, an empty string is returned. + /// The Source source string is updated in place to remove the returned string + /// and any delimiter prefix from it. + std::string llvm::getToken(std::string &Source, const char *Delimiters) { + unsigned NumDelimiters = std::strlen(Delimiters); + + // Figure out where the token starts. + std::string::size_type Start = + Source.find_first_not_of(Delimiters, 0, NumDelimiters); + if (Start == std::string::npos) Start = Source.size(); + + // Find the next occurance of the delimiter. + std::string::size_type End = + Source.find_first_of(Delimiters, Start, NumDelimiters); + if (End == std::string::npos) End = Source.size(); + + // Create the return token. + std::string Result = std::string(Source.begin()+Start, Source.begin()+End); + + // Erase the token that we read in. + Source.erase(Source.begin(), Source.begin()+End); + + return Result; + }