From alenhar2 at cs.uiuc.edu Mon Jan 2 15:16:05 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 2 Jan 2006 15:16:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Message-ID: <200601022116.PAA28203@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.25 -> 1.26 --- Log message: typeo --- Diffs of the changes: (+1 -1) AlphaISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.25 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.26 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.25 Sun Jan 1 16:16:14 2006 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Mon Jan 2 15:15:53 2006 @@ -65,7 +65,7 @@ { build = 0; break; } x >>= 8; } - return x; + return build; } static bool isFPZ(SDOperand N) { From lattner at cs.uiuc.edu Tue Jan 3 00:05:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 00:05:00 -0600 Subject: [llvm-commits] CVS: llvm/docs/AliasAnalysis.html Message-ID: <200601030605.AAA31350@zion.cs.uiuc.edu> Changes in directory llvm/docs: AliasAnalysis.html updated: 1.25 -> 1.26 --- Log message: update usage of -print-alias-sets --- Diffs of the changes: (+9 -3) AliasAnalysis.html | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) Index: llvm/docs/AliasAnalysis.html diff -u llvm/docs/AliasAnalysis.html:1.25 llvm/docs/AliasAnalysis.html:1.26 --- llvm/docs/AliasAnalysis.html:1.25 Mon Sep 6 18:00:30 2004 +++ llvm/docs/AliasAnalysis.html Tue Jan 3 00:04:48 2006 @@ -889,9 +889,15 @@

The -print-alias-sets pass is exposed as part of the -analyze tool to print out the Alias Sets formed by the opt tool to print out the Alias Sets formed by the AliasSetTracker class. This is useful if you're using -the AliasSetTracker class.

+the AliasSetTracker class. To use it, use something like:

+ +
+
+% opt -ds-aa -print-alias-sets -disable-output
+
+
@@ -946,7 +952,7 @@ Chris Lattner
LLVM Compiler Infrastructure
- Last modified: $Date: 2004/09/06 23:00:30 $ + Last modified: $Date: 2006/01/03 06:04:48 $ From lattner at cs.uiuc.edu Tue Jan 3 00:05:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 00:05:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasSetTracker.cpp Message-ID: <200601030605.AAA31384@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasSetTracker.cpp updated: 1.36 -> 1.37 --- Log message: Make the -print-alias-sets pass work for printing out something other than the default aa impl results. --- Diffs of the changes: (+3 -11) AliasSetTracker.cpp | 14 +++----------- 1 files changed, 3 insertions(+), 11 deletions(-) Index: llvm/lib/Analysis/AliasSetTracker.cpp diff -u llvm/lib/Analysis/AliasSetTracker.cpp:1.36 llvm/lib/Analysis/AliasSetTracker.cpp:1.37 --- llvm/lib/Analysis/AliasSetTracker.cpp:1.36 Thu Apr 21 16:04:58 2005 +++ llvm/lib/Analysis/AliasSetTracker.cpp Tue Jan 3 00:05:22 2006 @@ -540,18 +540,10 @@ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) Tracker->add(&*I); - return false; - } - - /// print - Convert to human readable form - virtual void print(std::ostream &OS, const Module* = 0) const { - Tracker->print(OS); - } - - virtual void releaseMemory() { + Tracker->print(std::cerr); delete Tracker; + return false; } }; - RegisterPass X("print-alias-sets", "Alias Set Printer", - PassInfo::Analysis | PassInfo::Optimization); + RegisterOpt X("print-alias-sets", "Alias Set Printer"); } From lattner at cs.uiuc.edu Tue Jan 3 01:05:29 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 01:05:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/PassManagerT.h Message-ID: <200601030705.BAA31782@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.58 -> 1.59 --- Log message: Finally commit Saem's 'patch #3' to refactor the pass manager --- Diffs of the changes: (+80 -55) PassManagerT.h | 135 +++++++++++++++++++++++++++++++++------------------------ 1 files changed, 80 insertions(+), 55 deletions(-) Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.58 llvm/lib/VMCore/PassManagerT.h:1.59 --- llvm/lib/VMCore/PassManagerT.h:1.58 Fri Dec 30 14:00:46 2005 +++ llvm/lib/VMCore/PassManagerT.h Tue Jan 3 01:05:17 2006 @@ -511,7 +511,7 @@ // batcher class then we can reorder to pass to execute before the batcher // does, which will potentially allow us to batch more passes! // - //const std::vector &ProvidedSet = AnUsage.getProvidedSet(); + // const std::vector &ProvidedSet = AnUsage.getProvidedSet(); if (Batcher /*&& ProvidedSet.empty()*/) closeBatcher(); // This pass cannot be batched! @@ -630,18 +630,6 @@ // into a single unit. // class BasicBlockPassManager { - //TODO:Start absorbing PassManagerTraits -}; - - -//===----------------------------------------------------------------------===// -// PassManagerTraits Specialization -// -// This pass manager is used to group together all of the BasicBlockPass's -// into a single unit. -// -template<> class PassManagerTraits : public BasicBlockPass, - public BasicBlockPassManager { public: // PassClass - The type of passes tracked by this PassManager typedef BasicBlockPass PassClass; @@ -664,27 +652,47 @@ // PMType - The type of the passmanager that subclasses this class typedef PassManagerT PMType; + // getPMName() - Return the name of the unit the PassManager operates on for + // debugging. + virtual const char *getPMName() const { return "BasicBlock"; } + + virtual const char *getPassName() const { return "BasicBlock Pass Manager"; } + + // TODO:Start absorbing PassManagerTraits +}; + + +//===----------------------------------------------------------------------===// +// PassManagerTraits Specialization +// +// This pass manager is used to group together all of the BasicBlockPass's +// into a single unit. +// +template<> class PassManagerTraits : public BasicBlockPass, + public BasicBlockPassManager { +public: // runPass - Specify how the pass should be run on the UnitType static bool runPass(PassClass *P, BasicBlock *M) { // todo, init and finalize return P->runOnBasicBlock(*M); } - - // getPMName() - Return the name of the unit the PassManager operates on for - // debugging. - const char *getPMName() const { return "BasicBlock"; } - virtual const char *getPassName() const { return "BasicBlock Pass Manager"; } - + // Implement the BasicBlockPass interface... virtual bool doInitialization(Module &M); virtual bool doInitialization(Function &F); virtual bool runOnBasicBlock(BasicBlock &BB); virtual bool doFinalization(Function &F); virtual bool doFinalization(Module &M); - + + // Forwarded + virtual const char *getPassName() const { + return BasicBlockPassManager::getPassName(); + } + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } + }; @@ -695,18 +703,6 @@ // into a single unit. // class FunctionPassManagerT { - //TODO:Start absorbing PassManagerTraits -}; - - -//===----------------------------------------------------------------------===// -// PassManagerTraits Specialization -// -// This pass manager is used to group together all of the FunctionPass's -// into a single unit. -// -template<> class PassManagerTraits : public FunctionPass, - public FunctionPassManagerT { public: // PassClass - The type of passes tracked by this PassManager typedef FunctionPass PassClass; @@ -722,25 +718,44 @@ // PMType - The type of the passmanager that subclasses this class typedef PassManagerT PMType; + + // getPMName() - Return the name of the unit the PassManager operates on for + // debugging. + virtual const char *getPMName() const { return "Function"; } + + virtual const char *getPassName() const { return "Function Pass Manager"; } + // TODO:Start absorbing PassManagerTraits +}; + + +//===----------------------------------------------------------------------===// +// PassManagerTraits Specialization +// +// This pass manager is used to group together all of the FunctionPass's +// into a single unit. +// +template<> class PassManagerTraits : public FunctionPass, + public FunctionPassManagerT { +public: // runPass - Specify how the pass should be run on the UnitType static bool runPass(PassClass *P, Function *F) { return P->runOnFunction(*F); } - - // getPMName() - Return the name of the unit the PassManager operates on for - // debugging. - const char *getPMName() const { return "Function"; } - virtual const char *getPassName() const { return "Function Pass Manager"; } - + // Implement the FunctionPass interface... virtual bool doInitialization(Module &M); virtual bool runOnFunction(Function &F); virtual bool doFinalization(Module &M); - + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } + + // Forwarded + virtual const char *getPassName() const { + return FunctionPassManagerT::getPassName(); + } }; @@ -750,17 +765,6 @@ // This is the top level PassManager implementation that holds generic passes. // class ModulePassManager { - //TODO:Start absorbing PassManagerTraits -}; - - -//===----------------------------------------------------------------------===// -// PassManagerTraits Specialization -// -// This is the top level PassManager implementation that holds generic passes. -// -template<> class PassManagerTraits : public ModulePass, - public ModulePassManager { public: // PassClass - The type of passes tracked by this PassManager typedef ModulePass PassClass; @@ -773,19 +777,40 @@ // ParentClass - The type of the parent PassManager... typedef AnalysisResolver ParentClass; - - // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Module *M) { return P->runOnModule(*M); } - + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. - const char *getPMName() const { return "Module"; } virtual const char *getPassName() const { return "Module Pass Manager"; } + + // getPMName() - Return the name of the unit the PassManager operates on for + // debugging. + virtual const char *getPMName() const { return "Module"; } + + + // TODO:Start absorbing PassManagerTraits +}; + +//===----------------------------------------------------------------------===// +// PassManagerTraits Specialization +// +// This is the top level PassManager implementation that holds generic passes. +// +template<> class PassManagerTraits : public ModulePass, + public ModulePassManager { +public: + // runPass - Specify how the pass should be run on the UnitType + static bool runPass(PassClass *P, Module *M) { return P->runOnModule(*M); } + // runOnModule - Implement the PassManager interface. bool runOnModule(Module &M) { return ((PassManagerT*)this)->runOnUnit(&M); } + + // Forwarded + virtual const char *getPassName() const { + return ModulePassManager::getPassName(); + } }; From lattner at cs.uiuc.edu Tue Jan 3 01:41:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 01:41:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <200601030741.BAA32000@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervalAnalysis.cpp updated: 1.151 -> 1.152 --- Log message: Change a variable from being an iterator to a raw MachineInstr*, to make GDB use tolerable --- Diffs of the changes: (+12 -12) LiveIntervalAnalysis.cpp | 24 ++++++++++++------------ 1 files changed, 12 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.151 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.152 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.151 Wed Oct 26 13:41:41 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Tue Jan 3 01:41:37 2006 @@ -247,7 +247,7 @@ index += InstrSlots::NUM; if (index == end) break; - MachineBasicBlock::iterator mi = getInstructionFromIndex(index); + MachineInstr *MI = getInstructionFromIndex(index); // NewRegLiveIn - This instruction might have multiple uses of the spilled // register. In this case, for the first use, keep track of the new vreg @@ -256,26 +256,26 @@ unsigned NewRegLiveIn = 0; for_operand: - for (unsigned i = 0; i != mi->getNumOperands(); ++i) { - MachineOperand& mop = mi->getOperand(i); + for (unsigned i = 0; i != MI->getNumOperands(); ++i) { + MachineOperand& mop = MI->getOperand(i); if (mop.isRegister() && mop.getReg() == li.reg) { if (NewRegLiveIn && mop.isUse()) { // We already emitted a reload of this value, reuse it for // subsequent operands. - mi->SetMachineOperandReg(i, NewRegLiveIn); + MI->SetMachineOperandReg(i, NewRegLiveIn); DEBUG(std::cerr << "\t\t\t\treused reload into reg" << NewRegLiveIn << " for operand #" << i << '\n'); - } else if (MachineInstr* fmi = mri_->foldMemoryOperand(mi, i, slot)) { + } else if (MachineInstr* fmi = mri_->foldMemoryOperand(MI, i, slot)) { // Attempt to fold the memory reference into the instruction. If we // can do this, we don't need to insert spill code. if (lv_) - lv_->instructionChanged(mi, fmi); - vrm.virtFolded(li.reg, mi, i, fmi); - mi2iMap_.erase(mi); + lv_->instructionChanged(MI, fmi); + vrm.virtFolded(li.reg, MI, i, fmi); + mi2iMap_.erase(MI); i2miMap_[index/InstrSlots::NUM] = fmi; mi2iMap_[fmi] = index; - MachineBasicBlock &MBB = *mi->getParent(); - mi = MBB.insert(MBB.erase(mi), fmi); + MachineBasicBlock &MBB = *MI->getParent(); + MI = MBB.insert(MBB.erase(MI), fmi); ++numFolded; // Folding the load/store can completely change the instruction in @@ -300,7 +300,7 @@ // create a new register for this spill NewRegLiveIn = mf_->getSSARegMap()->createVirtualRegister(rc); - mi->SetMachineOperandReg(i, NewRegLiveIn); + MI->SetMachineOperandReg(i, NewRegLiveIn); vrm.grow(); vrm.assignVirt2StackSlot(NewRegLiveIn, slot); LiveInterval& nI = getOrCreateInterval(NewRegLiveIn); @@ -316,7 +316,7 @@ // update live variables if it is available if (lv_) - lv_->addVirtualRegisterKilled(NewRegLiveIn, mi); + lv_->addVirtualRegisterKilled(NewRegLiveIn, MI); // If this is a live in, reuse it for subsequent live-ins. If it's // a def, we can't do this. From criswell at cs.uiuc.edu Tue Jan 3 08:42:32 2006 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue, 3 Jan 2006 08:42:32 -0600 Subject: [llvm-commits] CVS: llvm/LICENSE.TXT Message-ID: <200601031442.IAA16344@choi.cs.uiuc.edu> Changes in directory llvm: LICENSE.TXT updated: 1.25 -> 1.26 --- Log message: Happy New Year, LLVM. --- Diffs of the changes: (+1 -1) LICENSE.TXT | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/LICENSE.TXT diff -u llvm/LICENSE.TXT:1.25 llvm/LICENSE.TXT:1.26 --- llvm/LICENSE.TXT:1.25 Thu May 12 16:39:01 2005 +++ llvm/LICENSE.TXT Tue Jan 3 08:42:06 2006 @@ -4,7 +4,7 @@ University of Illinois/NCSA Open Source License -Copyright (c) 2003, 2004, 2005 University of Illinois at Urbana-Champaign. +Copyright (c) 2003, 2004, 2005, 2006 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: From lattner at cs.uiuc.edu Tue Jan 3 11:52:30 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 11:52:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/PassManagerT.h Message-ID: <200601031752.LAA10645@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.59 -> 1.60 --- Log message: silence some warnings --- Diffs of the changes: (+6 -0) PassManagerT.h | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.59 llvm/lib/VMCore/PassManagerT.h:1.60 --- llvm/lib/VMCore/PassManagerT.h:1.59 Tue Jan 3 01:05:17 2006 +++ llvm/lib/VMCore/PassManagerT.h Tue Jan 3 11:52:18 2006 @@ -652,6 +652,8 @@ // PMType - The type of the passmanager that subclasses this class typedef PassManagerT PMType; + virtual ~BasicBlockPassManager() {} + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPMName() const { return "BasicBlock"; } @@ -719,6 +721,8 @@ // PMType - The type of the passmanager that subclasses this class typedef PassManagerT PMType; + virtual ~FunctionPassManagerT() {} + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPMName() const { return "Function"; } @@ -778,6 +782,8 @@ // ParentClass - The type of the parent PassManager... typedef AnalysisResolver ParentClass; + virtual ~ModulePassManager() {} + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPassName() const { return "Module Pass Manager"; } From marco-ml at gmx.net Tue Jan 3 12:03:54 2006 From: marco-ml at gmx.net (Marco Matthies) Date: Tue, 03 Jan 2006 19:03:54 +0100 Subject: [llvm-commits] CVS: llvm-gcc/gcc/config/rs6000/sysv4.h t-ppccomm In-Reply-To: <200512231729.LAA25506@zion.cs.uiuc.edu> References: <200512231729.LAA25506@zion.cs.uiuc.edu> Message-ID: <43BABC8A.8090608@gmx.net> Chris Lattner wrote: > Changes in directory llvm-gcc/gcc/config/rs6000: > > sysv4.h updated: 1.1.1.2 -> 1.2 > t-ppccomm updated: 1.1.1.1 -> 1.2 > --- > Log message: > > get llvmgcc building on ppc-linux and ppc-linux64. Thanks to > Marco Matthies for the patch! To my shame i found out over the holidays that when i compiled it on ppc64-linux it got compiled as a ppc32 executable. I'll try and get it compiled and linked as a 64-bit executable to confirm if it also works on ppc64, though i cannot exactly tell when i'll get to it. Marco From sabre at nondot.org Tue Jan 3 12:28:13 2006 From: sabre at nondot.org (Chris Lattner) Date: Tue, 3 Jan 2006 12:28:13 -0600 (CST) Subject: [llvm-commits] CVS: llvm-gcc/gcc/config/rs6000/sysv4.h t-ppccomm In-Reply-To: <43BABC8A.8090608@gmx.net> References: <200512231729.LAA25506@zion.cs.uiuc.edu> <43BABC8A.8090608@gmx.net> Message-ID: On Tue, 3 Jan 2006, Marco Matthies wrote: > Chris Lattner wrote: >> Changes in directory llvm-gcc/gcc/config/rs6000: >> sysv4.h updated: 1.1.1.2 -> 1.2 >> t-ppccomm updated: 1.1.1.1 -> 1.2 >> --- >> Log message: >> >> get llvmgcc building on ppc-linux and ppc-linux64. Thanks to Marco >> Matthies for the patch! > > To my shame i found out over the holidays that when i compiled it on > ppc64-linux it got compiled as a ppc32 executable. I'll try and get it > compiled and linked as a 64-bit executable to confirm if it also works on > ppc64, though i cannot exactly tell when i'll get to it. Note that the LLVM native code generator doesn't support PPC64 yet. I don't know if that is something you're interested in. PPC32 should be close to working, but may need some minor hacking on the asmprinter to emit ELF .s files. -Chris -- http://nondot.org/sabre/ http://llvm.org/ From lattner at cs.uiuc.edu Tue Jan 3 13:13:29 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 13:13:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Internalize.cpp Message-ID: <200601031913.NAA11045@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: Internalize.cpp updated: 1.27 -> 1.28 --- Log message: Pull inline methods out of the pass class definition to make it easier to read the code. Do not internalize debugger anchors. --- Diffs of the changes: (+88 -78) Internalize.cpp | 166 +++++++++++++++++++++++++++++--------------------------- 1 files changed, 88 insertions(+), 78 deletions(-) Index: llvm/lib/Transforms/IPO/Internalize.cpp diff -u llvm/lib/Transforms/IPO/Internalize.cpp:1.27 llvm/lib/Transforms/IPO/Internalize.cpp:1.28 --- llvm/lib/Transforms/IPO/Internalize.cpp:1.27 Sun Dec 4 23:07:38 2005 +++ llvm/lib/Transforms/IPO/Internalize.cpp Tue Jan 3 13:13:17 2006 @@ -43,89 +43,99 @@ std::set ExternalNames; bool DontInternalize; public: - InternalizePass(bool InternalizeEverything = true) : DontInternalize(false){ - if (!APIFile.empty()) // If a filename is specified, use it - LoadFile(APIFile.c_str()); - else if (!APIList.empty()) // Else, if a list is specified, use it. - ExternalNames.insert(APIList.begin(), APIList.end()); - else if (!InternalizeEverything) - // Finally, if we're allowed to, internalize all but main. - DontInternalize = true; - } + InternalizePass(bool InternalizeEverything = true); + void LoadFile(const char *Filename); + virtual bool runOnModule(Module &M); + }; + RegisterOpt X("internalize", "Internalize Global Symbols"); +} // end anonymous namespace - void LoadFile(const char *Filename) { - // Load the APIFile... - std::ifstream In(Filename); - if (!In.good()) { - std::cerr << "WARNING: Internalize couldn't load file '" << Filename - << "'!\n"; - return; // Do not internalize anything... - } - while (In) { - std::string Symbol; - In >> Symbol; - if (!Symbol.empty()) - ExternalNames.insert(Symbol); - } - } +InternalizePass::InternalizePass(bool InternalizeEverything) + : DontInternalize(false){ + if (!APIFile.empty()) // If a filename is specified, use it + LoadFile(APIFile.c_str()); + else if (!APIList.empty()) // Else, if a list is specified, use it. + ExternalNames.insert(APIList.begin(), APIList.end()); + else if (!InternalizeEverything) + // Finally, if we're allowed to, internalize all but main. + DontInternalize = true; +} - virtual bool runOnModule(Module &M) { - if (DontInternalize) return false; +void InternalizePass::LoadFile(const char *Filename) { + // Load the APIFile... + std::ifstream In(Filename); + if (!In.good()) { + std::cerr << "WARNING: Internalize couldn't load file '" << Filename + << "'!\n"; + return; // Do not internalize anything... + } + while (In) { + std::string Symbol; + In >> Symbol; + if (!Symbol.empty()) + ExternalNames.insert(Symbol); + } +} + +bool InternalizePass::runOnModule(Module &M) { + if (DontInternalize) return false; + + // If no list or file of symbols was specified, check to see if there is a + // "main" symbol defined in the module. If so, use it, otherwise do not + // internalize the module, it must be a library or something. + // + if (ExternalNames.empty()) { + Function *MainFunc = M.getMainFunction(); + if (MainFunc == 0 || MainFunc->isExternal()) + return false; // No main found, must be a library... + + // Preserve main, internalize all else. + ExternalNames.insert(MainFunc->getName()); + } + + bool Changed = false; + + // Found a main function, mark all functions not named main as internal. + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isExternal() && // Function must be defined here + !I->hasInternalLinkage() && // Can't already have internal linkage + !ExternalNames.count(I->getName())) {// Not marked to keep external? + I->setLinkage(GlobalValue::InternalLinkage); + Changed = true; + ++NumFunctions; + DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n"); + } + + // Never internalize the llvm.used symbol. It is used to implement + // attribute((used)). + ExternalNames.insert("llvm.used"); + + // Never internalize anchors used by the debugger, else the debugger won't + // find them. + ExternalNames.insert("llvm.dbg.translation_units"); + ExternalNames.insert("llvm.dbg.globals"); - // If no list or file of symbols was specified, check to see if there is a - // "main" symbol defined in the module. If so, use it, otherwise do not - // internalize the module, it must be a library or something. + // Mark all global variables with initializers as internal as well. + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) + if (!I->isExternal() && !I->hasInternalLinkage() && + !ExternalNames.count(I->getName())) { + // Special case handling of the global ctor and dtor list. When we + // internalize it, we mark it constant, which allows elimination of + // the list if it's empty. // - if (ExternalNames.empty()) { - Function *MainFunc = M.getMainFunction(); - if (MainFunc == 0 || MainFunc->isExternal()) - return false; // No main found, must be a library... - - // Preserve main, internalize all else. - ExternalNames.insert(MainFunc->getName()); - } - - bool Changed = false; - - // Found a main function, mark all functions not named main as internal. - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal() && // Function must be defined here - !I->hasInternalLinkage() && // Can't already have internal linkage - !ExternalNames.count(I->getName())) {// Not marked to keep external? - I->setLinkage(GlobalValue::InternalLinkage); - Changed = true; - ++NumFunctions; - DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n"); - } - - // Mark all global variables with initializers as internal as well... - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - if (!I->isExternal() && !I->hasInternalLinkage() && - !ExternalNames.count(I->getName()) && - // *never* internalize the llvm.used symbol, used to implement - // attribute((used)). - I->getName() != "llvm.used") { - // Special case handling of the global ctor and dtor list. When we - // internalize it, we mark it constant, which allows elimination of - // the list if it's empty. - // - if (I->hasAppendingLinkage() && (I->getName() == "llvm.global_ctors"|| - I->getName() == "llvm.global_dtors")) - I->setConstant(true); - - I->setLinkage(GlobalValue::InternalLinkage); - Changed = true; - ++NumGlobals; - DEBUG(std::cerr << "Internalizing gvar " << I->getName() << "\n"); - } - - return Changed; + if (I->hasAppendingLinkage() && (I->getName() == "llvm.global_ctors" || + I->getName() == "llvm.global_dtors")) + I->setConstant(true); + + I->setLinkage(GlobalValue::InternalLinkage); + Changed = true; + ++NumGlobals; + DEBUG(std::cerr << "Internalizing gvar " << I->getName() << "\n"); } - }; - - RegisterOpt X("internalize", "Internalize Global Symbols"); -} // end anonymous namespace + + return Changed; +} ModulePass *llvm::createInternalizePass(bool InternalizeEverything) { return new InternalizePass(InternalizeEverything); From lattner at cs.uiuc.edu Tue Jan 3 16:55:28 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 16:55:28 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200601032255.QAA12257@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.119 -> 1.120 --- Log message: Remove my previous ugly hack that tries to reduce the stack space usage of SelectCode to make way for a better solution. --- Diffs of the changes: (+25 -68) DAGISelEmitter.cpp | 93 ++++++++++++++--------------------------------------- 1 files changed, 25 insertions(+), 68 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.119 llvm/utils/TableGen/DAGISelEmitter.cpp:1.120 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.119 Fri Dec 30 10:41:48 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue Jan 3 16:55:16 2006 @@ -1832,27 +1832,6 @@ ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr), PatternNo(PatNum), OS(os), TmpNo(0) {} - /// isPredeclaredSDOperand - Return true if this is one of the predeclared - /// SDOperands. - bool isPredeclaredSDOperand(const std::string &OpName) const { - return OpName == "N0" || OpName == "N1" || OpName == "N2" || - OpName == "N00" || OpName == "N01" || - OpName == "N10" || OpName == "N11" || - OpName == "Tmp0" || OpName == "Tmp1" || - OpName == "Tmp2" || OpName == "Tmp3"; - } - - /// DeclareSDOperand - Emit "SDOperand " or "". This works - /// around an ugly GCC bug where SelectCode is using too much stack space - void DeclareSDOperand(const std::string &OpName) const { - // If it's one of the common cases declared at the top of SelectCode, just - // use the existing declaration. - if (isPredeclaredSDOperand(OpName)) - OS << OpName; - else - OS << "SDOperand " << OpName; - } - /// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo /// if the match fails. At this point, we already know that the opcode for N /// matches, and the SDNode for the result has the RootName specified name. @@ -1926,9 +1905,8 @@ } for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { - OS << " "; - DeclareSDOperand(RootName+utostr(OpNo)); - OS << " = " << RootName << ".getOperand(" << OpNo << ");\n"; + OS << " SDOperand " << RootName << OpNo << " = " + << RootName << ".getOperand(" << OpNo << ");\n"; TreePatternNode *Child = N->getChild(i); if (!Child->isLeaf()) { @@ -1999,7 +1977,7 @@ if (HasChain) { if (!FoundChain) { - OS << " Chain = " << RootName << ".getOperand(0);\n"; + OS << " SDOperand Chain = " << RootName << ".getOperand(0);\n"; FoundChain = true; } } @@ -2039,41 +2017,30 @@ case MVT::i64: OS << " uint64_t Tmp"; break; } OS << ResNo << "C = cast(" << Val << ")->getValue();\n"; - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); - OS << " = CurDAG->getTargetConstant(Tmp" + OS << " SDOperand Tmp" << utostr(ResNo) + << " = CurDAG->getTargetConstant(Tmp" << ResNo << "C, MVT::" << getEnumName(N->getTypeNum(0)) << ");\n"; } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); - OS << " = " << Val << ";\n"; + OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; } else if (!N->isLeaf() && N->getOperator()->getName() == "tconstpool") { - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); - OS << " = " << Val << ";\n"; - } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym") { - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); - OS << " = " << Val << ";\n"; + OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){ + OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, ISE))) { std::string Fn = CP->getSelectFunc(); NumRes = CP->getNumOperands(); - for (unsigned i = 0; i != NumRes; ++i) { - if (!isPredeclaredSDOperand("Tmp" + utostr(i+ResNo))) { - OS << " "; - DeclareSDOperand("Tmp" + utostr(i+ResNo)); - OS << ";\n"; - } - } + OS << " SDOperand "; + for (unsigned i = 0; i != NumRes; ++i) + OS << "Tmp" << (i+ResNo) << ","; + OS << ";\n"; + OS << " if (!" << Fn << "(" << Val; for (unsigned i = 0; i < NumRes; i++) OS << ", Tmp" << i + ResNo; OS << ")) goto P" << PatternNo << "Fail;\n"; TmpNo = ResNo + NumRes; } else { - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); - OS << " = Select(" << Val << ");\n"; + OS << " SDOperand Tmp" << ResNo << " = Select(" << Val << ");\n"; } // Add Tmp to VariableMap, so that we don't multiply select this // value if used multiple times by this pattern result. @@ -2086,9 +2053,7 @@ if (DefInit *DI = dynamic_cast(N->getLeafValue())) { unsigned ResNo = TmpNo++; if (DI->getDef()->isSubClassOf("Register")) { - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); - OS << " = CurDAG->getRegister(" + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getRegister(" << ISE.getQualifiedName(DI->getDef()) << ", MVT::" << getEnumName(N->getTypeNum(0)) << ");\n"; @@ -2096,10 +2061,8 @@ } } else if (IntInit *II = dynamic_cast(N->getLeafValue())) { unsigned ResNo = TmpNo++; - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); assert(N->getExtTypes().size() == 1 && "Multiple types not handled!"); - OS << " = CurDAG->getTargetConstant(" + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(" << II->getValue() << ", MVT::" << getEnumName(N->getTypeNum(0)) << ");\n"; @@ -2125,7 +2088,7 @@ if (isRoot && PatternHasCtrlDep(Pattern, ISE)) HasChain = true; if (HasInFlag || HasOutFlag) - OS << " InFlag = SDOperand(0, 0);\n"; + OS << " SDOperand InFlag = SDOperand(0, 0);\n"; // Determine operand emission order. Complex pattern first. std::vector > EmitOrder; @@ -2167,9 +2130,7 @@ unsigned NumResults = Inst.getNumResults(); unsigned ResNo = TmpNo++; if (!isRoot) { - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); - OS << " = CurDAG->getTargetNode(" + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetNode(" << II.Namespace << "::" << II.TheDef->getName(); if (N->getTypeNum(0) != MVT::isVoid) OS << ", MVT::" << getEnumName(N->getTypeNum(0)); @@ -2188,7 +2149,7 @@ << NumResults << ");\n"; } } else if (HasChain || HasOutFlag) { - OS << " Result = CurDAG->getTargetNode(" + OS << " SDOperand Result = CurDAG->getTargetNode(" << II.Namespace << "::" << II.TheDef->getName(); // Output order: results, chain, flags @@ -2295,9 +2256,7 @@ assert(N->getNumChildren() == 1 && "node xform should have one child!"); unsigned OpVal = EmitResultCode(N->getChild(0)).second; unsigned ResNo = TmpNo++; - OS << " "; - DeclareSDOperand("Tmp"+utostr(ResNo)); - OS << " = Transform_" << Op->getName() + OS << " SDOperand Tmp" << ResNo << " = Transform_" << Op->getName() << "(Tmp" << OpVal << ".Val);\n"; if (isRoot) { OS << " CodeGenMap[N] = Tmp" << ResNo << ";\n"; @@ -2376,7 +2335,7 @@ } if (isRoot && HasInFlag) { - OS << " " << RootName << OpNo << " = " << RootName + OS << " SDOperand " << RootName << OpNo << " = " << RootName << ".getOperand(" << OpNo << ");\n"; OS << " InFlag = Select(" << RootName << OpNo << ");\n"; } @@ -2517,8 +2476,6 @@ << " std::map::iterator CGMI = CodeGenMap.find(N);\n" << " if (CGMI != CodeGenMap.end()) return CGMI->second;\n" << " // Work arounds for GCC stack overflow bugs.\n" - << " SDOperand N0, N1, N2, N00, N01, N10, N11, Tmp0, Tmp1, Tmp2, Tmp3;\n" - << " SDOperand Chain, InFlag, Result;\n" << " switch (N.getOpcode()) {\n" << " default: break;\n" << " case ISD::EntryToken: // These leaves remain the same.\n" @@ -2544,7 +2501,7 @@ << " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n" << " }\n" << " case ISD::CopyFromReg: {\n" - << " Chain = Select(N.getOperand(0));\n" + << " SDOperand Chain = Select(N.getOperand(0));\n" << " unsigned Reg = cast(N.getOperand(1))->getReg();\n" << " MVT::ValueType VT = N.Val->getValueType(0);\n" << " if (N.Val->getNumValues() == 2) {\n" @@ -2567,10 +2524,10 @@ << " }\n" << " }\n" << " case ISD::CopyToReg: {\n" - << " Chain = Select(N.getOperand(0));\n" + << " SDOperand Chain = Select(N.getOperand(0));\n" << " unsigned Reg = cast(N.getOperand(1))->getReg();\n" << " SDOperand Val = Select(N.getOperand(2));\n" - << " Result = N;\n" + << " SDOperand Result = N;\n" << " if (N.Val->getNumValues() == 1) {\n" << " if (Chain != N.getOperand(0) || Val != N.getOperand(2))\n" << " Result = CurDAG->getCopyToReg(Chain, Reg, Val);\n" From lattner at cs.uiuc.edu Tue Jan 3 18:25:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 18:25:11 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200601040025.SAA13063@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.120 -> 1.121 --- Log message: reduce stack usage of the recursive SelectCode function by out-lining each case of the switch statement into its own method. --- Diffs of the changes: (+61 -44) DAGISelEmitter.cpp | 105 ++++++++++++++++++++++++++++++----------------------- 1 files changed, 61 insertions(+), 44 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.120 llvm/utils/TableGen/DAGISelEmitter.cpp:1.121 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.120 Tue Jan 3 16:55:16 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue Jan 3 18:25:00 2006 @@ -2466,6 +2466,62 @@ std::string InstNS = Target.inst_begin()->second.Namespace; if (!InstNS.empty()) InstNS += "::"; + // Group the patterns by their top-level opcodes. + std::map, + CompareByRecordName> PatternsByOpcode; + for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { + TreePatternNode *Node = PatternsToMatch[i].getSrcPattern(); + if (!Node->isLeaf()) { + PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]); + } else { + const ComplexPattern *CP; + if (IntInit *II = + dynamic_cast(Node->getLeafValue())) { + PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); + } else if ((CP = NodeGetComplexPattern(Node, *this))) { + std::vector OpNodes = CP->getRootNodes(); + for (unsigned j = 0, e = OpNodes.size(); j != e; j++) { + PatternsByOpcode[OpNodes[j]].insert(PatternsByOpcode[OpNodes[j]].begin(), + &PatternsToMatch[i]); + } + } else { + std::cerr << "Unrecognized opcode '"; + Node->dump(); + std::cerr << "' on tree pattern '"; + std::cerr << PatternsToMatch[i].getDstPattern()->getOperator()->getName(); + std::cerr << "'!\n"; + exit(1); + } + } + } + + // Emit one Select_* method for each top-level opcode. We do this instead of + // emitting one giant switch statement to support compilers where this will + // result in the recursive functions taking less stack space. + for (std::map, + CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(), + E = PatternsByOpcode.end(); PBOI != E; ++PBOI) { + OS << "SDOperand Select_" << PBOI->first->getName() << "(SDOperand N) {\n"; + + const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first); + std::vector &Patterns = PBOI->second; + + // We want to emit all of the matching code now. However, we want to emit + // the matches in order of minimal cost. Sort the patterns so the least + // cost one is at the start. + std::stable_sort(Patterns.begin(), Patterns.end(), + PatternSortingPredicate(*this)); + + for (unsigned i = 0, e = Patterns.size(); i != e; ++i) + EmitCodeForPattern(*Patterns[i], OS); + + OS << " std::cerr << \"Cannot yet select: \";\n" + << " N.Val->dump(CurDAG);\n" + << " std::cerr << '\\n';\n" + << " abort();\n" + << "}\n\n"; + } + // Emit boilerplate. OS << "// The main instruction selector code.\n" << "SDOperand SelectCode(SDOperand N) {\n" @@ -2544,55 +2600,16 @@ << " }\n" << " }\n"; - // Group the patterns by their top-level opcodes. - std::map, - CompareByRecordName> PatternsByOpcode; - for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { - TreePatternNode *Node = PatternsToMatch[i].getSrcPattern(); - if (!Node->isLeaf()) { - PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]); - } else { - const ComplexPattern *CP; - if (IntInit *II = - dynamic_cast(Node->getLeafValue())) { - PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); - } else if ((CP = NodeGetComplexPattern(Node, *this))) { - std::vector OpNodes = CP->getRootNodes(); - for (unsigned j = 0, e = OpNodes.size(); j != e; j++) { - PatternsByOpcode[OpNodes[j]].insert(PatternsByOpcode[OpNodes[j]].begin(), - &PatternsToMatch[i]); - } - } else { - std::cerr << "Unrecognized opcode '"; - Node->dump(); - std::cerr << "' on tree pattern '"; - std::cerr << PatternsToMatch[i].getDstPattern()->getOperator()->getName(); - std::cerr << "'!\n"; - exit(1); - } - } - } - - // Loop over all of the case statements. + // Loop over all of the case statements, emiting a call to each method we + // emitted above. for (std::map, CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end(); PBOI != E; ++PBOI) { const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first); - std::vector &Patterns = PBOI->second; - - OS << " case " << OpcodeInfo.getEnumName() << ":\n"; - - // We want to emit all of the matching code now. However, we want to emit - // the matches in order of minimal cost. Sort the patterns so the least - // cost one is at the start. - std::stable_sort(Patterns.begin(), Patterns.end(), - PatternSortingPredicate(*this)); - - for (unsigned i = 0, e = Patterns.size(); i != e; ++i) - EmitCodeForPattern(*Patterns[i], OS); - OS << " break;\n\n"; + OS << " case " << OpcodeInfo.getEnumName() << ": " + << std::string(std::max(0, int(16-OpcodeInfo.getEnumName().size())), ' ') + << "return Select_" << PBOI->first->getName() << "(N);\n"; } - OS << " } // end of big switch.\n\n" << " std::cerr << \"Cannot yet select: \";\n" From lattner at cs.uiuc.edu Tue Jan 3 18:32:13 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 18:32:13 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200601040032.SAA13179@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.121 -> 1.122 --- Log message: Remove obsolete comment, make things look a bit nicer --- Diffs of the changes: (+1 -2) DAGISelEmitter.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.121 llvm/utils/TableGen/DAGISelEmitter.cpp:1.122 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.121 Tue Jan 3 18:25:00 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue Jan 3 18:32:01 2006 @@ -2531,7 +2531,6 @@ << " return N; // Already selected.\n\n" << " std::map::iterator CGMI = CodeGenMap.find(N);\n" << " if (CGMI != CodeGenMap.end()) return CGMI->second;\n" - << " // Work arounds for GCC stack overflow bugs.\n" << " switch (N.getOpcode()) {\n" << " default: break;\n" << " case ISD::EntryToken: // These leaves remain the same.\n" @@ -2607,7 +2606,7 @@ E = PatternsByOpcode.end(); PBOI != E; ++PBOI) { const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first); OS << " case " << OpcodeInfo.getEnumName() << ": " - << std::string(std::max(0, int(16-OpcodeInfo.getEnumName().size())), ' ') + << std::string(std::max(0, int(24-OpcodeInfo.getEnumName().size())), ' ') << "return Select_" << PBOI->first->getName() << "(N);\n"; } From lattner at cs.uiuc.edu Tue Jan 3 19:01:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 19:01:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200601040101.TAA13508@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.141 -> 1.142 --- Log message: Fix an assertion to allow constant folding of packed values --- Diffs of the changes: (+4 -3) Constants.cpp | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.141 llvm/lib/VMCore/Constants.cpp:1.142 --- llvm/lib/VMCore/Constants.cpp:1.141 Thu Dec 22 15:46:37 2005 +++ llvm/lib/VMCore/Constants.cpp Tue Jan 3 19:01:04 2006 @@ -1277,14 +1277,15 @@ case Instruction::Mul: case Instruction::Div: case Instruction::Rem: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint()) && + assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint() || + isa(C1->getType())) && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case Instruction::And: case Instruction::Or: case Instruction::Xor: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert(C1->getType()->isIntegral() && + assert((C1->getType()->isIntegral() || isa(C1->getType())) && "Tried to create a logical operation on a non-integral type!"); break; case Instruction::SetLT: case Instruction::SetGT: case Instruction::SetLE: @@ -1294,7 +1295,7 @@ case Instruction::Shl: case Instruction::Shr: assert(C2->getType() == Type::UByteTy && "Shift should be by ubyte!"); - assert(C1->getType()->isInteger() && + assert((C1->getType()->isInteger() || isa(C1->getType())) && "Tried to create a shift operation on a non-integer type!"); break; default: From lattner at cs.uiuc.edu Tue Jan 3 20:03:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 20:03:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp Message-ID: <200601040203.UAA14125@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.cpp updated: 1.76 -> 1.77 --- Log message: don't crash when trying to constant fold packed expressions. --- Diffs of the changes: (+29 -0) ConstantFolding.cpp | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.76 llvm/lib/VMCore/ConstantFolding.cpp:1.77 --- llvm/lib/VMCore/ConstantFolding.cpp:1.76 Mon May 2 22:13:01 2005 +++ llvm/lib/VMCore/ConstantFolding.cpp Tue Jan 3 20:03:29 2006 @@ -328,6 +328,29 @@ } }; +//===----------------------------------------------------------------------===// +// ConstantPackedRules Class +//===----------------------------------------------------------------------===// + +/// PackedTypeRules provides a concrete base class of ConstRules for +/// ConstantPacked operands. +/// +struct ConstantPackedRules + : public TemplateRules { +}; + + +//===----------------------------------------------------------------------===// +// GeneralPackedRules Class +//===----------------------------------------------------------------------===// + +/// GeneralPackedRules provides a concrete base class of ConstRules for +/// PackedType operands, where both operands are not ConstantPacked. The usual +/// cause for this is that one operand is a ConstantAggregateZero. +/// +struct GeneralPackedRules : public TemplateRules { +}; + //===----------------------------------------------------------------------===// // DirectRules Class @@ -487,6 +510,8 @@ static EmptyRules EmptyR; static BoolRules BoolR; static NullPointerRules NullPointerR; + static ConstantPackedRules ConstantPackedR; + static GeneralPackedRules GeneralPackedR; static DirectIntRules SByteR; static DirectIntRules UByteR; static DirectIntRules ShortR; @@ -517,6 +542,10 @@ case Type::ULongTyID: return ULongR; case Type::FloatTyID: return FloatR; case Type::DoubleTyID: return DoubleR; + case Type::PackedTyID: + if (isa(V1) && isa(V2)) + return ConstantPackedR; + return GeneralPackedR; // Constant folding rules for ConstantAggregateZero. } } From lattner at cs.uiuc.edu Tue Jan 3 20:15:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 20:15:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp Message-ID: <200601040215.UAA14261@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.cpp updated: 1.77 -> 1.78 --- Log message: implement constant folding for the element-wise binary operations --- Diffs of the changes: (+50 -0) ConstantFolding.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 50 insertions(+) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.77 llvm/lib/VMCore/ConstantFolding.cpp:1.78 --- llvm/lib/VMCore/ConstantFolding.cpp:1.77 Tue Jan 3 20:03:29 2006 +++ llvm/lib/VMCore/ConstantFolding.cpp Tue Jan 3 20:15:02 2006 @@ -332,11 +332,61 @@ // ConstantPackedRules Class //===----------------------------------------------------------------------===// +/// DoVectorOp - Given two packed constants and a function pointer, apply the +/// function pointer to each element pair, producing a new ConstantPacked +/// constant. +static Constant *EvalVectorOp(const ConstantPacked *V1, + const ConstantPacked *V2, + Constant *(*FP)(Constant*, Constant*)) { + std::vector Res; + for (unsigned i = 0, e = V1->getNumOperands(); i != e; ++i) + Res.push_back(FP(const_cast(V1->getOperand(i)), + const_cast(V2->getOperand(i)))); + return ConstantPacked::get(Res); +} + /// PackedTypeRules provides a concrete base class of ConstRules for /// ConstantPacked operands. /// struct ConstantPackedRules : public TemplateRules { + + static Constant *Add(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getAdd); + } + static Constant *Sub(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getSub); + } + static Constant *Mul(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getMul); + } + static Constant *Div(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getDiv); + } + static Constant *Rem(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getRem); + } + static Constant *And(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getAnd); + } + static Constant *Or (const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getOr); + } + static Constant *Xor(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getXor); + } + static Constant *Shl(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getShl); + } + static Constant *Shr(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getShr); + } + static Constant *LessThan(const ConstantPacked *V1, const ConstantPacked *V2){ + return 0; + } + static Constant *EqualTo(const ConstantPacked *V1, const ConstantPacked *V2) { + return 0; + } }; From lattner at cs.uiuc.edu Tue Jan 3 20:21:06 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 20:21:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp Message-ID: <200601040221.UAA14373@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.cpp updated: 1.78 -> 1.79 --- Log message: implement constant folding of ==/!= on constant packed, simplify some code. --- Diffs of the changes: (+11 -3) ConstantFolding.cpp | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.78 llvm/lib/VMCore/ConstantFolding.cpp:1.79 --- llvm/lib/VMCore/ConstantFolding.cpp:1.78 Tue Jan 3 20:15:02 2006 +++ llvm/lib/VMCore/ConstantFolding.cpp Tue Jan 3 20:20:54 2006 @@ -385,6 +385,14 @@ return 0; } static Constant *EqualTo(const ConstantPacked *V1, const ConstantPacked *V2) { + for (unsigned i = 0, e = V1->getNumOperands(); i != e; ++i) { + Constant *C = + ConstantExpr::getSetEQ(const_cast(V1->getOperand(i)), + const_cast(V2->getOperand(i))); + if (ConstantBool *CB = dyn_cast(C)) + return CB; + } + // Otherwise, could not decide from any element pairs. return 0; } }; @@ -951,15 +959,15 @@ case Instruction::SetGT: C = ConstRules::get(V1, V2).lessthan(V2, V1);break; case Instruction::SetNE: // V1 != V2 === !(V1 == V2) C = ConstRules::get(V1, V2).equalto(V1, V2); - if (C) return ConstantExpr::get(Instruction::Xor, C, ConstantBool::True); + if (C) return ConstantExpr::getNot(C); break; case Instruction::SetLE: // V1 <= V2 === !(V2 < V1) C = ConstRules::get(V1, V2).lessthan(V2, V1); - if (C) return ConstantExpr::get(Instruction::Xor, C, ConstantBool::True); + if (C) return ConstantExpr::getNot(C); break; case Instruction::SetGE: // V1 >= V2 === !(V1 < V2) C = ConstRules::get(V1, V2).lessthan(V1, V2); - if (C) return ConstantExpr::get(Instruction::Xor, C, ConstantBool::True); + if (C) return ConstantExpr::getNot(C); break; } From jeffc at jolt-lang.org Tue Jan 3 21:15:31 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Tue, 3 Jan 2006 21:15:31 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200601040315.VAA15031@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.122 -> 1.123 --- Log message: Tblgen was generating syntactically illegal C++ code like: SDOperand Tmp0,Tmp1,Tmp2,Tmp3,; GCC has a bug (24907) in which is fails to catch this, but VC++ correctly notes its illegality, so tblgen must be taught to only generate legal C++. --- Diffs of the changes: (+4 -3) DAGISelEmitter.cpp | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.122 llvm/utils/TableGen/DAGISelEmitter.cpp:1.123 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.122 Tue Jan 3 18:32:01 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue Jan 3 21:15:19 2006 @@ -2030,12 +2030,13 @@ std::string Fn = CP->getSelectFunc(); NumRes = CP->getNumOperands(); OS << " SDOperand "; - for (unsigned i = 0; i != NumRes; ++i) + unsigned i; + for (i = 0; i < NumRes - 1; ++i) OS << "Tmp" << (i+ResNo) << ","; - OS << ";\n"; + OS << "Tmp" << (i+ResNo) << ";\n"; OS << " if (!" << Fn << "(" << Val; - for (unsigned i = 0; i < NumRes; i++) + for (i = 0; i < NumRes; i++) OS << ", Tmp" << i + ResNo; OS << ")) goto P" << PatternNo << "Fail;\n"; TmpNo = ResNo + NumRes; From jeffc at jolt-lang.org Tue Jan 3 21:23:42 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Tue, 3 Jan 2006 21:23:42 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200601040323.VAA15161@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.123 -> 1.124 --- Log message: Replace fix with one less disruptive to the original code. Also note that GCC 4.1 also correctly flags the syntax error. --- Diffs of the changes: (+3 -4) DAGISelEmitter.cpp | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.123 llvm/utils/TableGen/DAGISelEmitter.cpp:1.124 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.123 Tue Jan 3 21:15:19 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue Jan 3 21:23:30 2006 @@ -2030,13 +2030,12 @@ std::string Fn = CP->getSelectFunc(); NumRes = CP->getNumOperands(); OS << " SDOperand "; - unsigned i; - for (i = 0; i < NumRes - 1; ++i) + for (unsigned i = 0; i < NumRes - 1; ++i) OS << "Tmp" << (i+ResNo) << ","; - OS << "Tmp" << (i+ResNo) << ";\n"; + OS << "Tmp" << (NumRes - 1 + ResNo) << ";\n"; OS << " if (!" << Fn << "(" << Val; - for (i = 0; i < NumRes; i++) + for (unsigned i = 0; i < NumRes; i++) OS << ", Tmp" << i + ResNo; OS << ")) goto P" << PatternNo << "Fail;\n"; TmpNo = ResNo + NumRes; From sabre at nondot.org Tue Jan 3 22:16:26 2006 From: sabre at nondot.org (Chris Lattner) Date: Tue, 3 Jan 2006 22:16:26 -0600 (CST) Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp In-Reply-To: <200601040315.VAA15031@zion.cs.uiuc.edu> References: <200601040315.VAA15031@zion.cs.uiuc.edu> Message-ID: Duh, thanks Jeffc! -Chris On Tue, 3 Jan 2006, Jeff Cohen wrote: > > > Changes in directory llvm/utils/TableGen: > > DAGISelEmitter.cpp updated: 1.122 -> 1.123 > --- > Log message: > > Tblgen was generating syntactically illegal C++ code like: > > SDOperand Tmp0,Tmp1,Tmp2,Tmp3,; > > GCC has a bug (24907) in which is fails to catch this, but VC++ correctly > notes its illegality, so tblgen must be taught to only generate legal C++. > > > > --- > Diffs of the changes: (+4 -3) > > DAGISelEmitter.cpp | 7 ++++--- > 1 files changed, 4 insertions(+), 3 deletions(-) > > > Index: llvm/utils/TableGen/DAGISelEmitter.cpp > diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.122 llvm/utils/TableGen/DAGISelEmitter.cpp:1.123 > --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.122 Tue Jan 3 18:32:01 2006 > +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue Jan 3 21:15:19 2006 > @@ -2030,12 +2030,13 @@ > std::string Fn = CP->getSelectFunc(); > NumRes = CP->getNumOperands(); > OS << " SDOperand "; > - for (unsigned i = 0; i != NumRes; ++i) > + unsigned i; > + for (i = 0; i < NumRes - 1; ++i) > OS << "Tmp" << (i+ResNo) << ","; > - OS << ";\n"; > + OS << "Tmp" << (i+ResNo) << ";\n"; > > OS << " if (!" << Fn << "(" << Val; > - for (unsigned i = 0; i < NumRes; i++) > + for (i = 0; i < NumRes; i++) > OS << ", Tmp" << i + ResNo; > OS << ")) goto P" << PatternNo << "Fail;\n"; > TmpNo = ResNo + NumRes; > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -Chris -- http://nondot.org/sabre/ http://llvm.org/ From lattner at cs.uiuc.edu Tue Jan 3 22:36:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 22:36:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/PassManagerT.h Message-ID: <200601040436.WAA15806@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.60 -> 1.61 --- Log message: patch #4 in Saem's passmanager refactoring. --- Diffs of the changes: (+50 -15) PassManagerT.h | 65 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 50 insertions(+), 15 deletions(-) Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.60 llvm/lib/VMCore/PassManagerT.h:1.61 --- llvm/lib/VMCore/PassManagerT.h:1.60 Tue Jan 3 11:52:18 2006 +++ llvm/lib/VMCore/PassManagerT.h Tue Jan 3 22:36:11 2006 @@ -620,6 +620,7 @@ // Initialize the immutable pass... IP->initializePass(); } + }; @@ -659,7 +660,10 @@ virtual const char *getPMName() const { return "BasicBlock"; } virtual const char *getPassName() const { return "BasicBlock Pass Manager"; } - + + virtual bool runOnBasicBlock(BasicBlock &BB); + + // TODO:Start absorbing PassManagerTraits }; @@ -682,7 +686,12 @@ // Implement the BasicBlockPass interface... virtual bool doInitialization(Module &M); virtual bool doInitialization(Function &F); - virtual bool runOnBasicBlock(BasicBlock &BB); + + // Forwarded + virtual bool runOnBasicBlock(BasicBlock &BB) { + return BasicBlockPassManager::runOnBasicBlock(BB); + } + virtual bool doFinalization(Function &F); virtual bool doFinalization(Module &M); @@ -728,7 +737,10 @@ virtual const char *getPMName() const { return "Function"; } virtual const char *getPassName() const { return "Function Pass Manager"; } - + + virtual bool runOnFunction(Function &F); + + // TODO:Start absorbing PassManagerTraits }; @@ -749,7 +761,12 @@ // Implement the FunctionPass interface... virtual bool doInitialization(Module &M); - virtual bool runOnFunction(Function &F); + + // Forwarded + virtual bool runOnFunction(Function &F) { + return FunctionPassManagerT::runOnFunction(F); + } + virtual bool doFinalization(Module &M); virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -762,7 +779,6 @@ } }; - //===----------------------------------------------------------------------===// // ModulePassManager // @@ -792,6 +808,8 @@ // debugging. virtual const char *getPMName() const { return "Module"; } + // runOnModule - Implement the PassManager interface. + virtual bool runOnModule(Module &M); // TODO:Start absorbing PassManagerTraits }; @@ -808,9 +826,9 @@ // runPass - Specify how the pass should be run on the UnitType static bool runPass(PassClass *P, Module *M) { return P->runOnModule(*M); } - // runOnModule - Implement the PassManager interface. + // Forwarded bool runOnModule(Module &M) { - return ((PassManagerT*)this)->runOnUnit(&M); + return ModulePassManager::runOnModule(M); } // Forwarded @@ -824,6 +842,31 @@ // PassManagerTraits Method Implementations // +// BasicBlockPassManager Implementations +// + +inline bool BasicBlockPassManager::runOnBasicBlock(BasicBlock &BB) { + return ((PMType*)this)->runOnUnit(&BB); +} + +// FunctionPassManagerT Implementations +// + +inline bool FunctionPassManagerT::runOnFunction(Function &F) { + return ((PMType*)this)->runOnUnit(&F); +} + +// ModulePassManager Implementations +// + +bool ModulePassManager::runOnModule(Module &M) { + return ((PassManagerT*)this)->runOnUnit(&M); +} + +//===----------------------------------------------------------------------===// +// PassManagerTraits Method Implementations +// + // PassManagerTraits Implementations // inline bool PassManagerTraits::doInitialization(Module &M) { @@ -840,10 +883,6 @@ return Changed; } -inline bool PassManagerTraits::runOnBasicBlock(BasicBlock &BB) { - return ((PMType*)this)->runOnUnit(&BB); -} - inline bool PassManagerTraits::doFinalization(Function &F) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) @@ -868,10 +907,6 @@ return Changed; } -inline bool PassManagerTraits::runOnFunction(Function &F) { - return ((PMType*)this)->runOnUnit(&F); -} - inline bool PassManagerTraits::doFinalization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) From lattner at cs.uiuc.edu Tue Jan 3 23:02:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 23:02:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/PassManagerT.h Message-ID: <200601040502.XAA16276@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.61 -> 1.62 --- Log message: Saem's patch #5 of the passmanager refactoring --- Diffs of the changes: (+93 -47) PassManagerT.h | 140 +++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 93 insertions(+), 47 deletions(-) Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.61 llvm/lib/VMCore/PassManagerT.h:1.62 --- llvm/lib/VMCore/PassManagerT.h:1.61 Tue Jan 3 22:36:11 2006 +++ llvm/lib/VMCore/PassManagerT.h Tue Jan 3 23:02:04 2006 @@ -136,6 +136,7 @@ // template class PassManagerT : public PassManagerTraits,public AnalysisResolver{ + // TODO:Edit these to reflect changes for world sanitisation typedef PassManagerTraits Traits; typedef typename Traits::PassClass PassClass; typedef typename Traits::SubPassClass SubPassClass; @@ -146,11 +147,17 @@ friend PassClass; friend SubPassClass; #else + // TODO:Redefine when sanitising friend class PassManagerTraits::PassClass; friend class PassManagerTraits::SubPassClass; #endif + // TODO:Redefine this when santising friend class PassManagerTraits; friend class ImmutablePass; + + friend class BasicBlockPassManager; + friend class FunctionPassManagerT; + friend class ModulePassManager; std::vector Passes; // List of passes to run std::vector ImmutablePasses; // List of immutable passes @@ -621,6 +628,8 @@ IP->initializePass(); } + // TODO: Once the world has been sanitised, the pure virtuals below can be + // brought in. }; @@ -653,6 +662,13 @@ // PMType - The type of the passmanager that subclasses this class typedef PassManagerT PMType; + + // runPass - Specify how the pass should be run on the UnitType + static bool runPass(PassClass *P, BasicBlock *M) { + // todo, init and finalize + return P->runOnBasicBlock(*M); + } + virtual ~BasicBlockPassManager() {} // getPMName() - Return the name of the unit the PassManager operates on for @@ -661,10 +677,15 @@ virtual const char *getPassName() const { return "BasicBlock Pass Manager"; } + virtual bool doInitialization(Module &M); + virtual bool doInitialization(Function &F); virtual bool runOnBasicBlock(BasicBlock &BB); + virtual bool doFinalization(Function &F); + virtual bool doFinalization(Module &M); - - // TODO:Start absorbing PassManagerTraits + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } }; @@ -679,29 +700,42 @@ public: // runPass - Specify how the pass should be run on the UnitType static bool runPass(PassClass *P, BasicBlock *M) { - // todo, init and finalize - return P->runOnBasicBlock(*M); + return BasicBlockPassManager::runPass(P,M); } - // Implement the BasicBlockPass interface... - virtual bool doInitialization(Module &M); - virtual bool doInitialization(Function &F); + // Forwarded + virtual bool doInitialization(Module &M) { + return BasicBlockPassManager::doInitialization(M); + } + + // Forwarded + virtual bool doInitialization(Function &F) { + return BasicBlockPassManager::doInitialization(F); + } // Forwarded virtual bool runOnBasicBlock(BasicBlock &BB) { return BasicBlockPassManager::runOnBasicBlock(BB); } - virtual bool doFinalization(Function &F); - virtual bool doFinalization(Module &M); + // Forwarded + virtual bool doFinalization(Function &F) { + return BasicBlockPassManager::doFinalization(F); + } + + // Forwarded + virtual bool doFinalization(Module &M) { + return BasicBlockPassManager::doFinalization(M); + } // Forwarded virtual const char *getPassName() const { return BasicBlockPassManager::getPassName(); } + // Forwarded virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); + BasicBlockPassManager::getAnalysisUsage(AU); } }; @@ -740,8 +774,18 @@ virtual bool runOnFunction(Function &F); + virtual bool doInitialization(Module &M); + + virtual bool doFinalization(Module &M); - // TODO:Start absorbing PassManagerTraits + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + + // runPass - Specify how the pass should be run on the UnitType + static bool runPass(PassClass *P, Function *F) { + return P->runOnFunction(*F); + } }; @@ -756,21 +800,27 @@ public: // runPass - Specify how the pass should be run on the UnitType static bool runPass(PassClass *P, Function *F) { - return P->runOnFunction(*F); + return FunctionPassManagerT::runPass(P,F); } - // Implement the FunctionPass interface... - virtual bool doInitialization(Module &M); + // Forwarded + virtual bool doInitialization(Module &M) { + return FunctionPassManagerT::doInitialization(M); + } // Forwarded virtual bool runOnFunction(Function &F) { return FunctionPassManagerT::runOnFunction(F); } - virtual bool doFinalization(Module &M); + // Forwarded + virtual bool doFinalization(Module &M) { + return FunctionPassManagerT::doFinalization(M); + } + // Forwarded virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); + FunctionPassManagerT::getAnalysisUsage(AU); } // Forwarded @@ -811,7 +861,9 @@ // runOnModule - Implement the PassManager interface. virtual bool runOnModule(Module &M); - // TODO:Start absorbing PassManagerTraits + // runPass - Specify how the pass should be run on the UnitType + static bool runPass(PassClass *P, Module *M) { return P->runOnModule(*M); } + }; @@ -823,8 +875,10 @@ template<> class PassManagerTraits : public ModulePass, public ModulePassManager { public: - // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Module *M) { return P->runOnModule(*M); } + // Forwarded + static bool runPass(PassClass *P, Module *M) { + return ModulePassManager::runPass(P,M); + } // Forwarded bool runOnModule(Module &M) { @@ -849,71 +903,63 @@ return ((PMType*)this)->runOnUnit(&BB); } -// FunctionPassManagerT Implementations -// - -inline bool FunctionPassManagerT::runOnFunction(Function &F) { - return ((PMType*)this)->runOnUnit(&F); -} - -// ModulePassManager Implementations -// - -bool ModulePassManager::runOnModule(Module &M) { - return ((PassManagerT*)this)->runOnUnit(&M); -} - -//===----------------------------------------------------------------------===// -// PassManagerTraits Method Implementations -// - -// PassManagerTraits Implementations -// -inline bool PassManagerTraits::doInitialization(Module &M) { +inline bool BasicBlockPassManager::doInitialization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doInitialization(M); return Changed; } -inline bool PassManagerTraits::doInitialization(Function &F) { +inline bool BasicBlockPassManager::doInitialization(Function &F) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doInitialization(F); return Changed; } -inline bool PassManagerTraits::doFinalization(Function &F) { +inline bool BasicBlockPassManager::doFinalization(Function &F) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doFinalization(F); return Changed; } -inline bool PassManagerTraits::doFinalization(Module &M) { +inline bool BasicBlockPassManager::doFinalization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doFinalization(M); return Changed; } - -// PassManagerTraits Implementations +// FunctionPassManagerT Implementations // -inline bool PassManagerTraits::doInitialization(Module &M) { + +inline bool FunctionPassManagerT::runOnFunction(Function &F) { + return ((PMType*)this)->runOnUnit(&F); +} + +inline bool FunctionPassManagerT::doInitialization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doInitialization(M); return Changed; } -inline bool PassManagerTraits::doFinalization(Module &M) { +inline bool FunctionPassManagerT::doFinalization(Module &M) { bool Changed = false; for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) ((PMType*)this)->Passes[i]->doFinalization(M); return Changed; } +// ModulePassManager Implementations +// + +bool ModulePassManager::runOnModule(Module &M) { + return ((PassManagerT*)this)->runOnUnit(&M); +} + + } // End llvm namespace #endif From lattner at cs.uiuc.edu Tue Jan 3 23:40:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 23:40:03 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/LiveVariables.h Message-ID: <200601040540.XAA16806@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveVariables.h updated: 1.26 -> 1.27 --- Log message: add a dump method to help debugging --- Diffs of the changes: (+2 -0) LiveVariables.h | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/include/llvm/CodeGen/LiveVariables.h diff -u llvm/include/llvm/CodeGen/LiveVariables.h:1.26 llvm/include/llvm/CodeGen/LiveVariables.h:1.27 --- llvm/include/llvm/CodeGen/LiveVariables.h:1.26 Thu Aug 25 00:45:31 2005 +++ llvm/include/llvm/CodeGen/LiveVariables.h Tue Jan 3 23:39:51 2006 @@ -68,6 +68,8 @@ } return false; } + + void dump() const; }; private: From lattner at cs.uiuc.edu Tue Jan 3 23:40:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 3 Jan 2006 23:40:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveVariables.cpp Message-ID: <200601040540.XAA16869@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveVariables.cpp updated: 1.53 -> 1.54 --- Log message: Add a LiveVariables::VarInfo::dump method --- Diffs of the changes: (+20 -0) LiveVariables.cpp | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+) Index: llvm/lib/CodeGen/LiveVariables.cpp diff -u llvm/lib/CodeGen/LiveVariables.cpp:1.53 llvm/lib/CodeGen/LiveVariables.cpp:1.54 --- llvm/lib/CodeGen/LiveVariables.cpp:1.53 Mon Nov 21 01:06:27 2005 +++ llvm/lib/CodeGen/LiveVariables.cpp Tue Jan 3 23:40:30 2006 @@ -35,10 +35,30 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Config/alloca.h" #include +#include using namespace llvm; static RegisterAnalysis X("livevars", "Live Variable Analysis"); +void LiveVariables::VarInfo::dump() const { + std::cerr << "Register Defined by: "; + if (DefInst) + std::cerr << *DefInst; + else + std::cerr << "\n"; + std::cerr << " Alive in blocks: "; + for (unsigned i = 0, e = AliveBlocks.size(); i != e; ++i) + if (AliveBlocks[i]) std::cerr << i << ", "; + std::cerr << "\n Killed by:"; + if (Kills.empty()) + std::cerr << " No instructions.\n"; + else { + for (unsigned i = 0, e = Kills.size(); i != e; ++i) + std::cerr << "\n #" << i << ": " << *Kills[i]; + std::cerr << "\n"; + } +} + LiveVariables::VarInfo &LiveVariables::getVarInfo(unsigned RegIdx) { assert(MRegisterInfo::isVirtualRegister(RegIdx) && "getVarInfo: not a virtual register!"); From lattner at cs.uiuc.edu Wed Jan 4 00:48:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Jan 2006 00:48:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PHIElimination.cpp VirtRegMap.cpp Message-ID: <200601040648.AAA17692@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PHIElimination.cpp updated: 1.39 -> 1.40 VirtRegMap.cpp updated: 1.42 -> 1.43 --- Log message: Add an assertion, update DefInst even though no one uses it (dangling pointers don't help anyone) --- Diffs of the changes: (+5 -0) PHIElimination.cpp | 4 ++++ VirtRegMap.cpp | 1 + 2 files changed, 5 insertions(+) Index: llvm/lib/CodeGen/PHIElimination.cpp diff -u llvm/lib/CodeGen/PHIElimination.cpp:1.39 llvm/lib/CodeGen/PHIElimination.cpp:1.40 --- llvm/lib/CodeGen/PHIElimination.cpp:1.39 Mon Oct 3 02:22:07 2005 +++ llvm/lib/CodeGen/PHIElimination.cpp Wed Jan 4 00:47:48 2006 @@ -145,6 +145,10 @@ LV->addVirtualRegisterDead(DestReg, PHICopy); LV->removeVirtualRegistersDead(MPhi); } + + // Realize that the destination register is defined by the PHI copy now, not + // the PHI itself. + LV->getVarInfo(DestReg).DefInst = PHICopy; } // Adjust the VRegPHIUseCount map to account for the removal of this PHI Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.42 llvm/lib/CodeGen/VirtRegMap.cpp:1.43 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.42 Thu Oct 6 12:19:06 2005 +++ llvm/lib/CodeGen/VirtRegMap.cpp Wed Jan 4 00:47:48 2006 @@ -393,6 +393,7 @@ // Otherwise, reload it and remember that we have it. PhysReg = VRM.getPhys(VirtReg); + assert(PhysReg && "Must map virtreg to physreg!"); const TargetRegisterClass* RC = MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); From jeffc at jolt-lang.org Wed Jan 4 00:51:33 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 4 Jan 2006 00:51:33 -0600 Subject: [llvm-commits] CVS: llvm/docs/GettingStarted.html Message-ID: <200601040651.AAA17743@zion.cs.uiuc.edu> Changes in directory llvm/docs: GettingStarted.html updated: 1.124 -> 1.125 --- Log message: Update list of supported bisons. --- Diffs of the changes: (+2 -2) GettingStarted.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.124 llvm/docs/GettingStarted.html:1.125 --- llvm/docs/GettingStarted.html:1.124 Tue Dec 20 21:46:45 2005 +++ llvm/docs/GettingStarted.html Wed Jan 4 00:51:22 2006 @@ -362,7 +362,7 @@ Bison - 1.28, 1.35, 1.75, or 2.0 (not 1.85) + 1.28, 1.35, 1.75, 1.875d, 2.0, or 2.1
(not 1.85 or 1.875) YACC compiler @@ -1546,7 +1546,7 @@ Chris Lattner
Reid Spencer
The LLVM Compiler Infrastructure
- Last modified: $Date: 2005/12/21 03:46:45 $ + Last modified: $Date: 2006/01/04 06:51:22 $ From lattner at cs.uiuc.edu Wed Jan 4 01:12:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Jan 2006 01:12:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/PHIElimination.cpp Message-ID: <200601040712.BAA17972@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: PHIElimination.cpp updated: 1.40 -> 1.41 --- Log message: Add support for targets (like Alpha) that have terminator instructions which use virtual registers. We now allow the first instruction in a block of terminators to use virtual registers, and update phi elimination to correctly update livevar when eliminating phi's. This fixes a problem on a testcase Andrew sent me. --- Diffs of the changes: (+41 -5) PHIElimination.cpp | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 41 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/PHIElimination.cpp diff -u llvm/lib/CodeGen/PHIElimination.cpp:1.40 llvm/lib/CodeGen/PHIElimination.cpp:1.41 --- llvm/lib/CodeGen/PHIElimination.cpp:1.40 Wed Jan 4 00:47:48 2006 +++ llvm/lib/CodeGen/PHIElimination.cpp Wed Jan 4 01:12:21 2006 @@ -98,6 +98,17 @@ return true; } +/// InstructionUsesRegister - Return true if the specified machine instr has a +/// use of the specified register. +static bool InstructionUsesRegister(MachineInstr *MI, unsigned SrcReg) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) + if (MI->getOperand(0).isRegister() && + MI->getOperand(0).getReg() == SrcReg && + MI->getOperand(0).isUse()) + return true; + return false; +} + /// LowerAtomicPHINode - Lower the PHI node at the top of the specified block, /// under the assuption that it needs to be lowered in a way that supports /// atomic execution of PHIs. This lowering method is always correct all of the @@ -262,12 +273,37 @@ } // Okay, if we now know that the value is not live out of the block, - // we can add a kill marker to the copy we inserted saying that it - // kills the incoming value! - // + // we can add a kill marker in this block saying that it kills the incoming + // value! if (!ValueIsLive) { - MachineBasicBlock::iterator Prev = prior(I); - LV->addVirtualRegisterKilled(SrcReg, Prev); + // In our final twist, we have to decide which instruction kills the + // register. In most cases this is the copy, however, the first + // terminator instruction at the end of the block may also use the value. + // In this case, we should mark *it* as being the killing block, not the + // copy. + bool FirstTerminatorUsesValue = false; + if (I != opBlock.end()) { + FirstTerminatorUsesValue = InstructionUsesRegister(I, SrcReg); + + // Check that no other terminators use values. +#ifndef NDEBUG + for (MachineBasicBlock::iterator TI = next(I); TI != opBlock.end(); + ++TI) { + assert(!InstructionUsesRegister(TI, SrcReg) && + "Terminator instructions cannot use virtual registers unless" + "they are the first terminator in a block!"); + } +#endif + } + + MachineBasicBlock::iterator KillInst; + if (!FirstTerminatorUsesValue) + KillInst = prior(I); + else + KillInst = I; + + // Finally, mark it killed. + LV->addVirtualRegisterKilled(SrcReg, KillInst); // This vreg no longer lives all of the way through opBlock. unsigned opBlockNum = opBlock.getNumber(); From lattner at cs.uiuc.edu Wed Jan 4 01:29:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Jan 2006 01:29:45 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/LiveVariables.h Message-ID: <200601040729.BAA18180@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: LiveVariables.h updated: 1.27 -> 1.28 --- Log message: add a comment that I should have written a long time ago --- Diffs of the changes: (+28 -0) LiveVariables.h | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+) Index: llvm/include/llvm/CodeGen/LiveVariables.h diff -u llvm/include/llvm/CodeGen/LiveVariables.h:1.27 llvm/include/llvm/CodeGen/LiveVariables.h:1.28 --- llvm/include/llvm/CodeGen/LiveVariables.h:1.27 Tue Jan 3 23:39:51 2006 +++ llvm/include/llvm/CodeGen/LiveVariables.h Wed Jan 4 01:29:33 2006 @@ -38,6 +38,34 @@ class LiveVariables : public MachineFunctionPass { public: + /// VarInfo - This represents the regions where a virtual register is live in + /// the program. We represent this with three difference pieces of + /// information: the instruction that uniquely defines the value, the set of + /// blocks the instruction is live into and live out of, and the set of + /// non-phi instructions that are the last users of the value. + /// + /// In the common case where a value is defined and killed in the same block, + /// DefInst is the defining inst, there is one killing instruction, and + /// AliveBlocks is empty. + /// + /// Otherwise, the value is live out of the block. If the value is live + /// across any blocks, these blocks are listed in AliveBlocks. Blocks where + /// the liveness range ends are not included in AliveBlocks, instead being + /// captured by the Kills set. In these blocks, the value is live into the + /// block (unless the value is defined and killed in the same block) and lives + /// until the specified instruction. Note that there cannot ever be a value + /// whose Kills set contains two instructions from the same basic block. + /// + /// PHI nodes complicate things a bit. If a PHI node is the last user of a + /// value in one of its predecessor blocks, it is not listed in the kills set, + /// but does include the predecessor block in the AliveBlocks set (unless that + /// block also defines the value). This leads to the (perfectly sensical) + /// situation where a value is defined in a block, and the last use is a phi + /// node in the successor. In this case, DefInst will be the defining + /// instruction, AliveBlocks is empty (the value is not live across any + /// blocks) and Kills is empty (phi nodes are not included). This is sensical + /// because the value must be live to the end of the block, but is not live in + /// any successor blocks. struct VarInfo { /// DefInst - The machine instruction that defines this register. /// From lattner at cs.uiuc.edu Wed Jan 4 01:47:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Jan 2006 01:47:24 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Pass.h PassManager.h Message-ID: <200601040747.BAA18367@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Pass.h updated: 1.51 -> 1.52 PassManager.h updated: 1.13 -> 1.14 --- Log message: Patch #6's in Saem's refactor-the-passmanager patch series. From him: This sanitises the world, blows away the specialisations and adds traits per passmanager type -- seemed most natural. --- Diffs of the changes: (+28 -19) Pass.h | 39 +++++++++++++++++++++++---------------- PassManager.h | 8 +++++--- 2 files changed, 28 insertions(+), 19 deletions(-) Index: llvm/include/llvm/Pass.h diff -u llvm/include/llvm/Pass.h:1.51 llvm/include/llvm/Pass.h:1.52 --- llvm/include/llvm/Pass.h:1.51 Thu Apr 21 15:11:51 2005 +++ llvm/include/llvm/Pass.h Wed Jan 4 01:47:12 2006 @@ -44,7 +44,10 @@ class AnalysisUsage; class PassInfo; class ImmutablePass; -template class PassManagerT; +template class PassManagerT; +class BasicBlockPassManager; +class FunctionPassManagerT; +class ModulePassManager; struct AnalysisResolver; // AnalysisID - Use the PassInfo to identify a pass... @@ -197,9 +200,10 @@ } private: - friend class PassManagerT; - friend class PassManagerT; - friend class PassManagerT; + template friend class PassManagerT; + friend class ModulePassManager; + friend class FunctionPassManagerT; + friend class BasicBlockPassManager; }; inline std::ostream &operator<<(std::ostream &OS, const Pass &P) { @@ -220,7 +224,7 @@ virtual bool runPass(Module &M) { return runOnModule(M); } virtual bool runPass(BasicBlock&) { return false; } - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); + virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU); }; @@ -244,8 +248,9 @@ virtual bool runOnModule(Module &M) { return false; } private: - friend class PassManagerT; - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); + template friend class PassManagerT; + friend class ModulePassManager; + virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU); }; //===----------------------------------------------------------------------===// @@ -286,11 +291,12 @@ bool run(Function &F); private: - friend class PassManagerT; - friend class PassManagerT; - friend class PassManagerT; - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); + template friend class PassManagerT; + friend class ModulePassManager; + friend class FunctionPassManagerT; + friend class BasicBlockPassManager; + virtual void addToPassManager(ModulePassManager *PM, AnalysisUsage &AU); + virtual void addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU); }; @@ -344,10 +350,11 @@ virtual bool runPass(BasicBlock &BB); private: - friend class PassManagerT; - friend class PassManagerT; - virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); - virtual void addToPassManager(PassManagerT *PM,AnalysisUsage &AU); + template friend class PassManagerT; + friend class FunctionPassManagerT; + friend class BasicBlockPassManager; + virtual void addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU); + virtual void addToPassManager(BasicBlockPassManager *PM,AnalysisUsage &AU); }; /// If the user specifies the -time-passes argument on an LLVM tool command line Index: llvm/include/llvm/PassManager.h diff -u llvm/include/llvm/PassManager.h:1.13 llvm/include/llvm/PassManager.h:1.14 --- llvm/include/llvm/PassManager.h:1.13 Thu Apr 21 15:11:51 2005 +++ llvm/include/llvm/PassManager.h Wed Jan 4 01:47:12 2006 @@ -23,10 +23,12 @@ class ModulePass; class Module; class ModuleProvider; -template class PassManagerT; +class ModulePassManager; +class FunctionPassManagerT; +class BasicBlockPassManager; class PassManager { - PassManagerT *PM; // This is a straightforward Pimpl class + ModulePassManager *PM; // This is a straightforward Pimpl class public: PassManager(); ~PassManager(); @@ -49,7 +51,7 @@ class Function; class FunctionPassManager { - PassManagerT *PM; // This is a straightforward Pimpl class + FunctionPassManagerT *PM; // This is a straightforward Pimpl class ModuleProvider *MP; public: FunctionPassManager(ModuleProvider *P); From lattner at cs.uiuc.edu Wed Jan 4 01:47:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Jan 2006 01:47:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Pass.cpp PassManagerT.h Message-ID: <200601040747.BAA18373@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Pass.cpp updated: 1.66 -> 1.67 PassManagerT.h updated: 1.62 -> 1.63 --- Log message: Patch #6's in Saem's refactor-the-passmanager patch series. From him: This sanitises the world, blows away the specialisations and adds traits per passmanager type -- seemed most natural. --- Diffs of the changes: (+157 -230) Pass.cpp | 16 +- PassManagerT.h | 371 ++++++++++++++++++++++----------------------------------- 2 files changed, 157 insertions(+), 230 deletions(-) Index: llvm/lib/VMCore/Pass.cpp diff -u llvm/lib/VMCore/Pass.cpp:1.66 llvm/lib/VMCore/Pass.cpp:1.67 --- llvm/lib/VMCore/Pass.cpp:1.66 Sun Apr 24 20:01:35 2005 +++ llvm/lib/VMCore/Pass.cpp Wed Jan 4 01:47:13 2006 @@ -78,7 +78,7 @@ // PassManager implementation - The PassManager class is a simple Pimpl class // that wraps the PassManagerT template. // -PassManager::PassManager() : PM(new PassManagerT()) {} +PassManager::PassManager() : PM(new ModulePassManager()) {} PassManager::~PassManager() { delete PM; } void PassManager::add(Pass *P) { ModulePass *MP = dynamic_cast(P); @@ -93,7 +93,7 @@ // is like PassManager, but only deals in FunctionPasses. // FunctionPassManager::FunctionPassManager(ModuleProvider *P) : - PM(new PassManagerT()), MP(P) {} + PM(new FunctionPassManagerT()), MP(P) {} FunctionPassManager::~FunctionPassManager() { delete PM; } void FunctionPassManager::add(FunctionPass *P) { PM->add(P); } void FunctionPassManager::add(ImmutablePass *IP) { PM->add(IP); } @@ -194,7 +194,7 @@ // Pass Implementation // -void ModulePass::addToPassManager(PassManagerT *PM, AnalysisUsage &AU) { +void ModulePass::addToPassManager(ModulePassManager *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } @@ -231,7 +231,7 @@ //===----------------------------------------------------------------------===// // ImmutablePass Implementation // -void ImmutablePass::addToPassManager(PassManagerT *PM, +void ImmutablePass::addToPassManager(ModulePassManager *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } @@ -264,12 +264,12 @@ return Changed | doFinalization(*F.getParent()); } -void FunctionPass::addToPassManager(PassManagerT *PM, +void FunctionPass::addToPassManager(ModulePassManager *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } -void FunctionPass::addToPassManager(PassManagerT *PM, +void FunctionPass::addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } @@ -302,12 +302,12 @@ return Changed; } -void BasicBlockPass::addToPassManager(PassManagerT *PM, +void BasicBlockPass::addToPassManager(FunctionPassManagerT *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } -void BasicBlockPass::addToPassManager(PassManagerT *PM, +void BasicBlockPass::addToPassManager(BasicBlockPassManager *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.62 llvm/lib/VMCore/PassManagerT.h:1.63 --- llvm/lib/VMCore/PassManagerT.h:1.62 Tue Jan 3 23:02:04 2006 +++ llvm/lib/VMCore/PassManagerT.h Wed Jan 4 01:47:13 2006 @@ -123,10 +123,70 @@ static TimingInfo *TheTimeInfo; -//===----------------------------------------------------------------------===// -// Declare the PassManagerTraits which will be specialized... -// -template class PassManagerTraits; // Do not define. +// FIXME:I'm not sure if this is the best way, but this was the only way I +// could get around the recursive template issues. -- Saem +struct BBTraits { + typedef BasicBlock UnitType; + + // PassClass - The type of passes tracked by this PassManager + typedef BasicBlockPass PassClass; + + // SubPassClass - The types of classes that should be collated together + // This is impossible to match, so BasicBlock instantiations of PassManagerT + // do not collate. + // + typedef BasicBlockPassManager SubPassClass; + + // BatcherClass - The type to use for collation of subtypes... This class is + // never instantiated for the PassManager, but it must be an + // instance of PassClass to typecheck. + // + typedef PassClass BatcherClass; + + // ParentClass - The type of the parent PassManager... + typedef FunctionPassManagerT ParentClass; + + // PMType - The type of this passmanager + typedef BasicBlockPassManager PMType; +}; + +struct FTraits { + typedef Function UnitType; + + // PassClass - The type of passes tracked by this PassManager + typedef FunctionPass PassClass; + + // SubPassClass - The types of classes that should be collated together + typedef BasicBlockPass SubPassClass; + + // BatcherClass - The type to use for collation of subtypes... + typedef BasicBlockPassManager BatcherClass; + + // ParentClass - The type of the parent PassManager... + typedef ModulePassManager ParentClass; + + // PMType - The type of this passmanager + typedef FunctionPassManagerT PMType; +}; + +struct MTraits { + typedef Module UnitType; + + // PassClass - The type of passes tracked by this PassManager + typedef ModulePass PassClass; + + // SubPassClass - The types of classes that should be collated together + typedef FunctionPass SubPassClass; + + // BatcherClass - The type to use for collation of subtypes... + typedef FunctionPassManagerT BatcherClass; + + // ParentClass - The type of the parent PassManager... + typedef AnalysisResolver ParentClass; + + // PMType - The type of this passmanager + typedef ModulePassManager PMType; +}; //===----------------------------------------------------------------------===// @@ -134,32 +194,26 @@ // deletes all passes contained inside of the PassManagerT, so you shouldn't // delete passes manually, and all passes should be dynamically allocated. // -template -class PassManagerT : public PassManagerTraits,public AnalysisResolver{ - // TODO:Edit these to reflect changes for world sanitisation - typedef PassManagerTraits Traits; - typedef typename Traits::PassClass PassClass; - typedef typename Traits::SubPassClass SubPassClass; - typedef typename Traits::BatcherClass BatcherClass; - typedef typename Traits::ParentClass ParentClass; - -#if defined(_MSC_VER) || defined(__INTEL_COMPILER) || defined(__HP_aCC) - friend PassClass; - friend SubPassClass; -#else - // TODO:Redefine when sanitising - friend class PassManagerTraits::PassClass; - friend class PassManagerTraits::SubPassClass; -#endif - // TODO:Redefine this when santising - friend class PassManagerTraits; +template class PassManagerT : public AnalysisResolver { + + typedef typename Trait::PassClass PassClass; + typedef typename Trait::UnitType UnitType; + typedef typename Trait::ParentClass ParentClass; + typedef typename Trait::SubPassClass SubPassClass; + typedef typename Trait::BatcherClass BatcherClass; + typedef typename Trait::PMType PMType; + + friend class ModulePass; + friend class FunctionPass; + friend class BasicBlockPass; + friend class ImmutablePass; friend class BasicBlockPassManager; friend class FunctionPassManagerT; friend class ModulePassManager; - std::vector Passes; // List of passes to run + std::vector Passes; // List of passes to run std::vector ImmutablePasses; // List of immutable passes // The parent of this pass manager... @@ -181,6 +235,18 @@ std::map LastUseOf; public: + + // getPMName() - Return the name of the unit the PassManager operates on for + // debugging. + virtual const char *getPMName() const =0; + + virtual const char *getPassName() const =0; + + virtual bool runPass(PassClass *P, UnitType *M) =0; + + // TODO:Figure out what pure virtuals remain. + + PassManagerT(ParentClass *Par = 0) : Parent(Par), Batcher(0) {} virtual ~PassManagerT() { // Delete all of the contained passes... @@ -221,7 +287,7 @@ LastUserOf[I->second].push_back(I->first); // Output debug information... - if (Parent == 0) PMDebug::PerformPassStartupStuff(this); + if (Parent == 0) PMDebug::PerformPassStartupStuff((dynamic_cast(this))); // Run all of the passes for (unsigned i = 0, e = Passes.size(); i < e; ++i) { @@ -337,7 +403,7 @@ for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) ImmutablePasses[i]->dumpPassStructure(0); - std::cerr << std::string(Offset*2, ' ') << Traits::getPMName() + std::cerr << std::string(Offset*2, ' ') << this->getPMName() << " Pass Manager\n"; for (typename std::vector::iterator I = Passes.begin(), E = Passes.end(); I != E; ++I) { @@ -425,7 +491,7 @@ // frees the analysis AFTER this pass manager runs. // if (Parent) { - Parent->markPassUsed(P, this); + Parent->markPassUsed(P, dynamic_cast(this)); } else { assert(getAnalysisOrNullUp(P) && dynamic_cast(getAnalysisOrNullUp(P)) && @@ -473,7 +539,7 @@ // depends on the class of the pass, and is critical to laying out passes in // an optimal order.. // - P->addToPassManager(this, AnUsage); + P->addToPassManager(dynamic_cast(this), AnUsage); } // add - H4x0r an ImmutablePass into a PassManager that might not be @@ -566,14 +632,14 @@ // For now assume that our results are never used... LastUseOf[P] = P; } - + // For FunctionPass subclasses, we must be sure to batch the FunctionPass's // together in a BatcherClass object so that all of the analyses are run // together a function at a time. // void addPass(SubPassClass *MP, AnalysisUsage &AnUsage) { if (Batcher == 0) // If we don't have a batcher yet, make one now. - Batcher = new BatcherClass(this); + Batcher = new BatcherClass((dynamic_cast(this))); // The Batcher will queue the passes up MP->addToPassManager(Batcher, AnUsage); } @@ -627,48 +693,33 @@ // Initialize the immutable pass... IP->initializePass(); } - - // TODO: Once the world has been sanitised, the pure virtuals below can be - // brought in. + }; - //===----------------------------------------------------------------------===// // BasicBlockPassManager // // This pass manager is used to group together all of the BasicBlockPass's // into a single unit. // -class BasicBlockPassManager { +class BasicBlockPassManager : public BasicBlockPass, + public BBTraits, + public PassManagerT { public: - // PassClass - The type of passes tracked by this PassManager - typedef BasicBlockPass PassClass; - - // SubPassClass - The types of classes that should be collated together - // This is impossible to match, so BasicBlock instantiations of PassManagerT - // do not collate. - // - typedef PassManagerT SubPassClass; - - // BatcherClass - The type to use for collation of subtypes... This class is - // never instantiated for the PassManager, but it must be an - // instance of PassClass to typecheck. - // - typedef PassClass BatcherClass; - - // ParentClass - The type of the parent PassManager... - typedef PassManagerT ParentClass; - - // PMType - The type of the passmanager that subclasses this class - typedef PassManagerT PMType; - + BasicBlockPassManager(BBTraits::ParentClass* PC) : + PassManagerT(PC) { + } + + BasicBlockPassManager(BasicBlockPassManager* BBPM) : + PassManagerT(BBPM->Parent) { + } // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, BasicBlock *M) { - // todo, init and finalize + virtual bool runPass(BBTraits::PassClass *P, BasicBlock *M) { + // TODO: init and finalize return P->runOnBasicBlock(*M); } - + virtual ~BasicBlockPassManager() {} // getPMName() - Return the name of the unit the PassManager operates on for @@ -688,84 +739,27 @@ } }; - //===----------------------------------------------------------------------===// -// PassManagerTraits Specialization +// FunctionPassManager // -// This pass manager is used to group together all of the BasicBlockPass's +// This pass manager is used to group together all of the FunctionPass's // into a single unit. // -template<> class PassManagerTraits : public BasicBlockPass, - public BasicBlockPassManager { +class FunctionPassManagerT : public FunctionPass, + public FTraits, + public PassManagerT { public: - // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, BasicBlock *M) { - return BasicBlockPassManager::runPass(P,M); - } - - // Forwarded - virtual bool doInitialization(Module &M) { - return BasicBlockPassManager::doInitialization(M); - } - - // Forwarded - virtual bool doInitialization(Function &F) { - return BasicBlockPassManager::doInitialization(F); - } - - // Forwarded - virtual bool runOnBasicBlock(BasicBlock &BB) { - return BasicBlockPassManager::runOnBasicBlock(BB); - } - - // Forwarded - virtual bool doFinalization(Function &F) { - return BasicBlockPassManager::doFinalization(F); - } + FunctionPassManagerT() : PassManagerT(0) {} - // Forwarded - virtual bool doFinalization(Module &M) { - return BasicBlockPassManager::doFinalization(M); - } + // Parent constructor + FunctionPassManagerT(FTraits::ParentClass* PC) : PassManagerT(PC) {} - // Forwarded - virtual const char *getPassName() const { - return BasicBlockPassManager::getPassName(); + FunctionPassManagerT(FunctionPassManagerT* FPM) : + PassManagerT(FPM->Parent) { } - // Forwarded - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - BasicBlockPassManager::getAnalysisUsage(AU); - } - -}; - - -//===----------------------------------------------------------------------===// -// FunctionPassManager -// -// This pass manager is used to group together all of the FunctionPass's -// into a single unit. -// -class FunctionPassManagerT { -public: - // PassClass - The type of passes tracked by this PassManager - typedef FunctionPass PassClass; - - // SubPassClass - The types of classes that should be collated together - typedef BasicBlockPass SubPassClass; - - // BatcherClass - The type to use for collation of subtypes... - typedef PassManagerT BatcherClass; - - // ParentClass - The type of the parent PassManager... - typedef PassManagerT ParentClass; - - // PMType - The type of the passmanager that subclasses this class - typedef PassManagerT PMType; - virtual ~FunctionPassManagerT() {} - + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPMName() const { return "Function"; } @@ -783,73 +777,32 @@ } // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Function *F) { + virtual bool runPass(FTraits::PassClass *P, Function *F) { return P->runOnFunction(*F); } }; //===----------------------------------------------------------------------===// -// PassManagerTraits Specialization +// ModulePassManager // -// This pass manager is used to group together all of the FunctionPass's -// into a single unit. +// This is the top level PassManager implementation that holds generic passes. // -template<> class PassManagerTraits : public FunctionPass, - public FunctionPassManagerT { +class ModulePassManager : public ModulePass, + public MTraits, + public PassManagerT { public: - // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Function *F) { - return FunctionPassManagerT::runPass(P,F); - } - - // Forwarded - virtual bool doInitialization(Module &M) { - return FunctionPassManagerT::doInitialization(M); - } + ModulePassManager() : PassManagerT(0) {} - // Forwarded - virtual bool runOnFunction(Function &F) { - return FunctionPassManagerT::runOnFunction(F); - } + // Batcher Constructor + ModulePassManager(MTraits::ParentClass* PC) : PassManagerT(PC) {} - // Forwarded - virtual bool doFinalization(Module &M) { - return FunctionPassManagerT::doFinalization(M); + ModulePassManager(ModulePassManager* MPM) : + PassManagerT((MPM->Parent)) { } - // Forwarded - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - FunctionPassManagerT::getAnalysisUsage(AU); - } - - // Forwarded - virtual const char *getPassName() const { - return FunctionPassManagerT::getPassName(); - } -}; - -//===----------------------------------------------------------------------===// -// ModulePassManager -// -// This is the top level PassManager implementation that holds generic passes. -// -class ModulePassManager { -public: - // PassClass - The type of passes tracked by this PassManager - typedef ModulePass PassClass; - - // SubPassClass - The types of classes that should be collated together - typedef FunctionPass SubPassClass; - - // BatcherClass - The type to use for collation of subtypes... - typedef PassManagerT BatcherClass; - - // ParentClass - The type of the parent PassManager... - typedef AnalysisResolver ParentClass; - virtual ~ModulePassManager() {} - + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPassName() const { return "Module Pass Manager"; } @@ -862,36 +815,10 @@ virtual bool runOnModule(Module &M); // runPass - Specify how the pass should be run on the UnitType - static bool runPass(PassClass *P, Module *M) { return P->runOnModule(*M); } + virtual bool runPass(MTraits::PassClass *P, Module *M) { return P->runOnModule(*M); } }; - -//===----------------------------------------------------------------------===// -// PassManagerTraits Specialization -// -// This is the top level PassManager implementation that holds generic passes. -// -template<> class PassManagerTraits : public ModulePass, - public ModulePassManager { -public: - // Forwarded - static bool runPass(PassClass *P, Module *M) { - return ModulePassManager::runPass(P,M); - } - - // Forwarded - bool runOnModule(Module &M) { - return ModulePassManager::runOnModule(M); - } - - // Forwarded - virtual const char *getPassName() const { - return ModulePassManager::getPassName(); - } -}; - - //===----------------------------------------------------------------------===// // PassManagerTraits Method Implementations // @@ -900,34 +827,34 @@ // inline bool BasicBlockPassManager::runOnBasicBlock(BasicBlock &BB) { - return ((PMType*)this)->runOnUnit(&BB); + return ((BBTraits::PMType*)this)->runOnUnit(&BB); } inline bool BasicBlockPassManager::doInitialization(Module &M) { bool Changed = false; - for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) - ((PMType*)this)->Passes[i]->doInitialization(M); + for (unsigned i = 0, e = ((BBTraits::PMType*)this)->Passes.size(); i != e; ++i) + ((BBTraits::PMType*)this)->Passes[i]->doInitialization(M); return Changed; } inline bool BasicBlockPassManager::doInitialization(Function &F) { bool Changed = false; - for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) - ((PMType*)this)->Passes[i]->doInitialization(F); + for (unsigned i = 0, e = ((BBTraits::PMType*)this)->Passes.size(); i != e; ++i) + ((BBTraits::PMType*)this)->Passes[i]->doInitialization(F); return Changed; } inline bool BasicBlockPassManager::doFinalization(Function &F) { bool Changed = false; - for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) - ((PMType*)this)->Passes[i]->doFinalization(F); + for (unsigned i = 0, e = ((BBTraits::PMType*)this)->Passes.size(); i != e; ++i) + ((BBTraits::PMType*)this)->Passes[i]->doFinalization(F); return Changed; } inline bool BasicBlockPassManager::doFinalization(Module &M) { bool Changed = false; - for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) - ((PMType*)this)->Passes[i]->doFinalization(M); + for (unsigned i=0, e = ((BBTraits::PMType*)this)->Passes.size(); i != e; ++i) + ((BBTraits::PMType*)this)->Passes[i]->doFinalization(M); return Changed; } @@ -935,20 +862,20 @@ // inline bool FunctionPassManagerT::runOnFunction(Function &F) { - return ((PMType*)this)->runOnUnit(&F); + return ((FTraits::PMType*)this)->runOnUnit(&F); } inline bool FunctionPassManagerT::doInitialization(Module &M) { bool Changed = false; - for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) - ((PMType*)this)->Passes[i]->doInitialization(M); + for (unsigned i=0, e = ((FTraits::PMType*)this)->Passes.size(); i != e; ++i) + ((FTraits::PMType*)this)->Passes[i]->doInitialization(M); return Changed; } inline bool FunctionPassManagerT::doFinalization(Module &M) { bool Changed = false; - for (unsigned i = 0, e = ((PMType*)this)->Passes.size(); i != e; ++i) - ((PMType*)this)->Passes[i]->doFinalization(M); + for (unsigned i=0, e = ((FTraits::PMType*)this)->Passes.size(); i != e; ++i) + ((FTraits::PMType*)this)->Passes[i]->doFinalization(M); return Changed; } @@ -956,7 +883,7 @@ // bool ModulePassManager::runOnModule(Module &M) { - return ((PassManagerT*)this)->runOnUnit(&M); + return ((PassManagerT*)this)->runOnUnit(&M); } From jlaskey at apple.com Wed Jan 4 07:36:59 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:36:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineDebugInfo.cpp Message-ID: <200601041336.HAA29869@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineDebugInfo.cpp added (r1.1) --- Log message: Extending MachineDebugInfo. --- Diffs of the changes: (+90 -0) MachineDebugInfo.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 90 insertions(+) Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -c /dev/null llvm/lib/CodeGen/MachineDebugInfo.cpp:1.1 *** /dev/null Wed Jan 4 07:36:49 2006 --- llvm/lib/CodeGen/MachineDebugInfo.cpp Wed Jan 4 07:36:38 2006 *************** *** 0 **** --- 1,90 ---- + //===-- llvm/CodeGen/MachineDebugInfo.cpp -----------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by James M. Laskey and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // Collect debug information for a module. This information should be in a + // neutral form that can be used by different debugging schemes. + // + //===----------------------------------------------------------------------===// + + #include "llvm/CodeGen/MachineDebugInfo.h" + + using namespace llvm; + + // Handle the Pass registration stuff necessary to use TargetData's. + namespace { + RegisterPass X("machinedebuginfo", "Debug Information", + PassInfo::Analysis | PassInfo::Optimization); + } + + namespace llvm { + + /// DebugInfo - Keep track of debug information for the function. + /// + // FIXME - making it global until we can find a proper place to hang it from. + MachineDebugInfo *DebugInfo; + + // FIXME - temporary hack until we can find a place to hand debug info from. + ModulePass *createDebugInfoPass() { + if (!DebugInfo) DebugInfo = new MachineDebugInfo(); + return (ModulePass *)DebugInfo; + } + + /// getDebugInfo - Returns the DebugInfo. + MachineDebugInfo &getMachineDebugInfo() { + assert(DebugInfo && "DebugInfo pass not created"); + return *DebugInfo; + } + + /// doInitialization - Initialize the debug state for a new module. + /// + bool MachineDebugInfo::doInitialization() { + return true; + } + + /// doFinalization - Tear down the debug state after completion of a module. + /// + bool MachineDebugInfo::doFinalization() { + return true; + } + + /// RecordSource - Register a source file with debug info. Returns an id. + /// + unsigned MachineDebugInfo::RecordSource(std::string fname, + std::string dirname) { + // Compose a key + std::string path = dirname + "/" + fname; + // Check if the source file is already recorded + StrIntMapIter SMI = SourceMap.find(path); + // If already there return existing id + if (SMI != SourceMap.end()) return SMI->second; + // Bump up the count + ++SourceCount; + // Record the count + SourceMap[path] = SourceCount; + // Return id + return SourceCount; + } + + /// getSourceFiles - Return a vector of files. Vector index + 1 equals id. + /// + std::vector MachineDebugInfo::getSourceFiles() { + std::vector Sources(SourceCount); + + for (StrIntMapIter SMI = SourceMap.begin(), E = SourceMap.end(); SMI != E; + SMI++) { + unsigned Index = SMI->second - 1; + std::string Path = SMI->first; + Sources[Index] = Path; + } + return Sources; + } + + + }; + From jlaskey at apple.com Wed Jan 4 07:37:44 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:37:44 -0600 Subject: [llvm-commits] CVS: llvm/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200601041337.HAA29886@zion.cs.uiuc.edu> Changes in directory llvm/Xcode/LLVM.xcodeproj: project.pbxproj updated: 1.15 -> 1.16 --- Log message: Adding new files. --- Diffs of the changes: (+4 -0) project.pbxproj | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/Xcode/LLVM.xcodeproj/project.pbxproj diff -u llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.15 llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.16 --- llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.15 Wed Dec 21 14:47:34 2005 +++ llvm/Xcode/LLVM.xcodeproj/project.pbxproj Wed Jan 4 07:37:32 2006 @@ -113,6 +113,8 @@ CF490D890906A78C0072DB1C /* PPC.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PPC.td; sourceTree = ""; }; CF490E2F0907BBF80072DB1C /* SubtargetEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtargetEmitter.h; sourceTree = ""; }; CF490E300907BBF80072DB1C /* SubtargetEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtargetEmitter.cpp; sourceTree = ""; }; + CF6529A6095B21A8007F884E /* MachineDebugInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachineDebugInfo.cpp; sourceTree = ""; }; + CF6B5AFD095C82C300D1EA42 /* DAGCombiner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DAGCombiner.cpp; sourceTree = ""; }; CF6F487109505E1500BC9E82 /* MachineDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachineDebugInfo.h; sourceTree = ""; }; CF9BCD0808C74DE0001E7011 /* SubtargetFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtargetFeature.h; sourceTree = ""; }; CF9BCD1508C75070001E7011 /* SubtargetFeature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtargetFeature.cpp; sourceTree = ""; }; @@ -1136,6 +1138,7 @@ DE66ED7508ABEC2B00323D32 /* LiveVariables.cpp */, DE66ED7608ABEC2B00323D32 /* MachineBasicBlock.cpp */, DE66ED7708ABEC2B00323D32 /* MachineCodeEmitter.cpp */, + CF6529A6095B21A8007F884E /* MachineDebugInfo.cpp */, DE66ED7808ABEC2B00323D32 /* MachineFunction.cpp */, DE66ED7908ABEC2B00323D32 /* MachineInstr.cpp */, DE66ED7B08ABEC2B00323D32 /* Passes.cpp */, @@ -1158,6 +1161,7 @@ DE66ED8308ABEC2B00323D32 /* SelectionDAG */ = { isa = PBXGroup; children = ( + CF6B5AFD095C82C300D1EA42 /* DAGCombiner.cpp */, DE66ED9008ABEC2B00323D32 /* LegalizeDAG.cpp */, DE694D9F08B51E0C0039C106 /* ScheduleDAG.cpp */, DE66ED9208ABEC2B00323D32 /* SelectionDAG.cpp */, From jlaskey at apple.com Wed Jan 4 07:42:15 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:42:15 -0600 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200601041342.HAA29939@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.123 -> 1.124 --- Log message: Adding MachineDebugInfo as a immutable pass. --- Diffs of the changes: (+4 -0) llc.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.123 llvm/tools/llc/llc.cpp:1.124 --- llvm/tools/llc/llc.cpp:1.123 Thu Dec 29 20:50:44 2005 +++ llvm/tools/llc/llc.cpp Wed Jan 4 07:42:02 2006 @@ -27,6 +27,7 @@ #include "llvm/Support/FileUtilities.h" #include "llvm/Analysis/Verifier.h" #include "llvm/System/Signals.h" +#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/Config/config.h" #include #include @@ -237,6 +238,9 @@ sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } } + + // Set up collection of debug information + Passes.add(createDebugInfoPass()); // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) { From jlaskey at apple.com Wed Jan 4 07:43:11 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:43:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200601041343.HAA29957@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.249 -> 1.250 --- Log message: Change how MachineDebugInfo is fetched. --- Diffs of the changes: (+1 -1) LegalizeDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.249 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.250 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.249 Sat Dec 24 19:07:37 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jan 4 07:42:59 2006 @@ -619,7 +619,7 @@ default: assert(0 && "This action is not supported yet!"); case TargetLowering::Expand: { if (TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other)) { - MachineDebugInfo &DebugInfo = DAG.getMachineFunction().getDebugInfo(); + MachineDebugInfo &DebugInfo = getMachineDebugInfo(); std::vector Ops; Ops.push_back(Tmp1); // chain Ops.push_back(Node->getOperand(1)); // line # From jlaskey at apple.com Wed Jan 4 07:44:08 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:44:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineFunction.cpp Message-ID: <200601041344.HAA29977@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineFunction.cpp updated: 1.82 -> 1.83 --- Log message: Moving MachineDebugInfo to module level location. --- Diffs of the changes: (+1 -1) MachineFunction.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/MachineFunction.cpp diff -u llvm/lib/CodeGen/MachineFunction.cpp:1.82 llvm/lib/CodeGen/MachineFunction.cpp:1.83 --- llvm/lib/CodeGen/MachineFunction.cpp:1.82 Fri Dec 16 16:45:28 2005 +++ llvm/lib/CodeGen/MachineFunction.cpp Wed Jan 4 07:43:56 2006 @@ -108,7 +108,7 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM) - : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0), DebugInfo() { + : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) { SSARegMapping = new SSARegMap(); MFInfo = 0; FrameInfo = new MachineFrameInfo(); From jlaskey at apple.com Wed Jan 4 07:44:54 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:44:54 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineFunction.h Message-ID: <200601041344.HAA29993@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineFunction.h updated: 1.56 -> 1.57 --- Log message: Move MachineDebugInfo to module level location. --- Diffs of the changes: (+0 -9) MachineFunction.h | 9 --------- 1 files changed, 9 deletions(-) Index: llvm/include/llvm/CodeGen/MachineFunction.h diff -u llvm/include/llvm/CodeGen/MachineFunction.h:1.56 llvm/include/llvm/CodeGen/MachineFunction.h:1.57 --- llvm/include/llvm/CodeGen/MachineFunction.h:1.56 Fri Dec 16 16:45:28 2005 +++ llvm/include/llvm/CodeGen/MachineFunction.h Wed Jan 4 07:44:43 2006 @@ -114,10 +114,6 @@ std::vector > LiveIns; std::vector LiveOuts; - /// DebugInfo - Keep track of debug information for the function. - /// - MachineDebugInfo DebugInfo; - public: MachineFunction(const Function *Fn, const TargetMachine &TM); ~MachineFunction(); @@ -218,11 +214,6 @@ return MBBNumbering.back(); } - /// getDebugInfo - Returns the DebugInfo. - MachineDebugInfo &getDebugInfo() { - return DebugInfo; - } - /// print - Print out the MachineFunction in a format suitable for debugging /// to the specified stream. /// From jlaskey at apple.com Wed Jan 4 07:46:49 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:46:49 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200601041346.HAA30023@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.1 -> 1.2 --- Log message: 1. Make MachineDebugInfo a pass. 2. Add label uniquing code. --- Diffs of the changes: (+21 -31) MachineDebugInfo.h | 52 +++++++++++++++++++++------------------------------- 1 files changed, 21 insertions(+), 31 deletions(-) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.1 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.2 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.1 Fri Dec 16 16:45:28 2005 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Jan 4 07:46:37 2006 @@ -15,6 +15,7 @@ #ifndef LLVM_CODEGEN_MACHINEDEBUGINFO_H #define LLVM_CODEGEN_MACHINEDEBUGINFO_H +#include "llvm/Pass.h" #include #include #include @@ -25,7 +26,7 @@ /// module. Queries can be made by different debugging schemes and reformated /// for specific use. /// -class MachineDebugInfo { +class MachineDebugInfo : public ImmutablePass { private: // convenience types typedef std::map StrIntMap; @@ -34,46 +35,35 @@ StrIntMap SourceMap; // Map of source file path to id unsigned SourceCount; // Number of source files (used to // generate id) + unsigned UniqueID; // Number used to unique labels used + // by debugger. public: // Ctor. - MachineDebugInfo() : SourceMap(), SourceCount(0) {} + MachineDebugInfo() + : SourceMap() + , SourceCount(0) + , UniqueID(1) + {} + ~MachineDebugInfo() { } - /// RecordSource - Register a source file with debug info. Returns an id. + /// NextUniqueID - Returns a unique number for labels used by debugger. /// - unsigned RecordSource(std::string fname, std::string dirname) { - // Compose a key - std::string path = dirname + "/" + fname; - // Check if the source file is already recorded - StrIntMapIter SMI = SourceMap.find(path); - // If already there return existing id - if (SMI != SourceMap.end()) return SMI->second; - // Bump up the count - ++SourceCount; - // Record the count - SourceMap[path] = SourceCount; - // Return id - return SourceCount; - } - - /// getSourceFiles - Return a vector of files. Vector index + 1 equals id. - /// - std::vector getSourceFiles() { - std::vector Sources(SourceCount); - - for (StrIntMapIter SMI = SourceMap.begin(), E = SourceMap.end(); SMI != E; - SMI++) { - unsigned Index = SMI->second - 1; - std::string Path = SMI->first; - Sources[Index] = Path; - } - return Sources; - } + unsigned NextUniqueID() { return UniqueID++; } + + bool doInitialization(); + bool doFinalization(); + unsigned RecordSource(std::string fname, std::string dirname); + std::vector getSourceFiles(); }; // End class MachineDebugInfo //===----------------------------------------------------------------------===// +// FIXME - temporary hack until we can find a place to hang debug info from. +MachineDebugInfo &getMachineDebugInfo(); +// FIXME - temporary hack until we can find a place to hand debug info from. +ModulePass *createDebugInfoPass(); } // End llvm namespace From jlaskey at apple.com Wed Jan 4 07:52:42 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:52:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCTargetMachine.cpp Message-ID: <200601041352.HAA30088@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.133 -> 1.134 PPCTargetMachine.cpp updated: 1.77 -> 1.78 --- Log message: Tie dwarf generation to darwin assembler. --- Diffs of the changes: (+35 -9) PPCAsmPrinter.cpp | 42 ++++++++++++++++++++++++++++++++++-------- PPCTargetMachine.cpp | 2 +- 2 files changed, 35 insertions(+), 9 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.133 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.134 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.133 Fri Dec 23 19:00:15 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Wed Jan 4 07:52:30 2006 @@ -25,6 +25,7 @@ #include "llvm/Module.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/DwarfWriter.h" #include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" @@ -205,13 +206,33 @@ virtual bool doFinalization(Module &M) = 0; }; + /// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X + /// + struct DarwinDwarfWriter : public DwarfWriter { + // Ctor. + DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di) + : DwarfWriter(o, ap, di) + { + hasLEB128 = false; + needsSet = true; + DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev,regular,debug"; + DwarfInfoSection = ".section __DWARFA,__debug_info,regular,debug"; + DwarfLineSection = ".section __DWARFA,__debug_line,regular,debug"; + } + }; + /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS /// X /// struct DarwinAsmPrinter : public PPCAsmPrinter { + + DarwinDwarfWriter DW; DarwinAsmPrinter(std::ostream &O, TargetMachine &TM) - : PPCAsmPrinter(O, TM) { + : PPCAsmPrinter(O, TM), + // FIXME - MachineDebugInfo needs a proper location + DW(O, this, getMachineDebugInfo()) + { CommentString = ";"; GlobalPrefix = "_"; PrivateGlobalPrefix = "L"; // Marker for constant pool idxs @@ -397,12 +418,8 @@ SetupMachineFunction(MF); O << "\n\n"; - // Print out dwarf file info - MachineDebugInfo &DebugInfo = MF.getDebugInfo(); - std::vector Sources = DebugInfo.getSourceFiles(); - for (unsigned i = 0, N = Sources.size(); i < N; i++) { - O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i] << "\"" << "\n"; - } + // Emit pre-function debug information. + DW.BeginFunction(); // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); @@ -449,6 +466,9 @@ } } + // Emit post-function debug information. + DW.EndFunction(); + // We didn't modify anything. return false; } @@ -461,6 +481,9 @@ // Darwin wants symbols to be quoted if they have complex names. Mang->setUseQuotes(true); + + // Emit initial debug information. + DW.BeginModule(); return false; } @@ -583,6 +606,9 @@ // code that does this, it is always safe to set. O << "\t.subsections_via_symbols\n"; + // Emit initial debug information. + DW.EndModule(); + AsmPrinter::doFinalization(M); return false; // success } @@ -592,7 +618,7 @@ /// bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) { SetupMachineFunction(MF); - + // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.77 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.78 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.77 Mon Nov 7 20:12:47 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Wed Jan 4 07:52:30 2006 @@ -80,7 +80,7 @@ CodeGenFileType FileType, bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; - + // Run loop strength reduction before anything else. if (!Fast) PM.add(createLoopStrengthReducePass()); From jlaskey at apple.com Wed Jan 4 07:52:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:52:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp DwarfWriter.cpp Message-ID: <200601041352.HAA30096@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.34 -> 1.35 DwarfWriter.cpp updated: 1.2 -> 1.3 --- Log message: Tie dwarf generation to darwin assembler. --- Diffs of the changes: (+96 -0) AsmPrinter.cpp | 1 DwarfWriter.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.34 llvm/lib/CodeGen/AsmPrinter.cpp:1.35 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.34 Wed Dec 28 00:29:02 2005 +++ llvm/lib/CodeGen/AsmPrinter.cpp Wed Jan 4 07:52:30 2006 @@ -16,6 +16,7 @@ #include "llvm/Constants.h" #include "llvm/Module.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetMachine.h" Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.2 llvm/lib/CodeGen/DwarfWriter.cpp:1.3 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.2 Wed Dec 21 19:41:00 2005 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Jan 4 07:52:30 2006 @@ -12,4 +12,99 @@ //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DwarfWriter.h" +#include "llvm/Support/CommandLine.h" + + +namespace llvm { + +static cl::opt +DwarfVerbose("dwarf-verbose", cl::Hidden, + cl::desc("Add comments to dwarf directives.")); + +/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an +/// unsigned leb128 value. +/// +void DwarfWriter::EmitULEB128Bytes(unsigned Value, std::string Comment) { + if (hasLEB128) { + O << "\t.uleb128\t" + << Value; + } else { + O << Asm->getData8bitsDirective(); + EmitULEB128(Value); + } + if (DwarfVerbose) { + O << "\t" + << Asm->getCommentString() + << " " + << Comment + << " " + << Value; + } + O << "\n"; +} + +/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a +/// signed leb128 value. +/// +void DwarfWriter::EmitSLEB128Bytes(int Value, std::string Comment) { + if (hasLEB128) { + O << "\t.sleb128\t" + << Value; + } else { + O << Asm->getData8bitsDirective(); + EmitSLEB128(Value); + } + if (DwarfVerbose) { + O << "\t" + << Asm->getCommentString() + << " " + << Comment + << " " + << Value; + } + O << "\n"; +} + +/// BeginModule - Emit all dwarf sections that should come prior to the content. +/// +void DwarfWriter::BeginModule() { + EmitComment("Dwarf Begin Module"); + + // define base addresses for dwarf sections + Asm->SwitchSection(DwarfAbbrevSection, 0); + EmitLabel("abbrev", 0); + Asm->SwitchSection(DwarfInfoSection, 0); + EmitLabel("info", 0); + Asm->SwitchSection(DwarfLineSection, 0); + EmitLabel("line", 0); +} + +/// EndModule - Emit all dwarf sections that should come after the content. +/// +void DwarfWriter::EndModule() { + EmitComment("Dwarf End Module"); + // Print out dwarf file info + std::vector Sources = DebugInfo.getSourceFiles(); + for (unsigned i = 0, N = Sources.size(); i < N; i++) { + O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i] << "\"" << "\n"; + } +} + + +/// BeginFunction - Emit pre-function debug information. +/// +void DwarfWriter::BeginFunction() { + EmitComment("Dwarf Begin Function"); +} + +/// EndFunction - Emit post-function debug information. +/// +void DwarfWriter::EndFunction() { + EmitComment("Dwarf End Function"); +} + + +} // End llvm namespace + From jlaskey at apple.com Wed Jan 4 07:52:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 07:52:43 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h DwarfWriter.h Message-ID: <200601041352.HAA30098@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.23 -> 1.24 DwarfWriter.h updated: 1.3 -> 1.4 --- Log message: Tie dwarf generation to darwin assembler. --- Diffs of the changes: (+180 -3) AsmPrinter.h | 41 ++++++++++++++++ DwarfWriter.h | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 180 insertions(+), 3 deletions(-) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.23 llvm/include/llvm/CodeGen/AsmPrinter.h:1.24 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.23 Tue Dec 13 00:31:41 2005 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Wed Jan 4 07:52:30 2006 @@ -35,7 +35,7 @@ /// IncrementFunctionNumber(). /// unsigned FunctionNumber; - + protected: /// Output stream on which we're printing assembly code. /// @@ -165,6 +165,7 @@ AsmPrinter(std::ostream &o, TargetMachine &TM); + public: /// SwitchSection - Switch to the specified section of the executable if we /// are not already in it! If GV is non-null and if the global has an /// explicitly requested section, we switch to the section indicated for the @@ -175,6 +176,7 @@ /// void SwitchSection(const char *NewSection, const GlobalValue *GV); + protected: /// getFunctionNumber - Return a unique ID for the current function. /// unsigned getFunctionNumber() const { return FunctionNumber; } @@ -229,6 +231,43 @@ private: void EmitXXStructorList(Constant *List); + + public: + /// getCommentString - get the comment string. + /// + const char *getCommentString() { + return CommentString; + } + + /// getData8bitsDirective - get the 8-bit data directive string. + /// + const char *getData8bitsDirective() { + return Data8bitsDirective; + } + + /// getData16bitsDirective - get the 16-bit data directive string. + /// + const char *getData16bitsDirective() { + return Data16bitsDirective; + } + + /// getData32bitsDirective - get the 32-bit data directive string. + /// + const char *getData32bitsDirective() { + return Data32bitsDirective; + } + + /// getData64bitsDirective - get the 64-bit data directive string. + /// + const char *getData64bitsDirective() { + return Data64bitsDirective; + } + + /// getPrivateGlobalPrefix - get private label prefix. + /// + const char *getPrivateGlobalPrefix() { + return PrivateGlobalPrefix; + } }; } Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.3 llvm/include/llvm/CodeGen/DwarfWriter.h:1.4 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.3 Wed Dec 21 19:40:06 2005 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Wed Jan 4 07:52:30 2006 @@ -14,11 +14,14 @@ #ifndef LLVM_CODEGEN_DWARFPRINTER_H #define LLVM_CODEGEN_DWARFPRINTER_H +#include +#include "llvm/CodeGen/MachineDebugInfo.h" + namespace llvm { - //===----------------------------------------------------------------------===// + //===--------------------------------------------------------------------===// // Dwarf constants as gleaned from the DWARF Debugging Information Format V.3 - // reference manual http://dwarf.freestandards.org. + // reference manual http://dwarf.freestandards.org . // enum dwarf_constants { // Tags @@ -422,6 +425,141 @@ DW_CFA_lo_user = 0x1c, DW_CFA_hi_user = 0x3f }; + + // Forward declarations. + // + class AsmPrinter; + + //===--------------------------------------------------------------------===// + // DwarfWriter - emits dwarf debug and exception handling directives. + // + class DwarfWriter { + + protected: + + /// O - Stream to .s file. + /// + std::ostream &O; + + /// Asm - Target of dwarf emission. + /// + AsmPrinter *Asm; + + /// DebugInfo - Collected debug information. + /// + MachineDebugInfo &DebugInfo; + + /// hasLEB128 - True if target asm supports leb128 directives. + /// + bool hasLEB128; /// Defaults to false. + + /// needsSet - True if target asm can't compute addresses on data + /// directives. + bool needsSet; /// Defaults to false. + + /// DwarfAbbrevSection - section directive arg for dwarf abbrev. + /// + const char *DwarfAbbrevSection; /// Defaults to ".debug_abbrev". + + /// DwarfInfoSection - section directive arg for dwarf info. + /// + const char *DwarfInfoSection; /// Defaults to ".debug_info". + + /// DwarfLineSection - section directive arg for dwarf info. + /// + const char *DwarfLineSection; /// Defaults to ".debug_line". + + public: + + // Ctor. + DwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di) + : O(o) + , Asm(ap) + , DebugInfo(di) + , hasLEB128(false) + , needsSet(false) + , DwarfAbbrevSection(".debug_abbrev") + , DwarfInfoSection(".debug_info") + , DwarfLineSection(".debug_line") + {} + + /// EmitHex - Emit a hexidecimal string to the output stream. + /// + void EmitHex(unsigned Value) { + O << "0x" + << std::hex + << Value + << std::dec; + } + + /// EmitComment - Emit a simple string comment. + /// + void EmitComment(const char *Comment) { + O << "\t" + << Asm->getCommentString() + << " " + << Comment + << "\n"; + } + + /// EmitULEB128 - Emit a series of hexidecimal values (separated by commas) + /// representing an unsigned leb128 value. + /// + void EmitULEB128(unsigned Value) { + do { + unsigned Byte = Value & 0x7f; + Value >>= 7; + if (Value) Byte |= 0x80; + EmitHex(Byte); + if (Value) O << ", "; + } while (Value); + } + + /// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas) + /// representing a signed leb128 value. + /// + void EmitSLEB128(int Value) { + int Sign = Value >> (8 * sizeof(Value) - 1); + bool IsMore; + + do { + unsigned Byte = Value & 0x7f; + Value >>= 7; + IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; + if (IsMore) Byte |= 0x80; + EmitHex(Byte); + if (IsMore) O << ", "; + } while (IsMore); + } + + /// EmitLabelName - Emit label name for internal use by dwarf. + /// + void EmitLabelName(const char *Tag, int Num) { + O << Asm->getPrivateGlobalPrefix() + << "debug_" + << Tag + << Num; + } + + /// EmitLabel - Emit location label for internal use by dwarf. + /// + void EmitLabel(const char *Tag, int Num) { + EmitLabelName(Tag, Num); + O << ":\n"; + } + + // Defined elsewhere + + void EmitULEB128Bytes(unsigned Value, std::string Comment); + void EmitSLEB128Bytes(int Value, std::string Comment); + + void BeginModule(); + void EndModule(); + + void BeginFunction(); + void EndFunction(); + }; + } // end llvm namespace From jlaskey at apple.com Wed Jan 4 08:29:37 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 08:29:37 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineDebugInfo.h Message-ID: <200601041429.IAA30376@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineDebugInfo.h updated: 1.2 -> 1.3 --- Log message: Add flag for debug presence. --- Diffs of the changes: (+5 -0) MachineDebugInfo.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.2 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.3 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.2 Wed Jan 4 07:46:37 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Jan 4 08:29:26 2006 @@ -47,6 +47,11 @@ {} ~MachineDebugInfo() { } + /// hasInfo - Returns true if debug info is present. + /// + // FIXME - need scheme to suppress debug output. + bool hasInfo() { return true; } + /// NextUniqueID - Returns a unique number for labels used by debugger. /// unsigned NextUniqueID() { return UniqueID++; } From jlaskey at apple.com Wed Jan 4 08:30:24 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 08:30:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp Message-ID: <200601041430.IAA30401@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: DwarfWriter.cpp updated: 1.3 -> 1.4 --- Log message: Add check for debug presence. --- Diffs of the changes: (+4 -0) DwarfWriter.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.3 llvm/lib/CodeGen/DwarfWriter.cpp:1.4 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.3 Wed Jan 4 07:52:30 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Jan 4 08:30:12 2006 @@ -70,6 +70,7 @@ /// BeginModule - Emit all dwarf sections that should come prior to the content. /// void DwarfWriter::BeginModule() { + if (!DebugInfo.hasInfo()) return; EmitComment("Dwarf Begin Module"); // define base addresses for dwarf sections @@ -84,6 +85,7 @@ /// EndModule - Emit all dwarf sections that should come after the content. /// void DwarfWriter::EndModule() { + if (!DebugInfo.hasInfo()) return; EmitComment("Dwarf End Module"); // Print out dwarf file info std::vector Sources = DebugInfo.getSourceFiles(); @@ -96,12 +98,14 @@ /// BeginFunction - Emit pre-function debug information. /// void DwarfWriter::BeginFunction() { + if (!DebugInfo.hasInfo()) return; EmitComment("Dwarf Begin Function"); } /// EndFunction - Emit post-function debug information. /// void DwarfWriter::EndFunction() { + if (!DebugInfo.hasInfo()) return; EmitComment("Dwarf End Function"); } From jlaskey at apple.com Wed Jan 4 09:04:24 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 09:04:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineDebugInfo.cpp Message-ID: <200601041504.JAA30697@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineDebugInfo.cpp updated: 1.1 -> 1.2 --- Log message: Add unique id to debug location for debug label use (work in progress.) --- Diffs of the changes: (+1 -0) MachineDebugInfo.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.1 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.2 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.1 Wed Jan 4 07:36:38 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Wed Jan 4 09:04:11 2006 @@ -50,6 +50,7 @@ /// doFinalization - Tear down the debug state after completion of a module. /// bool MachineDebugInfo::doFinalization() { + return true; } From jlaskey at apple.com Wed Jan 4 09:04:24 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 09:04:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrInfo.td Message-ID: <200601041504.JAA30701@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrInfo.td updated: 1.167 -> 1.168 --- Log message: Add unique id to debug location for debug label use (work in progress.) --- Diffs of the changes: (+4 -3) PPCInstrInfo.td | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.167 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.168 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.167 Thu Dec 29 18:12:56 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Wed Jan 4 09:04:11 2006 @@ -955,10 +955,11 @@ // DWARF Pseudo Instructions // -def DWARF_LOC : Pseudo<(ops i32imm:$line, i32imm:$col, i32imm:$file), - "; .loc $file, $line, $col", +def DWARF_LOC : Pseudo<(ops i32imm:$line, i32imm:$col, i32imm:$file, + i32imm:$id), + "; .loc $file, $line, $col\nLdebug_loc$id:", [(dwarf_loc (i32 imm:$line), (i32 imm:$col), - (i32 imm:$file))]>; + (i32 imm:$file), (i32 imm:$id))]>; //===----------------------------------------------------------------------===// // PowerPC Instruction Patterns From jlaskey at apple.com Wed Jan 4 09:04:25 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 09:04:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp Message-ID: <200601041504.JAA30715@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.75 -> 1.76 LegalizeDAG.cpp updated: 1.250 -> 1.251 --- Log message: Add unique id to debug location for debug label use (work in progress.) --- Diffs of the changes: (+23 -15) DAGCombiner.cpp | 3 ++- LegalizeDAG.cpp | 35 +++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 15 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.75 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.76 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.75 Fri Dec 23 14:08:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Jan 4 09:04:11 2006 @@ -2117,7 +2117,8 @@ return DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Chain.getOperand(0), N->getOperand(1), N->getOperand(2), - N->getOperand(3)); + N->getOperand(3), + N->getOperand(4)); } return SDOperand(); Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.250 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.251 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.250 Wed Jan 4 07:42:59 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jan 4 09:04:11 2006 @@ -628,8 +628,10 @@ cast(Node->getOperand(3))->getValue(); const std::string &dirname = cast(Node->getOperand(4))->getValue(); - unsigned id = DebugInfo.RecordSource(fname, dirname); - Ops.push_back(DAG.getConstant(id, MVT::i32)); // source file id + unsigned srcfile = DebugInfo.RecordSource(fname, dirname); + Ops.push_back(DAG.getConstant(srcfile, MVT::i32)); // source file id + unsigned id = DebugInfo.NextUniqueID(); + Ops.push_back(DAG.getConstant(id, MVT::i32)); // label id Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops); } else { Result = Tmp1; // chain @@ -659,22 +661,27 @@ break; case ISD::DEBUG_LOC: - assert(Node->getNumOperands() == 4 && "Invalid DEBUG_LOC node!"); + assert(Node->getNumOperands() == 5 && "Invalid DEBUG_LOC node!"); switch (TLI.getOperationAction(ISD::DEBUG_LOC, MVT::Other)) { case TargetLowering::Promote: case TargetLowering::Expand: default: assert(0 && "This action is not supported yet!"); - case TargetLowering::Legal: - Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. - Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the line #. - Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the col #. - Tmp4 = LegalizeOp(Node->getOperand(3)); // Legalize the source file id. - - if (Tmp1 != Node->getOperand(0) || - Tmp2 != Node->getOperand(1) || - Tmp3 != Node->getOperand(2) || - Tmp4 != Node->getOperand(3)) { - Result = DAG.getNode(ISD::DEBUG_LOC,MVT::Other, Tmp1, Tmp2, Tmp3, Tmp4); + case TargetLowering::Legal: { + SDOperand Tmp5; + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the line #. + Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the col #. + Tmp4 = LegalizeOp(Node->getOperand(3)); // Legalize the source file id. + Tmp5 = LegalizeOp(Node->getOperand(4)); // Legalize the label id. + + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1) || + Tmp3 != Node->getOperand(2) || + Tmp4 != Node->getOperand(3) || + Tmp5 != Node->getOperand(4)) { + Result = + DAG.getNode(ISD::DEBUG_LOC,MVT::Other, Tmp1, Tmp2, Tmp3, Tmp4, Tmp5); + } } break; } From jlaskey at apple.com Wed Jan 4 09:04:25 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 09:04:25 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200601041504.JAA30709@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.85 -> 1.86 --- Log message: Add unique id to debug location for debug label use (work in progress.) --- Diffs of the changes: (+3 -2) SelectionDAGNodes.h | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.85 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.86 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.85 Thu Dec 22 18:46:10 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Wed Jan 4 09:04:11 2006 @@ -356,8 +356,9 @@ // DEBUG_LOC - This node is used to represent source line information // embedded in the code. It takes token chain as input, then a line number, - // then a column then a file id (provided by MachineDebugInfo. It produces - // a token chain as output. + // then a column then a file id (provided by MachineDebugInfo), then a + // unique id (provided by MachineDebugInfo for label gen). It produces a + // token chain as output. DEBUG_LOC, // BUILTIN_OP_END - This must be the last enum value in this list. From jlaskey at apple.com Wed Jan 4 09:04:25 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 09:04:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200601041504.JAA30705@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.38 -> 1.39 --- Log message: Add unique id to debug location for debug label use (work in progress.) --- Diffs of the changes: (+2 -2) TargetSelectionDAG.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.38 llvm/lib/Target/TargetSelectionDAG.td:1.39 --- llvm/lib/Target/TargetSelectionDAG.td:1.38 Sun Jan 1 16:16:43 2006 +++ llvm/lib/Target/TargetSelectionDAG.td Wed Jan 4 09:04:11 2006 @@ -440,8 +440,8 @@ //===----------------------------------------------------------------------===// // Dwarf support. // -def SDT_dwarf_loc : SDTypeProfile<0, 3, - [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>; +def SDT_dwarf_loc : SDTypeProfile<0, 4, + [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>, SDTCisInt<3>]>; def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>; From jeffc at jolt-lang.org Wed Jan 4 11:19:59 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 4 Jan 2006 11:19:59 -0600 Subject: [llvm-commits] CVS: llvm/win32/CodeGen/CodeGen.vcproj Message-ID: <200601041719.LAA32063@zion.cs.uiuc.edu> Changes in directory llvm/win32/CodeGen: CodeGen.vcproj updated: 1.17 -> 1.18 --- Log message: Teach Visual Studio about new file. --- Diffs of the changes: (+3 -0) CodeGen.vcproj | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/win32/CodeGen/CodeGen.vcproj diff -u llvm/win32/CodeGen/CodeGen.vcproj:1.17 llvm/win32/CodeGen/CodeGen.vcproj:1.18 --- llvm/win32/CodeGen/CodeGen.vcproj:1.17 Wed Dec 21 19:50:11 2005 +++ llvm/win32/CodeGen/CodeGen.vcproj Wed Jan 4 11:19:48 2006 @@ -139,6 +139,9 @@ RelativePath="..\..\lib\CodeGen\MachineCodeEmitter.cpp"> + + Changes in directory llvm/include/llvm: Pass.h updated: 1.52 -> 1.53 --- Log message: Be consistent in using class vs struct to make VC++ happy. And as it contains methods, virtual method even, class wins. --- Diffs of the changes: (+2 -1) Pass.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Pass.h diff -u llvm/include/llvm/Pass.h:1.52 llvm/include/llvm/Pass.h:1.53 --- llvm/include/llvm/Pass.h:1.52 Wed Jan 4 01:47:12 2006 +++ llvm/include/llvm/Pass.h Wed Jan 4 11:21:23 2006 @@ -311,7 +311,8 @@ /// other basic block in the function. /// 3. Optimizations conform to all of the constraints of FunctionPasses. /// -struct BasicBlockPass : public FunctionPass { +class BasicBlockPass : public FunctionPass { +public: /// doInitialization - Virtual method overridden by subclasses to do /// any necessary per-module initialization. /// From bocchino at cs.uiuc.edu Wed Jan 4 14:28:17 2006 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 4 Jan 2006 14:28:17 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Vector/SSE.cpp Message-ID: <200601042028.OAA01772@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Vector: SSE.cpp updated: 1.1.2.3 -> 1.1.2.4 --- Log message: Fixed a bug in SSE code generation for unpack. --- Diffs of the changes: (+49 -25) SSE.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 49 insertions(+), 25 deletions(-) Index: llvm/lib/Transforms/Vector/SSE.cpp diff -u llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.3 llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.4 --- llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.3 Wed Nov 16 12:32:56 2005 +++ llvm/lib/Transforms/Vector/SSE.cpp Wed Jan 4 14:28:05 2006 @@ -147,6 +147,31 @@ return false; } + static const Type *getSignedType(const Type *Ty) { + if (Ty->isSigned()) + return Ty; + switch(Ty->getTypeID()) { + case Type::UIntTyID: + return Type::IntTy; + default: + std::cerr << "Can't handle type " << Ty->getDescription() << "\n"; + exit(1); + } + } + + static const Type *promoteType(const Type *Ty) { + if (const FixedVectorType *VT = dyn_cast(Ty)) + return FixedVectorType::get(promoteType(VT->getElementType()), + VT->getNumElements()); + switch(Ty->getTypeID()) { + case Type::ShortTyID: + return Type::IntTy; + default: + std::cerr << "Can't promote type " << Ty->getDescription() << "\n"; + exit(1); + } + } + //===----------------------------------------------------------------------===// // SSE implementation @@ -274,12 +299,19 @@ ExtractInst *extract0 = dyn_cast(*I++); ExtractInst *extract1 = dyn_cast(*I); assert(extract0 && extract1); - CallInst *unpackhi = VectorUtils::getCallInst(VT2, getSSEName("unpackhi", VT2), - combine1->getOperand(1), combine2->getOperand(1), - "unpackhi", extract0); - CallInst *unpacklo = VectorUtils::getCallInst(VT2, getSSEName("unpacklo", VT2), - combine1->getOperand(1), combine2->getOperand(1), - "unpacklo", extract0); + const FixedVectorType *HalfVT = + FixedVectorType::get(promoteType(VT2->getElementType()), + VT2->getNumElements() / 2); + CallInst *tmp = + VectorUtils::getCallInst(HalfVT, getSSEName("unpackhi", VT2), + combine1->getOperand(1), combine2->getOperand(1), + "unpackhi", extract0); + CastInst *unpackhi = new CastInst(tmp, VT2, "cast", extract0); + tmp = + VectorUtils::getCallInst(HalfVT, getSSEName("unpacklo", VT2), + combine1->getOperand(1), combine2->getOperand(1), + "unpacklo", extract0); + CastInst *unpacklo = new CastInst(tmp, VT2, "cast", extract0); if (cast(extract0->getOperand(1))->getValue() == 1) { extract0->replaceAllUsesWith(unpackhi); extract1->replaceAllUsesWith(unpacklo); @@ -371,18 +403,6 @@ } } - static const Type *getSignedType(const Type *Ty) { - if (Ty->isSigned()) - return Ty; - switch(Ty->getTypeID()) { - case Type::UIntTyID: - return Type::IntTy; - default: - std::cerr << "Can't handle type " << Ty->getDescription() << "\n"; - } - return 0; - } - void SSE::addComposeConstant(BinaryOperator &Add, Value *arg1, Value *arg2) { CallInst *compose = dyn_cast(arg1);//Add.getOperand(0)); @@ -398,14 +418,18 @@ const FixedVectorType *LongVT = dyn_cast(Add.getType()); const FixedVectorType *ShortVT = dyn_cast(op1->getType()); if (!LongVT || !ShortVT) return; - const FixedVectorType *HalfVT = FixedVectorType::get(getSignedType(LongVT->getElementType()), - LongVT->getNumElements() / 2); - CallInst *splat2 = VectorUtils::getCallInst(HalfVT, getSSEName("splat", HalfVT), - C, "splat", &Add); - CallInst *unpackLo = VectorUtils::getCallInst(HalfVT, getSSEName("unpacklo", ShortVT), + const FixedVectorType *HalfVT = + FixedVectorType::get(getSignedType(LongVT->getElementType()), + LongVT->getNumElements() / 2); + CallInst *splat2 = + VectorUtils::getCallInst(HalfVT, getSSEName("splat", HalfVT), + C, "splat", &Add); + CallInst *unpackLo = + VectorUtils::getCallInst(HalfVT, getSSEName("unpacklo", ShortVT), op1, op2, "unpackLo", &Add); - CallInst *unpackHi = VectorUtils::getCallInst(HalfVT, getSSEName("unpackhi", ShortVT), - op1, op2, "unpackHi", &Add); + CallInst *unpackHi = + VectorUtils::getCallInst(HalfVT, getSSEName("unpackhi", ShortVT), + op1, op2, "unpackHi", &Add); CallInst *addLo = VectorUtils::getCallInst(HalfVT, getSSEName("add", HalfVT), unpackLo, splat2, "addLo", &Add); CallInst *addHi = VectorUtils::getCallInst(HalfVT, getSSEName("add", HalfVT), From jlaskey at apple.com Wed Jan 4 16:28:38 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 16:28:38 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h DwarfWriter.h MachineDebugInfo.h SelectionDAG.h Message-ID: <200601042228.QAA02434@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.24 -> 1.25 DwarfWriter.h updated: 1.4 -> 1.5 MachineDebugInfo.h updated: 1.3 -> 1.4 SelectionDAG.h updated: 1.82 -> 1.83 --- Log message: Applied some recommend changes from sabre. The dominate one beginning "let the pass manager do it's thing." Fixes crash when compiling -g files and suppresses dwarf statements if no debug info is present. --- Diffs of the changes: (+88 -112) AsmPrinter.h | 45 ++------------------ DwarfWriter.h | 119 ++++++++++++++++++++++++++++------------------------- MachineDebugInfo.h | 30 +++++-------- SelectionDAG.h | 6 ++ 4 files changed, 88 insertions(+), 112 deletions(-) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.24 llvm/include/llvm/CodeGen/AsmPrinter.h:1.25 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.24 Wed Jan 4 07:52:30 2006 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Wed Jan 4 16:28:25 2006 @@ -36,7 +36,7 @@ /// unsigned FunctionNumber; - protected: + public: /// Output stream on which we're printing assembly code. /// std::ostream &O; @@ -162,7 +162,8 @@ /// HasDotTypeDotSizeDirective - True if the target has .type and .size /// directives, this is true for most ELF targets. bool HasDotTypeDotSizeDirective; // Defaults to true. - + + protected: AsmPrinter(std::ostream &o, TargetMachine &TM); public: @@ -194,7 +195,7 @@ /// doFinalization - Shut down the asmprinter. If you override this in your /// pass, you must make sure to call it explicitly. bool doFinalization(Module &M); - + /// SetupMachineFunction - This should be called when a new MachineFunction /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); @@ -231,43 +232,7 @@ private: void EmitXXStructorList(Constant *List); - - public: - /// getCommentString - get the comment string. - /// - const char *getCommentString() { - return CommentString; - } - - /// getData8bitsDirective - get the 8-bit data directive string. - /// - const char *getData8bitsDirective() { - return Data8bitsDirective; - } - - /// getData16bitsDirective - get the 16-bit data directive string. - /// - const char *getData16bitsDirective() { - return Data16bitsDirective; - } - - /// getData32bitsDirective - get the 32-bit data directive string. - /// - const char *getData32bitsDirective() { - return Data32bitsDirective; - } - - /// getData64bitsDirective - get the 64-bit data directive string. - /// - const char *getData64bitsDirective() { - return Data64bitsDirective; - } - - /// getPrivateGlobalPrefix - get private label prefix. - /// - const char *getPrivateGlobalPrefix() { - return PrivateGlobalPrefix; - } + }; } Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.4 llvm/include/llvm/CodeGen/DwarfWriter.h:1.5 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.4 Wed Jan 4 07:52:30 2006 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Wed Jan 4 16:28:25 2006 @@ -14,8 +14,7 @@ #ifndef LLVM_CODEGEN_DWARFPRINTER_H #define LLVM_CODEGEN_DWARFPRINTER_H -#include -#include "llvm/CodeGen/MachineDebugInfo.h" +#include namespace llvm { @@ -429,6 +428,7 @@ // Forward declarations. // class AsmPrinter; + class MachineDebugInfo; //===--------------------------------------------------------------------===// // DwarfWriter - emits dwarf debug and exception handling directives. @@ -447,12 +447,28 @@ /// DebugInfo - Collected debug information. /// - MachineDebugInfo &DebugInfo; + MachineDebugInfo *DebugInfo; + /// didInitial - Flag to indicate if initial emission has been done. + /// + bool didInitial; + + //===------------------------------------------------------------------===// + // Properties to be set by the derived class ctor, used to configure the + // dwarf writer. + /// hasLEB128 - True if target asm supports leb128 directives. /// bool hasLEB128; /// Defaults to false. + /// hasDotLoc - True if target asm supports .loc directives. + /// + bool hasDotLoc; /// Defaults to false. + + /// hasDotFile - True if target asm supports .file directives. + /// + bool hasDotFile; /// Defaults to false. + /// needsSet - True if target asm can't compute addresses on data /// directives. bool needsSet; /// Defaults to false. @@ -469,94 +485,89 @@ /// const char *DwarfLineSection; /// Defaults to ".debug_line". + //===------------------------------------------------------------------===// + public: // Ctor. - DwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di) + DwarfWriter(std::ostream &o, AsmPrinter *ap) : O(o) , Asm(ap) - , DebugInfo(di) + , DebugInfo(NULL) + , didInitial(false) , hasLEB128(false) + , hasDotLoc(false) + , hasDotFile(false) , needsSet(false) , DwarfAbbrevSection(".debug_abbrev") , DwarfInfoSection(".debug_info") , DwarfLineSection(".debug_line") {} + /// SetDebugInfo - Set DebugInfo at when it's know that pass manager + /// has created it. + void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; } + /// EmitHex - Emit a hexidecimal string to the output stream. /// - void EmitHex(unsigned Value) { - O << "0x" - << std::hex - << Value - << std::dec; - } + void EmitHex(unsigned Value) const; /// EmitComment - Emit a simple string comment. /// - void EmitComment(const char *Comment) { - O << "\t" - << Asm->getCommentString() - << " " - << Comment - << "\n"; - } + void EmitComment(const char *Comment) const; /// EmitULEB128 - Emit a series of hexidecimal values (separated by commas) /// representing an unsigned leb128 value. /// - void EmitULEB128(unsigned Value) { - do { - unsigned Byte = Value & 0x7f; - Value >>= 7; - if (Value) Byte |= 0x80; - EmitHex(Byte); - if (Value) O << ", "; - } while (Value); - } + void EmitULEB128(unsigned Value) const; /// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas) /// representing a signed leb128 value. /// - void EmitSLEB128(int Value) { - int Sign = Value >> (8 * sizeof(Value) - 1); - bool IsMore; - - do { - unsigned Byte = Value & 0x7f; - Value >>= 7; - IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; - if (IsMore) Byte |= 0x80; - EmitHex(Byte); - if (IsMore) O << ", "; - } while (IsMore); - } + void EmitSLEB128(int Value) const; /// EmitLabelName - Emit label name for internal use by dwarf. /// - void EmitLabelName(const char *Tag, int Num) { - O << Asm->getPrivateGlobalPrefix() - << "debug_" - << Tag - << Num; - } + void EmitLabelName(const char *Tag, int Num) const; /// EmitLabel - Emit location label for internal use by dwarf. /// - void EmitLabel(const char *Tag, int Num) { - EmitLabelName(Tag, Num); - O << ":\n"; - } + void EmitLabel(const char *Tag, int Num) const; - // Defined elsewhere - - void EmitULEB128Bytes(unsigned Value, std::string Comment); - void EmitSLEB128Bytes(int Value, std::string Comment); + /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an + /// unsigned leb128 value. Comment is added to the end of the directive if + /// DwarfVerbose is true (should not contain any newlines.) + /// + void EmitULEB128Bytes(unsigned Value, const char *Comment) const; + + /// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a + /// signed leb128 value. Comment is added to the end of the directive if + /// DwarfVerbose is true (should not contain any newlines.) + /// + void EmitSLEB128Bytes(int Value, const char *Comment) const; + + /// EmitInitial - Emit initial dwarf declarations. + /// + void EmitInitial() const; + + /// ShouldEmitDwarf - Determine if dwarf declarations should be made. + /// + bool ShouldEmitDwarf(); + /// BeginModule - Emit all dwarf sections that should come prior to the + /// content. void BeginModule(); + + /// EndModule - Emit all dwarf sections that should come after the content. + /// void EndModule(); + /// BeginFunction - Emit pre-function debug information. + /// void BeginFunction(); + + /// EndFunction - Emit post-function debug information. + /// void EndFunction(); }; Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.3 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.4 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.3 Wed Jan 4 08:29:26 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Jan 4 16:28:25 2006 @@ -28,11 +28,7 @@ /// class MachineDebugInfo : public ImmutablePass { private: - // convenience types - typedef std::map StrIntMap; - typedef StrIntMap::iterator StrIntMapIter; - - StrIntMap SourceMap; // Map of source file path to id + std::map SourceMap; // Map of source file path to id unsigned SourceCount; // Number of source files (used to // generate id) unsigned UniqueID; // Number used to unique labels used @@ -50,25 +46,25 @@ /// hasInfo - Returns true if debug info is present. /// // FIXME - need scheme to suppress debug output. - bool hasInfo() { return true; } + bool hasInfo() const { return SourceCount != 0; } - /// NextUniqueID - Returns a unique number for labels used by debugger. + /// getNextUniqueID - Returns a unique number for labels used by debugger. /// - unsigned NextUniqueID() { return UniqueID++; } + unsigned getNextUniqueID() { return UniqueID++; } bool doInitialization(); bool doFinalization(); - unsigned RecordSource(std::string fname, std::string dirname); - std::vector getSourceFiles(); + + /// getUniqueSourceID - Register a source file with debug info. Returns an id. + /// + unsigned getUniqueSourceID(const std::string &fname, + const std::string &dirname); + + /// getSourceFiles - Return a vector of files. Vector index + 1 equals id. + /// + std::vector getSourceFiles() const; }; // End class MachineDebugInfo -//===----------------------------------------------------------------------===// - -// FIXME - temporary hack until we can find a place to hang debug info from. -MachineDebugInfo &getMachineDebugInfo(); - -// FIXME - temporary hack until we can find a place to hand debug info from. -ModulePass *createDebugInfoPass(); } // End llvm namespace Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.82 llvm/include/llvm/CodeGen/SelectionDAG.h:1.83 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.82 Thu Dec 22 15:16:35 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Wed Jan 4 16:28:25 2006 @@ -25,6 +25,7 @@ namespace llvm { class TargetLowering; class TargetMachine; + class MachineDebugInfo; class MachineFunction; /// SelectionDAG class - This is used to represent a portion of an LLVM function @@ -41,6 +42,7 @@ class SelectionDAG { TargetLowering &TLI; MachineFunction &MF; + MachineDebugInfo *DI; // Root - The root of the entire DAG. EntryNode - The starting token. SDOperand Root, EntryNode; @@ -52,7 +54,8 @@ std::map, SDNode*> ValueNodes; public: - SelectionDAG(TargetLowering &tli, MachineFunction &mf) : TLI(tli), MF(mf) { + SelectionDAG(TargetLowering &tli, MachineFunction &mf, MachineDebugInfo *di) + : TLI(tli), MF(mf), DI(di) { EntryNode = Root = getNode(ISD::EntryToken, MVT::Other); } ~SelectionDAG(); @@ -60,6 +63,7 @@ MachineFunction &getMachineFunction() const { return MF; } const TargetMachine &getTarget() const; TargetLowering &getTargetLoweringInfo() const { return TLI; } + MachineDebugInfo *getMachineDebugInfo() const { return DI; } /// viewGraph - Pop up a ghostview window with the DAG rendered using 'dot'. /// From jlaskey at apple.com Wed Jan 4 16:28:39 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 16:28:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAGISel.cpp Message-ID: <200601042228.QAA02452@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.251 -> 1.252 SelectionDAGISel.cpp updated: 1.119 -> 1.120 --- Log message: Applied some recommend changes from sabre. The dominate one beginning "let the pass manager do it's thing." Fixes crash when compiling -g files and suppresses dwarf statements if no debug info is present. --- Diffs of the changes: (+6 -5) LegalizeDAG.cpp | 8 ++++---- SelectionDAGISel.cpp | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.251 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.252 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.251 Wed Jan 4 09:04:11 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jan 4 16:28:25 2006 @@ -618,8 +618,8 @@ case TargetLowering::Promote: default: assert(0 && "This action is not supported yet!"); case TargetLowering::Expand: { - if (TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other)) { - MachineDebugInfo &DebugInfo = getMachineDebugInfo(); + MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo(); + if (TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other) && DebugInfo) { std::vector Ops; Ops.push_back(Tmp1); // chain Ops.push_back(Node->getOperand(1)); // line # @@ -628,9 +628,9 @@ cast(Node->getOperand(3))->getValue(); const std::string &dirname = cast(Node->getOperand(4))->getValue(); - unsigned srcfile = DebugInfo.RecordSource(fname, dirname); + unsigned srcfile = DebugInfo->getUniqueSourceID(fname, dirname); Ops.push_back(DAG.getConstant(srcfile, MVT::i32)); // source file id - unsigned id = DebugInfo.NextUniqueID(); + unsigned id = DebugInfo->getNextUniqueID(); Ops.push_back(DAG.getConstant(id, MVT::i32)); // label id Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops); } else { Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.119 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.120 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.119 Wed Dec 21 13:36:36 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Jan 4 16:28:25 2006 @@ -21,6 +21,7 @@ #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/CodeGen/IntrinsicLowering.h" +#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -1640,7 +1641,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, FunctionLoweringInfo &FuncInfo) { - SelectionDAG DAG(TLI, MF); + SelectionDAG DAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &DAG; std::vector > PHINodesToUpdate; From jlaskey at apple.com Wed Jan 4 16:28:39 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 16:28:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp DwarfWriter.cpp MachineDebugInfo.cpp Message-ID: <200601042228.QAA02446@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.35 -> 1.36 DwarfWriter.cpp updated: 1.4 -> 1.5 MachineDebugInfo.cpp updated: 1.2 -> 1.3 --- Log message: Applied some recommend changes from sabre. The dominate one beginning "let the pass manager do it's thing." Fixes crash when compiling -g files and suppresses dwarf statements if no debug info is present. --- Diffs of the changes: (+150 -89) AsmPrinter.cpp | 1 DwarfWriter.cpp | 132 +++++++++++++++++++++++++++++++++++++++++---------- MachineDebugInfo.cpp | 106 ++++++++++++++++------------------------ 3 files changed, 150 insertions(+), 89 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.35 llvm/lib/CodeGen/AsmPrinter.cpp:1.36 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.35 Wed Jan 4 07:52:30 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Wed Jan 4 16:28:25 2006 @@ -16,7 +16,6 @@ #include "llvm/Constants.h" #include "llvm/Module.h" #include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetMachine.h" Index: llvm/lib/CodeGen/DwarfWriter.cpp diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.4 llvm/lib/CodeGen/DwarfWriter.cpp:1.5 --- llvm/lib/CodeGen/DwarfWriter.cpp:1.4 Wed Jan 4 08:30:12 2006 +++ llvm/lib/CodeGen/DwarfWriter.cpp Wed Jan 4 16:28:25 2006 @@ -11,32 +11,35 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/DwarfWriter.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/DwarfWriter.h" +#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/Support/CommandLine.h" +#include -namespace llvm { +using namespace llvm; static cl::opt DwarfVerbose("dwarf-verbose", cl::Hidden, cl::desc("Add comments to dwarf directives.")); /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an -/// unsigned leb128 value. +/// unsigned leb128 value. Comment is added to the end of the directive if +/// DwarfVerbose is true (should not contain any newlines.) /// -void DwarfWriter::EmitULEB128Bytes(unsigned Value, std::string Comment) { +void DwarfWriter::EmitULEB128Bytes(unsigned Value, const char *Comment) const { if (hasLEB128) { O << "\t.uleb128\t" << Value; } else { - O << Asm->getData8bitsDirective(); + O << Asm->Data8bitsDirective; EmitULEB128(Value); } if (DwarfVerbose) { O << "\t" - << Asm->getCommentString() + << Asm->CommentString << " " << Comment << " " @@ -46,19 +49,20 @@ } /// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a -/// signed leb128 value. +/// signed leb128 value. Comment is added to the end of the directive if +/// DwarfVerbose is true (should not contain any newlines.) /// -void DwarfWriter::EmitSLEB128Bytes(int Value, std::string Comment) { +void DwarfWriter::EmitSLEB128Bytes(int Value, const char *Comment) const { if (hasLEB128) { O << "\t.sleb128\t" << Value; } else { - O << Asm->getData8bitsDirective(); + O << Asm->Data8bitsDirective; EmitSLEB128(Value); } if (DwarfVerbose) { O << "\t" - << Asm->getCommentString() + << Asm->CommentString << " " << Comment << " " @@ -67,13 +71,75 @@ O << "\n"; } -/// BeginModule - Emit all dwarf sections that should come prior to the content. +/// EmitHex - Emit a hexidecimal string to the output stream. /// -void DwarfWriter::BeginModule() { - if (!DebugInfo.hasInfo()) return; - EmitComment("Dwarf Begin Module"); +void DwarfWriter::EmitHex(unsigned Value) const { + O << "0x" + << std::hex + << Value + << std::dec; +} + +/// EmitComment - Emit a simple string comment. +/// +void DwarfWriter::EmitComment(const char *Comment) const { + O << "\t" + << Asm->CommentString + << " " + << Comment + << "\n"; +} + +/// EmitULEB128 - Emit a series of hexidecimal values (separated by commas) +/// representing an unsigned leb128 value. +/// +void DwarfWriter::EmitULEB128(unsigned Value) const { + do { + unsigned Byte = Value & 0x7f; + Value >>= 7; + if (Value) Byte |= 0x80; + EmitHex(Byte); + if (Value) O << ", "; + } while (Value); +} + +/// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas) +/// representing a signed leb128 value. +/// +void DwarfWriter::EmitSLEB128(int Value) const { + int Sign = Value >> (8 * sizeof(Value) - 1); + bool IsMore; - // define base addresses for dwarf sections + do { + unsigned Byte = Value & 0x7f; + Value >>= 7; + IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; + if (IsMore) Byte |= 0x80; + EmitHex(Byte); + if (IsMore) O << ", "; + } while (IsMore); +} + +/// EmitLabelName - Emit label name for internal use by dwarf. +/// +void DwarfWriter::EmitLabelName(const char *Tag, int Num) const { + O << Asm->PrivateGlobalPrefix + << "debug_" + << Tag + << Num; +} + +/// EmitLabel - Emit location label for internal use by dwarf. +/// +void DwarfWriter::EmitLabel(const char *Tag, int Num) const { + EmitLabelName(Tag, Num); + O << ":\n"; +} + +/// EmitInitial -Emit initial dwarf declarations. +/// +void DwarfWriter::EmitInitial() const { + // Dwarf section's base addresses. Asm->SwitchSection(DwarfAbbrevSection, 0); EmitLabel("abbrev", 0); Asm->SwitchSection(DwarfInfoSection, 0); @@ -82,33 +148,51 @@ EmitLabel("line", 0); } +/// ShouldEmitDwarf - Determine if dwarf declarations should be made. +/// +bool DwarfWriter::ShouldEmitDwarf() { + // Check if debug info is present. + if (!DebugInfo || !DebugInfo->hasInfo()) return false; + + // Make sure initial declarations are made. + if (!didInitial) { + EmitInitial(); + didInitial = true; + } + + // Okay to emit. + return true; +} + +/// BeginModule - Emit all dwarf sections that should come prior to the content. +/// +void DwarfWriter::BeginModule() { + if (!ShouldEmitDwarf()) return; + EmitComment("Dwarf Begin Module"); +} + /// EndModule - Emit all dwarf sections that should come after the content. /// void DwarfWriter::EndModule() { - if (!DebugInfo.hasInfo()) return; + if (!ShouldEmitDwarf()) return; EmitComment("Dwarf End Module"); // Print out dwarf file info - std::vector Sources = DebugInfo.getSourceFiles(); + std::vector Sources = DebugInfo->getSourceFiles(); for (unsigned i = 0, N = Sources.size(); i < N; i++) { O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i] << "\"" << "\n"; } } - /// BeginFunction - Emit pre-function debug information. /// void DwarfWriter::BeginFunction() { - if (!DebugInfo.hasInfo()) return; + if (!ShouldEmitDwarf()) return; EmitComment("Dwarf Begin Function"); } /// EndFunction - Emit post-function debug information. /// void DwarfWriter::EndFunction() { - if (!DebugInfo.hasInfo()) return; + if (!ShouldEmitDwarf()) return; EmitComment("Dwarf End Function"); } - - -} // End llvm namespace - Index: llvm/lib/CodeGen/MachineDebugInfo.cpp diff -u llvm/lib/CodeGen/MachineDebugInfo.cpp:1.2 llvm/lib/CodeGen/MachineDebugInfo.cpp:1.3 --- llvm/lib/CodeGen/MachineDebugInfo.cpp:1.2 Wed Jan 4 09:04:11 2006 +++ llvm/lib/CodeGen/MachineDebugInfo.cpp Wed Jan 4 16:28:25 2006 @@ -18,74 +18,52 @@ // Handle the Pass registration stuff necessary to use TargetData's. namespace { - RegisterPass X("machinedebuginfo", "Debug Information", - PassInfo::Analysis | PassInfo::Optimization); + RegisterPass X("machinedebuginfo", "Debug Information"); } - -namespace llvm { - - /// DebugInfo - Keep track of debug information for the function. - /// - // FIXME - making it global until we can find a proper place to hang it from. - MachineDebugInfo *DebugInfo; - - // FIXME - temporary hack until we can find a place to hand debug info from. - ModulePass *createDebugInfoPass() { - if (!DebugInfo) DebugInfo = new MachineDebugInfo(); - return (ModulePass *)DebugInfo; - } - /// getDebugInfo - Returns the DebugInfo. - MachineDebugInfo &getMachineDebugInfo() { - assert(DebugInfo && "DebugInfo pass not created"); - return *DebugInfo; - } - - /// doInitialization - Initialize the debug state for a new module. - /// - bool MachineDebugInfo::doInitialization() { - return true; - } +/// doInitialization - Initialize the debug state for a new module. +/// +bool MachineDebugInfo::doInitialization() { + return false; +} - /// doFinalization - Tear down the debug state after completion of a module. - /// - bool MachineDebugInfo::doFinalization() { - - return true; - } +/// doFinalization - Tear down the debug state after completion of a module. +/// +bool MachineDebugInfo::doFinalization() { + return false; +} - /// RecordSource - Register a source file with debug info. Returns an id. - /// - unsigned MachineDebugInfo::RecordSource(std::string fname, - std::string dirname) { - // Compose a key - std::string path = dirname + "/" + fname; - // Check if the source file is already recorded - StrIntMapIter SMI = SourceMap.find(path); - // If already there return existing id - if (SMI != SourceMap.end()) return SMI->second; - // Bump up the count - ++SourceCount; - // Record the count - SourceMap[path] = SourceCount; - // Return id - return SourceCount; - } +/// getUniqueSourceID - Register a source file with debug info. Returns an id. +/// +unsigned MachineDebugInfo::getUniqueSourceID(const std::string &fname, + const std::string &dirname) { + // Compose a key + const std::string path = dirname + "/" + fname; + // Check if the source file is already recorded + std::map::iterator + SMI = SourceMap.lower_bound(path); + // If already there return existing id + if (SMI != SourceMap.end() && SMI->first == path) return SMI->second; + // Bump up the count + ++SourceCount; + // Record the count + SourceMap.insert(SMI, std::make_pair(path, SourceCount)); + // Return id + return SourceCount; +} - /// getSourceFiles - Return a vector of files. Vector index + 1 equals id. - /// - std::vector MachineDebugInfo::getSourceFiles() { - std::vector Sources(SourceCount); - - for (StrIntMapIter SMI = SourceMap.begin(), E = SourceMap.end(); SMI != E; - SMI++) { - unsigned Index = SMI->second - 1; - std::string Path = SMI->first; - Sources[Index] = Path; - } - return Sources; +/// getSourceFiles - Return a vector of files. Vector index + 1 equals id. +/// +std::vector MachineDebugInfo::getSourceFiles() const { + std::vector Sources(SourceCount); + + for (std::map::const_iterator SMI = SourceMap.begin(), + E = SourceMap.end(); + SMI != E; SMI++) { + unsigned Index = SMI->second - 1; + const std::string &Path = SMI->first; + Sources[Index] = Path; } - - -}; + return Sources; +} From jlaskey at apple.com Wed Jan 4 16:28:39 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 16:28:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200601042228.QAA02438@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.134 -> 1.135 --- Log message: Applied some recommend changes from sabre. The dominate one beginning "let the pass manager do it's thing." Fixes crash when compiling -g files and suppresses dwarf statements if no debug info is present. --- Diffs of the changes: (+11 -7) PPCAsmPrinter.cpp | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.134 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.135 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.134 Wed Jan 4 07:52:30 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Wed Jan 4 16:28:25 2006 @@ -204,16 +204,16 @@ virtual bool runOnMachineFunction(MachineFunction &F) = 0; virtual bool doFinalization(Module &M) = 0; + }; /// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X /// struct DarwinDwarfWriter : public DwarfWriter { // Ctor. - DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di) - : DwarfWriter(o, ap, di) + DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap) + : DwarfWriter(o, ap) { - hasLEB128 = false; needsSet = true; DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev,regular,debug"; DwarfInfoSection = ".section __DWARFA,__debug_info,regular,debug"; @@ -229,9 +229,7 @@ DarwinDwarfWriter DW; DarwinAsmPrinter(std::ostream &O, TargetMachine &TM) - : PPCAsmPrinter(O, TM), - // FIXME - MachineDebugInfo needs a proper location - DW(O, this, getMachineDebugInfo()) + : PPCAsmPrinter(O, TM), DW(O, this) { CommentString = ";"; GlobalPrefix = "_"; @@ -252,6 +250,11 @@ bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); bool doFinalization(Module &M); + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + }; /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX @@ -483,6 +486,7 @@ Mang->setUseQuotes(true); // Emit initial debug information. + DW.SetDebugInfo(getAnalysisToUpdate()); DW.BeginModule(); return false; } @@ -613,7 +617,7 @@ return false; // success } -/// runOnMachineFunction - This uses the printMachineInstruction() +/// runOnMachineFunction - This uses the e() /// method to print assembly for each instruction. /// bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) { From jlaskey at apple.com Wed Jan 4 16:28:39 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 16:28:39 -0600 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200601042228.QAA02456@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.124 -> 1.125 --- Log message: Applied some recommend changes from sabre. The dominate one beginning "let the pass manager do it's thing." Fixes crash when compiling -g files and suppresses dwarf statements if no debug info is present. --- Diffs of the changes: (+0 -3) llc.cpp | 3 --- 1 files changed, 3 deletions(-) Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.124 llvm/tools/llc/llc.cpp:1.125 --- llvm/tools/llc/llc.cpp:1.124 Wed Jan 4 07:42:02 2006 +++ llvm/tools/llc/llc.cpp Wed Jan 4 16:28:25 2006 @@ -239,9 +239,6 @@ } } - // Set up collection of debug information - Passes.add(createDebugInfoPass()); - // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) { std::cerr << argv[0] << ": target '" << Target.getName() From lattner at cs.uiuc.edu Wed Jan 4 18:21:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Jan 2006 18:21:49 -0600 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200601050021.SAA03312@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.125 -> 1.126 --- Log message: remove unused header --- Diffs of the changes: (+0 -1) llc.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.125 llvm/tools/llc/llc.cpp:1.126 --- llvm/tools/llc/llc.cpp:1.125 Wed Jan 4 16:28:25 2006 +++ llvm/tools/llc/llc.cpp Wed Jan 4 18:21:37 2006 @@ -27,7 +27,6 @@ #include "llvm/Support/FileUtilities.h" #include "llvm/Analysis/Verifier.h" #include "llvm/System/Signals.h" -#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/Config/config.h" #include #include From evan.cheng at apple.com Wed Jan 4 18:26:26 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 4 Jan 2006 18:26:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601050026.SAA03344@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.37 -> 1.38 --- Log message: Remove some dead code. --- Diffs of the changes: (+0 -4) SparcV8ISelDAGToDAG.cpp | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.37 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.38 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.37 Fri Dec 23 01:08:39 2005 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Wed Jan 4 18:26:14 2006 @@ -476,10 +476,6 @@ InFlag = Chain.getValue(1); } - std::vector RetVals; - RetVals.push_back(MVT::Other); - RetVals.push_back(MVT::Flag); - // If the callee is a GlobalAddress node (quite common, every direct call is) // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. if (GlobalAddressSDNode *G = dyn_cast(Callee)) From evan.cheng at apple.com Wed Jan 4 18:27:14 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 4 Jan 2006 18:27:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td Message-ID: <200601050027.SAA03366@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.19 -> 1.20 X86ISelLowering.cpp updated: 1.18 -> 1.19 X86ISelLowering.h updated: 1.9 -> 1.10 X86InstrInfo.td updated: 1.186 -> 1.187 --- Log message: DAG based isel call support. --- Diffs of the changes: (+197 -41) X86ISelDAGToDAG.cpp | 27 +++++++++ X86ISelLowering.cpp | 141 ++++++++++++++++++++++++++++++++++++++++------------ X86ISelLowering.h | 11 ++++ X86InstrInfo.td | 59 +++++++++++++++++---- 4 files changed, 197 insertions(+), 41 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.19 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.20 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.19 Wed Dec 21 17:05:39 2005 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Jan 4 18:27:02 2006 @@ -410,6 +410,33 @@ return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result); break; } + + case ISD::ConstantFP: { + Opc = 0; + if (X86ScalarSSE) { + assert(cast(N)->isExactlyValue(+0.0) && + "SSE only supports +0.0"); + Opc = (NVT == MVT::f32) ? X86::FLD0SS : X86::FLD0SD; + } + + if (cast(N)->isExactlyValue(+0.0) || + cast(N)->isExactlyValue(-0.0)) + Opc = X86::FpLD0; + else if (cast(N)->isExactlyValue(+1.0) || + cast(N)->isExactlyValue(-1.0)) + Opc = X86::FpLD1; + + assert(Opc != 0 && "Unexpected constant!"); + + SDOperand Result = CurDAG->getTargetNode(Opc, NVT); + + if (cast(N)->getValue() < 0.0 || + cast(N)->isExactlyValue(-0.0)) + Result = CurDAG->getTargetNode(X86::FpCHS, NVT, Result); + + CodeGenMap[N] = Result; + return Result; + } } return SelectCode(N); Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.18 llvm/lib/Target/X86/X86ISelLowering.cpp:1.19 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.18 Mon Dec 26 21:02:18 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Jan 4 18:27:02 2006 @@ -457,38 +457,117 @@ RetVals.push_back(MVT::i32); break; } - std::vector Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); - Ops.push_back(DAG.getConstant(0, getPointerTy())); - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - RetVals, Ops); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); - SDOperand ResultVal; - switch (RetTyVT) { - case MVT::isVoid: break; - default: - ResultVal = TheCall.getValue(1); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); - break; - case MVT::f32: - // FIXME: we would really like to remember that this FP_ROUND operation is - // okay to eliminate if we allow excess FP precision. - ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); - break; - case MVT::i64: - ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), - TheCall.getValue(2)); - break; - } + if (X86DAGIsel) { + std::vector NodeTys; + NodeTys.push_back(MVT::Other); // Returns a chain + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. - return std::make_pair(ResultVal, Chain); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + + Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + NodeTys, Ops); + SDOperand InFlag = Chain.getValue(1); + + SDOperand RetVal; + if (RetTyVT != MVT::isVoid) { + switch (RetTyVT) { + default: assert(0 && "Unknown value type to return!"); + case MVT::i1: + case MVT::i8: + RetVal = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i16: + RetVal = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i32: + RetVal = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i64: { + SDOperand Lo = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); + SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, MVT::i32, + Lo.getValue(2)); + RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); + Chain = Hi.getValue(1); + break; + } + case MVT::f32: + case MVT::f64: { + std::vector Tys; + Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(InFlag); + RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops); + Chain = RetVal.getValue(1); + if (X86ScalarSSE) { + unsigned Size = MVT::getSizeInBits(MVT::f64)/8; + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + Tys.clear(); + Tys.push_back(MVT::Other); + Ops.clear(); + Ops.push_back(Chain); + Ops.push_back(RetVal); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(RetTyVT)); + Chain = DAG.getNode(X86ISD::FST, Tys, Ops); + RetVal = DAG.getLoad(RetTyVT, Chain, StackSlot, + DAG.getSrcValue(NULL)); + Chain = RetVal.getValue(1); + } else if (RetTyVT == MVT::f32) + RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal); + break; + } + } + } + + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy()), + DAG.getConstant(0, getPointerTy())); + return std::make_pair(RetVal, Chain); + } else { + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); + Ops.push_back(DAG.getConstant(0, getPointerTy())); + + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + RetVals, Ops); + + SDOperand ResultVal; + switch (RetTyVT) { + case MVT::isVoid: break; + default: + ResultVal = TheCall.getValue(1); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); + break; + case MVT::f32: + // FIXME: we would really like to remember that this FP_ROUND operation is + // okay to eliminate if we allow excess FP precision. + ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); + break; + case MVT::i64: + ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), + TheCall.getValue(2)); + break; + } + + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); + return std::make_pair(ResultVal, Chain); + } } SDOperand @@ -1085,6 +1164,8 @@ case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM"; case X86ISD::FP_TO_INT64_IN_MEM: return "X86ISD::FP_TO_INT64_IN_MEM"; case X86ISD::FLD: return "X86ISD::FLD"; + case X86ISD::FST: return "X86ISD::FST"; + case X86ISD::FP_GET_RESULT: return "X86ISD::FP_GET_RESULT"; case X86ISD::FP_SET_RESULT: return "X86ISD::FP_SET_RESULT"; case X86ISD::CALL: return "X86ISD::CALL"; case X86ISD::TAILCALL: return "X86ISD::TAILCALL"; Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.9 llvm/lib/Target/X86/X86ISelLowering.h:1.10 --- llvm/lib/Target/X86/X86ISelLowering.h:1.9 Fri Dec 23 01:31:11 2005 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Jan 4 18:27:02 2006 @@ -46,6 +46,17 @@ /// to load to. FLD, + /// FST - This instruction implements a truncating store to FP stack + /// slots. This corresponds to the X86::FST32m / X86::FST64m. It takes a + /// chain operand, value to store, address, and a ValueType to store it + /// as. + FST, + + /// FP_SET_RESULT - This corresponds to FpGETRESULT pseudo instrcuction + /// which copies from ST(0) to the destination. It takes a chain and writes + /// a RFP result and a chain. + FP_GET_RESULT, + /// FP_SET_RESULT - This corresponds to FpSETRESULT pseudo instrcuction /// which copies the source operand to ST(0). It takes a chain and writes /// a chain and a flag. Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.186 llvm/lib/Target/X86/X86InstrInfo.td:1.187 --- llvm/lib/Target/X86/X86InstrInfo.td:1.186 Mon Dec 26 03:11:45 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Jan 4 18:27:02 2006 @@ -36,7 +36,11 @@ def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>; +def SDTX86Fst : SDTypeProfile<0, 3, [SDTCisFP<0>, + SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>; + +def SDTX86FpGet : SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>; def SDTX86FpSet : SDTypeProfile<0, 1, [SDTCisFP<0>]>; def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest, []>; @@ -49,10 +53,24 @@ def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>; def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, [SDNPHasChain]>; +def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, [SDNPHasChain]>; +def X86fpget : SDNode<"X86ISD::FP_GET_RESULT", + SDTX86FpGet, [SDNPHasChain]>; def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet, [SDNPHasChain]>; +def SDT_X86CallSeqStart : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; +def SDT_X86CallSeqEnd : SDTypeProfile<0, 2, [ SDTCisVT<0, i32>, + SDTCisVT<1, i32> ]>; +def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart, + [SDNPHasChain]>; +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd, + [SDNPHasChain]>; + +def SDT_X86Call : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; +def call : SDNode<"X86ISD::CALL", SDT_X86Call, [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // X86 Operand Definitions. // @@ -275,9 +293,11 @@ def PHI : I<0, Pseudo, (ops variable_ops), "PHINODE", []>; // PHI node. def NOOP : I<0x90, RawFrm, (ops), "nop", []>; // nop -def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN", []>; +def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN", + [(callseq_start imm:$amt)]>; def ADJCALLSTACKUP : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2), - "#ADJCALLSTACKUP", []>; + "#ADJCALLSTACKUP", + [(callseq_end imm:$amt1, imm:$amt2)]>; def IMPLICIT_USE : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_USE", []>; def IMPLICIT_DEF : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_DEF", []>; let isTerminator = 1 in @@ -301,9 +321,6 @@ } } -def : Pat<(X86retflag 0), (RET)>; -def : Pat<(X86retflag imm:$amt), (RETI imm:$amt)>; - // All branches are RawFrm, Void, Branch, and Terminators let isBranch = 1, isTerminator = 1, noResults = 1 in class IBr opcode, dag ops, string asm, list pattern> : @@ -342,15 +359,25 @@ //===----------------------------------------------------------------------===// // Call Instructions... // -let isCall = 1, noResults = 1 in +// FIXME: How about hasInFlag = 1? A fastcall would require an incoming flag +// to stick the CopyToRegs to the call. +let isCall = 1, noResults = 1, hasOutFlag = 1 in // All calls clobber the non-callee saved registers... let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in { - def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst", []>; - def CALL32r : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst", []>; - def CALL32m : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst", []>; + def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst", + []>; + def CALL32r : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst", + []>; + def CALL32m : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst", + []>; } +def : Pat<(call tglobaladdr:$dst), + (CALLpcrel32 tglobaladdr:$dst)>; +def : Pat<(call externalsym:$dst), + (CALLpcrel32 externalsym:$dst)>; + // Tail call stuff. let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in def TAILJMPd : IBr<0xE9, (ops calltarget:$dst), "jmp $dst # TAIL CALL", []>; @@ -2309,11 +2336,17 @@ } // Random Pseudo Instructions. -def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, []>; // FPR = ST(0) +let hasInFlag = 1 in + def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, []>; // FPR = ST(0) + +// Do not inline into instruction def. since it isn't predicated on FPStack. +def : Pat<(X86fpget), (FpGETRESULT)>; + let noResults = 1, hasOutFlag = 1 in def FpSETRESULT : FpI<(ops RFP:$src), SpecialFP, []>, Imp<[], [ST0]>; // ST(0) = FPR +// Do not inline into instruction def. since it isn't predicated on FPStack. def : Pat<(X86fpset RFP:$src), (FpSETRESULT RFP:$src)>; def FpMOV : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2 @@ -2359,7 +2392,7 @@ [(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>; // ST(0) = ST(0) - [mem64] def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, - [(set RFP:$dst, (fadd (extloadf64f32 addr:$src2), + [(set RFP:$dst, (fsub (extloadf64f32 addr:$src2), RFP:$src1))]>; // ST(0) = [mem32] - ST(0) def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW, @@ -2503,6 +2536,10 @@ [(truncstore RFP:$src, addr:$op, f32)]>; def FpST64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, [(store RFP:$src, addr:$op)]>; + +def : Pat<(X86fst RFP:$src, addr:$op, f32), (FpST32m addr:$op, RFP:$src)>; +def : Pat<(X86fst RFP:$src, addr:$op, f64), (FpST64m addr:$op, RFP:$src)>; + def FpSTP32m : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>; def FpSTP64m : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>; def FpIST16m : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>; From jlaskey at apple.com Wed Jan 4 19:25:43 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:25:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCISelLowering.cpp PPCInstrInfo.td Message-ID: <200601050125.TAA03595@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.135 -> 1.136 PPCISelLowering.cpp updated: 1.56 -> 1.57 PPCInstrInfo.td updated: 1.168 -> 1.169 --- Log message: Added initial support for DEBUG_LABEL allowing debug specific labels to be inserted in the code. --- Diffs of the changes: (+16 -6) PPCAsmPrinter.cpp | 6 +++++- PPCISelLowering.cpp | 5 ++++- PPCInstrInfo.td | 11 +++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.135 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.136 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.135 Wed Jan 4 16:28:25 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Wed Jan 4 19:25:28 2006 @@ -252,7 +252,9 @@ bool doFinalization(Module &M); void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); AU.addRequired(); + PPCAsmPrinter::getAnalysisUsage(AU); } }; @@ -418,6 +420,9 @@ /// method to print assembly for each instruction. /// bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + // FIXME - is this the earliest this can be set. + DW.SetDebugInfo(&getAnalysis()); + SetupMachineFunction(MF); O << "\n\n"; @@ -486,7 +491,6 @@ Mang->setUseQuotes(true); // Emit initial debug information. - DW.SetDebugInfo(getAnalysisToUpdate()); DW.BeginModule(); return false; } Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.56 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.57 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.56 Thu Dec 29 18:11:07 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed Jan 4 19:25:28 2006 @@ -94,8 +94,11 @@ // PowerPC does not have truncstore for i1. setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); - // PowerPC doesn't have line number support yet. + // Support label based line numbers. setOperationAction(ISD::LOCATION, MVT::Other, Expand); + // FIXME - use subtarget debug flags + if (TM.getSubtarget().isDarwin()) + setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); // We want to legalize GlobalAddress and ConstantPool nodes into the // appropriate instructions to materialize the address. Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.168 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.169 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.168 Wed Jan 4 09:04:11 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Wed Jan 4 19:25:28 2006 @@ -955,11 +955,14 @@ // DWARF Pseudo Instructions // -def DWARF_LOC : Pseudo<(ops i32imm:$line, i32imm:$col, i32imm:$file, - i32imm:$id), - "; .loc $file, $line, $col\nLdebug_loc$id:", +def DWARF_LOC : Pseudo<(ops i32imm:$line, i32imm:$col, i32imm:$file), + "; .loc $file, $line, $col", [(dwarf_loc (i32 imm:$line), (i32 imm:$col), - (i32 imm:$file), (i32 imm:$id))]>; + (i32 imm:$file))]>; + +def DWARF_LABEL : Pseudo<(ops i32imm:$id), + "\nLdebug_loc$id:", + [(dwarf_label (i32 imm:$id))]>; //===----------------------------------------------------------------------===// // PowerPC Instruction Patterns From jlaskey at apple.com Wed Jan 4 19:25:44 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:25:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelLowering.cpp IA64ISelPattern.cpp Message-ID: <200601050125.TAA03605@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelLowering.cpp updated: 1.9 -> 1.10 IA64ISelPattern.cpp updated: 1.71 -> 1.72 --- Log message: Added initial support for DEBUG_LABEL allowing debug specific labels to be inserted in the code. --- Diffs of the changes: (+0 -2) IA64ISelLowering.cpp | 1 - IA64ISelPattern.cpp | 1 - 2 files changed, 2 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelLowering.cpp diff -u llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.9 llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.10 --- llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.9 Tue Dec 27 04:17:03 2005 +++ llvm/lib/Target/IA64/IA64ISelLowering.cpp Wed Jan 4 19:25:28 2006 @@ -74,7 +74,6 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); //IA64 has these, but they are not implemented setOperationAction(ISD::CTTZ , MVT::i64 , Expand); Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.71 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.72 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.71 Thu Dec 22 15:15:41 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Wed Jan 4 19:25:28 2006 @@ -102,7 +102,6 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); computeRegisterProperties(); From jlaskey at apple.com Wed Jan 4 19:25:44 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:25:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200601050125.TAA03599@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.39 -> 1.40 --- Log message: Added initial support for DEBUG_LABEL allowing debug specific labels to be inserted in the code. --- Diffs of the changes: (+6 -3) TargetSelectionDAG.td | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.39 llvm/lib/Target/TargetSelectionDAG.td:1.40 --- llvm/lib/Target/TargetSelectionDAG.td:1.39 Wed Jan 4 09:04:11 2006 +++ llvm/lib/Target/TargetSelectionDAG.td Wed Jan 4 19:25:28 2006 @@ -440,9 +440,12 @@ //===----------------------------------------------------------------------===// // Dwarf support. // -def SDT_dwarf_loc : SDTypeProfile<0, 4, - [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>, SDTCisInt<3>]>; -def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>; +def SDT_dwarf_loc : SDTypeProfile<0, 3, + [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>; +def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>; + +def SDT_dwarf_label : SDTypeProfile<0, 1, [SDTCisInt<0>]>; +def dwarf_label : SDNode<"ISD::DEBUG_LABEL", SDT_dwarf_label,[SDNPHasChain]>; From jlaskey at apple.com Wed Jan 4 19:25:45 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:25:45 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/DwarfWriter.h MachineDebugInfo.h SelectionDAGNodes.h Message-ID: <200601050125.TAA03633@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: DwarfWriter.h updated: 1.5 -> 1.6 MachineDebugInfo.h updated: 1.4 -> 1.5 SelectionDAGNodes.h updated: 1.86 -> 1.87 --- Log message: Added initial support for DEBUG_LABEL allowing debug specific labels to be inserted in the code. --- Diffs of the changes: (+19 -6) DwarfWriter.h | 5 +++-- MachineDebugInfo.h | 7 +++++++ SelectionDAGNodes.h | 13 +++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) Index: llvm/include/llvm/CodeGen/DwarfWriter.h diff -u llvm/include/llvm/CodeGen/DwarfWriter.h:1.5 llvm/include/llvm/CodeGen/DwarfWriter.h:1.6 --- llvm/include/llvm/CodeGen/DwarfWriter.h:1.5 Wed Jan 4 16:28:25 2006 +++ llvm/include/llvm/CodeGen/DwarfWriter.h Wed Jan 4 19:25:28 2006 @@ -550,8 +550,9 @@ /// void EmitInitial() const; - /// ShouldEmitDwarf - Determine if dwarf declarations should be made. - /// + /// ShouldEmitDwarf - Returns true if dwarf declarations should be made. + /// When called it also checks to see if debug info is newly available. if + /// so the initial dwarf headers are emitted. bool ShouldEmitDwarf(); /// BeginModule - Emit all dwarf sections that should come prior to the Index: llvm/include/llvm/CodeGen/MachineDebugInfo.h diff -u llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.4 llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.5 --- llvm/include/llvm/CodeGen/MachineDebugInfo.h:1.4 Wed Jan 4 16:28:25 2006 +++ llvm/include/llvm/CodeGen/MachineDebugInfo.h Wed Jan 4 19:25:28 2006 @@ -52,6 +52,13 @@ /// unsigned getNextUniqueID() { return UniqueID++; } + /// RecordLabel - Records location information and associates it with a + /// debug label. Returns unique label id. + unsigned RecordLabel(unsigned Line, unsigned Col, unsigned SrcFile) { + // FIXME - actually record. + return getNextUniqueID(); + } + bool doInitialization(); bool doFinalization(); Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.86 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.87 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.86 Wed Jan 4 09:04:11 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Wed Jan 4 19:25:28 2006 @@ -355,12 +355,17 @@ LOCATION, // DEBUG_LOC - This node is used to represent source line information - // embedded in the code. It takes token chain as input, then a line number, - // then a column then a file id (provided by MachineDebugInfo), then a - // unique id (provided by MachineDebugInfo for label gen). It produces a - // token chain as output. + // embedded in the code. It takes a token chain as input, then a line + // number, then a column then a file id (provided by MachineDebugInfo.) It + // produces a token chain as output. DEBUG_LOC, + // DEBUG_LABEL - This node is used to mark a location in the code where a + // label should be generated for use by the debug information. It takes a + // token chain as input, the a unique id (provided by MachineDebugInfo.) It + // produces a token chain as output. + DEBUG_LABEL, + // BUILTIN_OP_END - This must be the last enum value in this list. BUILTIN_OP_END, }; From jlaskey at apple.com Wed Jan 4 19:25:45 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:25:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601050125.TAA03609@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.38 -> 1.39 --- Log message: Added initial support for DEBUG_LABEL allowing debug specific labels to be inserted in the code. --- Diffs of the changes: (+0 -1) SparcV8ISelDAGToDAG.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.38 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.39 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.38 Wed Jan 4 18:26:14 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Wed Jan 4 19:25:28 2006 @@ -153,7 +153,6 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); computeRegisterProperties(); } From jlaskey at apple.com Wed Jan 4 19:25:45 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:25:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp Message-ID: <200601050125.TAA03611@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.16 -> 1.17 --- Log message: Added initial support for DEBUG_LABEL allowing debug specific labels to be inserted in the code. --- Diffs of the changes: (+0 -1) AlphaISelLowering.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.16 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.17 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.16 Sat Dec 24 19:34:27 2005 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Wed Jan 4 19:25:28 2006 @@ -103,7 +103,6 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); // We want to legalize GlobalAddress and ConstantPool and // ExternalSymbols nodes into the appropriate instructions to From jlaskey at apple.com Wed Jan 4 19:25:45 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:25:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp SelectionDAG.cpp Message-ID: <200601050125.TAA03625@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.76 -> 1.77 LegalizeDAG.cpp updated: 1.252 -> 1.253 SelectionDAG.cpp updated: 1.233 -> 1.234 --- Log message: Added initial support for DEBUG_LABEL allowing debug specific labels to be inserted in the code. --- Diffs of the changes: (+57 -31) DAGCombiner.cpp | 3 - LegalizeDAG.cpp | 84 ++++++++++++++++++++++++++++++++++++------------------- SelectionDAG.cpp | 1 3 files changed, 57 insertions(+), 31 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.76 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.77 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.76 Wed Jan 4 09:04:11 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Jan 4 19:25:28 2006 @@ -2117,8 +2117,7 @@ return DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Chain.getOperand(0), N->getOperand(1), N->getOperand(2), - N->getOperand(3), - N->getOperand(4)); + N->getOperand(3)); } return SDOperand(); Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.252 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.253 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.252 Wed Jan 4 16:28:25 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Jan 4 19:25:28 2006 @@ -619,20 +619,33 @@ default: assert(0 && "This action is not supported yet!"); case TargetLowering::Expand: { MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo(); - if (TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other) && DebugInfo) { - std::vector Ops; - Ops.push_back(Tmp1); // chain - Ops.push_back(Node->getOperand(1)); // line # - Ops.push_back(Node->getOperand(2)); // col # - const std::string &fname = + bool useDEBUG_LOC = TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other); + bool useDEBUG_LABEL = TLI.isOperationLegal(ISD::DEBUG_LABEL, MVT::Other); + + if (DebugInfo && (useDEBUG_LOC || useDEBUG_LABEL)) { + const std::string &FName = cast(Node->getOperand(3))->getValue(); - const std::string &dirname = + const std::string &DirName = cast(Node->getOperand(4))->getValue(); - unsigned srcfile = DebugInfo->getUniqueSourceID(fname, dirname); - Ops.push_back(DAG.getConstant(srcfile, MVT::i32)); // source file id - unsigned id = DebugInfo->getNextUniqueID(); - Ops.push_back(DAG.getConstant(id, MVT::i32)); // label id - Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops); + unsigned SrcFile = DebugInfo->getUniqueSourceID(FName, DirName); + + std::vector Ops; + Ops.push_back(Tmp1); // chain + SDOperand LineOp = Node->getOperand(1); + SDOperand ColOp = Node->getOperand(2); + + if (useDEBUG_LOC) { + Ops.push_back(LineOp); // line # + Ops.push_back(ColOp); // col # + Ops.push_back(DAG.getConstant(SrcFile, MVT::i32)); // source file id + Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops); + } else { + unsigned Line = dyn_cast(LineOp)->getValue(); + unsigned Col = dyn_cast(ColOp)->getValue(); + unsigned ID = DebugInfo->RecordLabel(Line, Col, SrcFile); + Ops.push_back(DAG.getConstant(ID, MVT::i32)); + Result = DAG.getNode(ISD::DEBUG_LABEL, MVT::Other, Ops); + } } else { Result = Tmp1; // chain } @@ -661,27 +674,40 @@ break; case ISD::DEBUG_LOC: - assert(Node->getNumOperands() == 5 && "Invalid DEBUG_LOC node!"); + assert(Node->getNumOperands() == 4 && "Invalid DEBUG_LOC node!"); switch (TLI.getOperationAction(ISD::DEBUG_LOC, MVT::Other)) { case TargetLowering::Promote: case TargetLowering::Expand: default: assert(0 && "This action is not supported yet!"); - case TargetLowering::Legal: { - SDOperand Tmp5; - Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. - Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the line #. - Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the col #. - Tmp4 = LegalizeOp(Node->getOperand(3)); // Legalize the source file id. - Tmp5 = LegalizeOp(Node->getOperand(4)); // Legalize the label id. - - if (Tmp1 != Node->getOperand(0) || - Tmp2 != Node->getOperand(1) || - Tmp3 != Node->getOperand(2) || - Tmp4 != Node->getOperand(3) || - Tmp5 != Node->getOperand(4)) { - Result = - DAG.getNode(ISD::DEBUG_LOC,MVT::Other, Tmp1, Tmp2, Tmp3, Tmp4, Tmp5); - } + case TargetLowering::Legal: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the line #. + Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the col #. + Tmp4 = LegalizeOp(Node->getOperand(3)); // Legalize the source file id. + + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1) || + Tmp3 != Node->getOperand(2) || + Tmp4 != Node->getOperand(3)) { + Result = DAG.getNode(ISD::DEBUG_LOC,MVT::Other, Tmp1, Tmp2, Tmp3, Tmp4); + } + break; + } + break; + + case ISD::DEBUG_LABEL: + assert(Node->getNumOperands() == 2 && "Invalid DEBUG_LABEL node!"); + switch (TLI.getOperationAction(ISD::DEBUG_LABEL, MVT::Other)) { + case TargetLowering::Promote: + case TargetLowering::Expand: + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Legal: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the label id. + + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) { + Result = DAG.getNode(ISD::DEBUG_LABEL, MVT::Other, Tmp1, Tmp2); } break; } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.233 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.234 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.233 Thu Dec 29 18:10:38 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Jan 4 19:25:28 2006 @@ -2005,6 +2005,7 @@ // Debug info case ISD::LOCATION: return "location"; case ISD::DEBUG_LOC: return "debug_loc"; + case ISD::DEBUG_LABEL: return "debug_label"; case ISD::CONDCODE: switch (cast(this)->get()) { From jlaskey at apple.com Wed Jan 4 19:25:45 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:25:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200601050125.TAA03617@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.19 -> 1.20 --- Log message: Added initial support for DEBUG_LABEL allowing debug specific labels to be inserted in the code. --- Diffs of the changes: (+0 -1) X86ISelLowering.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.19 llvm/lib/Target/X86/X86ISelLowering.cpp:1.20 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.19 Wed Jan 4 18:27:02 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Jan 4 19:25:28 2006 @@ -130,7 +130,6 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); if (X86ScalarSSE) { // Set up the FP register classes. From jlaskey at apple.com Wed Jan 4 19:47:58 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:47:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200601050147.TAA03703@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.57 -> 1.58 --- Log message: Had expand logic backward. --- Diffs of the changes: (+2 -1) PPCISelLowering.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.57 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.58 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.57 Wed Jan 4 19:25:28 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed Jan 4 19:47:43 2006 @@ -96,8 +96,9 @@ // Support label based line numbers. setOperationAction(ISD::LOCATION, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); // FIXME - use subtarget debug flags - if (TM.getSubtarget().isDarwin()) + if (!TM.getSubtarget().isDarwin()) setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); // We want to legalize GlobalAddress and ConstantPool nodes into the From jlaskey at apple.com Wed Jan 4 19:47:58 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:47:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601050147.TAA03715@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.39 -> 1.40 --- Log message: Had expand logic backward. --- Diffs of the changes: (+2 -0) SparcV8ISelDAGToDAG.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.39 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.40 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.39 Wed Jan 4 19:25:28 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Wed Jan 4 19:47:43 2006 @@ -153,6 +153,8 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); computeRegisterProperties(); } From jlaskey at apple.com Wed Jan 4 19:47:58 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:47:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200601050147.TAA03705@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.20 -> 1.21 --- Log message: Had expand logic backward. --- Diffs of the changes: (+2 -0) X86ISelLowering.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.20 llvm/lib/Target/X86/X86ISelLowering.cpp:1.21 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.20 Wed Jan 4 19:25:28 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Jan 4 19:47:43 2006 @@ -130,6 +130,8 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); if (X86ScalarSSE) { // Set up the FP register classes. From jlaskey at apple.com Wed Jan 4 19:47:58 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:47:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp Message-ID: <200601050147.TAA03711@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.17 -> 1.18 --- Log message: Had expand logic backward. --- Diffs of the changes: (+2 -0) AlphaISelLowering.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.17 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.18 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.17 Wed Jan 4 19:25:28 2006 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Wed Jan 4 19:47:43 2006 @@ -103,6 +103,8 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); // We want to legalize GlobalAddress and ConstantPool and // ExternalSymbols nodes into the appropriate instructions to From jlaskey at apple.com Wed Jan 4 19:47:58 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:47:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelLowering.cpp IA64ISelPattern.cpp Message-ID: <200601050147.TAA03721@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelLowering.cpp updated: 1.10 -> 1.11 IA64ISelPattern.cpp updated: 1.72 -> 1.73 --- Log message: Had expand logic backward. --- Diffs of the changes: (+4 -0) IA64ISelLowering.cpp | 2 ++ IA64ISelPattern.cpp | 2 ++ 2 files changed, 4 insertions(+) Index: llvm/lib/Target/IA64/IA64ISelLowering.cpp diff -u llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.10 llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.11 --- llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.10 Wed Jan 4 19:25:28 2006 +++ llvm/lib/Target/IA64/IA64ISelLowering.cpp Wed Jan 4 19:47:43 2006 @@ -74,6 +74,8 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); //IA64 has these, but they are not implemented setOperationAction(ISD::CTTZ , MVT::i64 , Expand); Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.72 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.73 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.72 Wed Jan 4 19:25:28 2006 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Wed Jan 4 19:47:43 2006 @@ -102,6 +102,8 @@ // We don't have line number support yet. setOperationAction(ISD::LOCATION, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); + setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); computeRegisterProperties(); From jlaskey at apple.com Wed Jan 4 19:53:39 2006 From: jlaskey at apple.com (Jim Laskey) Date: Wed, 4 Jan 2006 19:53:39 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200601050153.TAA03772@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.87 -> 1.88 --- Log message: Grammer correction. --- Diffs of the changes: (+2 -2) SelectionDAGNodes.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.87 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.88 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.87 Wed Jan 4 19:25:28 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Wed Jan 4 19:53:28 2006 @@ -362,8 +362,8 @@ // DEBUG_LABEL - This node is used to mark a location in the code where a // label should be generated for use by the debug information. It takes a - // token chain as input, the a unique id (provided by MachineDebugInfo.) It - // produces a token chain as output. + // token chain as input and then a unique id (provided by MachineDebugInfo.) + // It produces a token chain as output. DEBUG_LABEL, // BUILTIN_OP_END - This must be the last enum value in this list. From evan.cheng at apple.com Wed Jan 4 20:08:00 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 4 Jan 2006 20:08:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200601050208.UAA03950@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.40 -> 1.41 --- Log message: Added fpimm node for ConstantFP. --- Diffs of the changes: (+2 -0) TargetSelectionDAG.td | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.40 llvm/lib/Target/TargetSelectionDAG.td:1.41 --- llvm/lib/Target/TargetSelectionDAG.td:1.40 Wed Jan 4 19:25:28 2006 +++ llvm/lib/Target/TargetSelectionDAG.td Wed Jan 4 20:07:49 2006 @@ -70,6 +70,7 @@ // Builtin profiles. def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. +def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'. def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'. def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. @@ -190,6 +191,7 @@ def srcvalue; def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">; +def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">; def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">; def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">; def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">; From evan.cheng at apple.com Wed Jan 4 20:08:48 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 4 Jan 2006 20:08:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86InstrInfo.td Message-ID: <200601050208.UAA03964@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.20 -> 1.21 X86InstrInfo.td updated: 1.187 -> 1.188 --- Log message: Added ConstantFP patterns. --- Diffs of the changes: (+33 -31) X86ISelDAGToDAG.cpp | 27 --------------------------- X86InstrInfo.td | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 31 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.20 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.21 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.20 Wed Jan 4 18:27:02 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Jan 4 20:08:37 2006 @@ -410,33 +410,6 @@ return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result); break; } - - case ISD::ConstantFP: { - Opc = 0; - if (X86ScalarSSE) { - assert(cast(N)->isExactlyValue(+0.0) && - "SSE only supports +0.0"); - Opc = (NVT == MVT::f32) ? X86::FLD0SS : X86::FLD0SD; - } - - if (cast(N)->isExactlyValue(+0.0) || - cast(N)->isExactlyValue(-0.0)) - Opc = X86::FpLD0; - else if (cast(N)->isExactlyValue(+1.0) || - cast(N)->isExactlyValue(-1.0)) - Opc = X86::FpLD1; - - assert(Opc != 0 && "Unexpected constant!"); - - SDOperand Result = CurDAG->getTargetNode(Opc, NVT); - - if (cast(N)->getValue() < 0.0 || - cast(N)->isExactlyValue(-0.0)) - Result = CurDAG->getTargetNode(X86::FpCHS, NVT, Result); - - CodeGenMap[N] = Result; - return Result; - } } return SelectCode(N); Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.187 llvm/lib/Target/X86/X86InstrInfo.td:1.188 --- llvm/lib/Target/X86/X86InstrInfo.td:1.187 Wed Jan 4 18:27:02 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Jan 4 20:08:37 2006 @@ -244,6 +244,26 @@ return (unsigned)N->getValue() == (unsigned char)N->getValue(); }]>; +def fp32imm0 : PatLeaf<(f32 fpimm), [{ + return N->isExactlyValue(+0.0); +}]>; + +def fp64imm0 : PatLeaf<(f64 fpimm), [{ + return N->isExactlyValue(+0.0); +}]>; + +def fp64immneg0 : PatLeaf<(f64 fpimm), [{ + return N->isExactlyValue(-0.0); +}]>; + +def fp64imm1 : PatLeaf<(f64 fpimm), [{ + return N->isExactlyValue(+1.0); +}]>; + +def fp64immneg1 : PatLeaf<(f64 fpimm), [{ + return N->isExactlyValue(-1.0); +}]>; + // Helper fragments for loads. def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>; def loadi16 : PatFrag<(ops node:$ptr), (i16 (load node:$ptr))>; @@ -2187,9 +2207,13 @@ // Pseudo-instructions that map fld0 to xorps/xorpd for sse. // FIXME: remove when we can teach regalloc that xor reg, reg is ok. def FLD0SS : I<0x57, MRMSrcReg, (ops FR32:$dst), - "xorps $dst, $dst", []>, Requires<[HasSSE1]>, TB; + "xorps $dst, $dst", + [(set FR32:$dst, fp32imm0)]>, + Requires<[HasSSE1]>, TB; def FLD0SD : I<0x57, MRMSrcReg, (ops FR64:$dst), - "xorpd $dst, $dst", []>, Requires<[HasSSE2]>, TB, OpSize; + "xorpd $dst, $dst", + [(set FR64:$dst, fp64imm0)]>, + Requires<[HasSSE2]>, TB, OpSize; let isTwoAddress = 1 in { // SSE Scalar Arithmetic @@ -2568,8 +2592,13 @@ def FXCH : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9; // Floating point constant loads. -def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP, []>; -def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP, []>; +def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP, + [(set RFP:$dst, fp64imm0)]>; +def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP, + [(set RFP:$dst, fp64imm1)]>; + +def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>; +def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>; def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9; def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9; From lattner at cs.uiuc.edu Wed Jan 4 22:48:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 4 Jan 2006 22:48:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.td Message-ID: <200601050448.WAA04881@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.td updated: 1.97 -> 1.98 --- Log message: unbreak the build, these are now in TargetSelectionDAG.td --- Diffs of the changes: (+0 -3) AlphaInstrInfo.td | 3 --- 1 files changed, 3 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.97 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.98 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.97 Sun Jan 1 16:16:14 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Wed Jan 4 22:48:15 2006 @@ -34,9 +34,6 @@ def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeq,[SDNPHasChain]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeq,[SDNPHasChain]>; -def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'. -def fpimm : SDNode<"ISD::ConstantFP" , SDTFPLeaf , [], "ConstantFPSDNode">; - //******************** //Paterns for matching //******************** From lattner at cs.uiuc.edu Thu Jan 5 01:20:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Jan 2006 01:20:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp Message-ID: <200601050720.BAA15019@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.cpp updated: 1.79 -> 1.80 --- Log message: fix some formatting problems --- Diffs of the changes: (+7 -7) ConstantFolding.cpp | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.79 llvm/lib/VMCore/ConstantFolding.cpp:1.80 --- llvm/lib/VMCore/ConstantFolding.cpp:1.79 Tue Jan 3 20:20:54 2006 +++ llvm/lib/VMCore/ConstantFolding.cpp Thu Jan 5 01:19:51 2006 @@ -235,7 +235,7 @@ // struct BoolRules : public TemplateRules { - static Constant *LessThan(const ConstantBool *V1, const ConstantBool *V2){ + static Constant *LessThan(const ConstantBool *V1, const ConstantBool *V2) { return ConstantBool::get(V1->getValue() < V2->getValue()); } @@ -800,13 +800,13 @@ if (SwappedRelation != Instruction::BinaryOpsEnd) return SetCondInst::getSwappedCondition(SwappedRelation); - } else if (const GlobalValue *CPR1 = dyn_cast(V1)){ + } else if (const GlobalValue *CPR1 = dyn_cast(V1)) { if (isa(V2)) { // Swap as necessary. - Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1); - if (SwappedRelation != Instruction::BinaryOpsEnd) - return SetCondInst::getSwappedCondition(SwappedRelation); - else - return Instruction::BinaryOpsEnd; + Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1); + if (SwappedRelation != Instruction::BinaryOpsEnd) + return SetCondInst::getSwappedCondition(SwappedRelation); + else + return Instruction::BinaryOpsEnd; } // Now we know that the RHS is a GlobalValue or simple constant, From lattner at cs.uiuc.edu Thu Jan 5 01:46:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Jan 2006 01:46:58 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/ConstantExprFold.llx Message-ID: <200601050746.BAA17823@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: ConstantExprFold.llx updated: 1.2 -> 1.3 --- Log message: new tests, derived from cosmics scheme output --- Diffs of the changes: (+5 -1) ConstantExprFold.llx | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) Index: llvm/test/Regression/Assembler/ConstantExprFold.llx diff -u llvm/test/Regression/Assembler/ConstantExprFold.llx:1.2 llvm/test/Regression/Assembler/ConstantExprFold.llx:1.3 --- llvm/test/Regression/Assembler/ConstantExprFold.llx:1.2 Thu Jul 8 10:38:23 2004 +++ llvm/test/Regression/Assembler/ConstantExprFold.llx Thu Jan 5 01:46:46 2006 @@ -1,6 +1,7 @@ ; This test checks to make sure that constant exprs fold in some simple situations -; RUN: llvm-as < %s | llvm-dis | not grep '(' +; RUN: llvm-as < %s | llvm-dis | not grep '(' && +; RUN: llvm-as < %s %A = global long 0 @@ -23,3 +24,6 @@ int* getelementptr (%Ty* %B, long 0, ubyte 1)) ; true ;global bool setne (long* %A, long* cast (%Ty* %B to long*)) ; true +global bool seteq ({ short }* cast (int 1 to { short }*), { short }* null) +global bool setlt ({ short }* cast (int 1 to { short }*), { short }* cast (int 2 to { short }*)) + From lattner at cs.uiuc.edu Thu Jan 5 01:49:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Jan 2006 01:49:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp Message-ID: <200601050749.BAA18285@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.cpp updated: 1.80 -> 1.81 --- Log message: Implement a few symbolic constant folding things. X ? Y : Y is Y. Fold: seteq ({ short }* cast (int 1 to { short }*), { short }* null) setlt ({ short }* cast (int 1 to { short }*), { short }* cast (int 2 to { short }*)) to false/true. These last two commonly occur in the output of compilers that tag integers, like cozmic's scheme compiler. Tested by Regression/Assembler/ConstantExprFold.llx --- Diffs of the changes: (+32 -7) ConstantFolding.cpp | 39 ++++++++++++++++++++++++++++++++------- 1 files changed, 32 insertions(+), 7 deletions(-) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.80 llvm/lib/VMCore/ConstantFolding.cpp:1.81 --- llvm/lib/VMCore/ConstantFolding.cpp:1.80 Thu Jan 5 01:19:51 2006 +++ llvm/lib/VMCore/ConstantFolding.cpp Thu Jan 5 01:49:30 2006 @@ -720,6 +720,7 @@ if (isa(V1)) return const_cast(V2); if (isa(V2)) return const_cast(V1); if (isa(Cond)) return const_cast(V1); + if (V1 == V2) return const_cast(V1); return 0; } @@ -786,16 +787,27 @@ /// constants (like ConstantInt) to be the simplest, followed by /// GlobalValues, followed by ConstantExpr's (the most complex). /// -static Instruction::BinaryOps evaluateRelation(const Constant *V1, - const Constant *V2) { +static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { assert(V1->getType() == V2->getType() && "Cannot compare different types of values!"); if (V1 == V2) return Instruction::SetEQ; if (!isa(V1) && !isa(V1)) { + if (!isa(V2) && !isa(V2)) { + // We distilled this down to a simple case, use the standard constant + // folder. + ConstantBool *R = dyn_cast(ConstantExpr::getSetEQ(V1, V2)); + if (R == ConstantBool::True) return Instruction::SetEQ; + R = dyn_cast(ConstantExpr::getSetLT(V1, V2)); + if (R == ConstantBool::True) return Instruction::SetLT; + R = dyn_cast(ConstantExpr::getSetGT(V1, V2)); + if (R == ConstantBool::True) return Instruction::SetGT; + + // If we couldn't figure it out, bail. + return Instruction::BinaryOpsEnd; + } + // If the first operand is simple, swap operands. - assert((isa(V2) || isa(V2)) && - "Simple cases should have been handled by caller!"); Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1); if (SwappedRelation != Instruction::BinaryOpsEnd) return SetCondInst::getSwappedCondition(SwappedRelation); @@ -826,7 +838,7 @@ } else { // Ok, the LHS is known to be a constantexpr. The RHS can be any of a // constantexpr, a CPR, or a simple constant. - const ConstantExpr *CE1 = cast(V1); + ConstantExpr *CE1 = cast(V1); Constant *CE1Op0 = CE1->getOperand(0); switch (CE1->getOpcode()) { @@ -834,9 +846,21 @@ // If the cast is not actually changing bits, and the second operand is a // null pointer, do the comparison with the pre-casted value. if (V2->isNullValue() && - CE1->getType()->isLosslesslyConvertibleTo(CE1Op0->getType())) + (isa(CE1->getType()) || CE1->getType()->isIntegral())) return evaluateRelation(CE1Op0, Constant::getNullValue(CE1Op0->getType())); + + // If the dest type is a pointer type, and the RHS is a constantexpr cast + // from the same type as the src of the LHS, evaluate the inputs. This is + // important for things like "seteq (cast 4 to int*), (cast 5 to int*)", + // which happens a lot in compilers with tagged integers. + if (ConstantExpr *CE2 = dyn_cast(V2)) + if (isa(CE1->getType()) && + CE2->getOpcode() == Instruction::Cast && + CE1->getOperand(0)->getType() == CE2->getOperand(0)->getType() && + CE1->getOperand(0)->getType()->isIntegral()) { + return evaluateRelation(CE1->getOperand(0), CE2->getOperand(0)); + } break; case Instruction::GetElementPtr: @@ -977,7 +1001,8 @@ if (SetCondInst::isRelational(Opcode)) { if (isa(V1) || isa(V2)) return UndefValue::get(Type::BoolTy); - switch (evaluateRelation(V1, V2)) { + switch (evaluateRelation(const_cast(V1), + const_cast(V2))) { default: assert(0 && "Unknown relational!"); case Instruction::BinaryOpsEnd: break; // Couldn't determine anything about these constants. From bocchino at persephone.cs.uiuc.edu Thu Jan 5 11:37:32 2006 From: bocchino at persephone.cs.uiuc.edu (Robert L. Bocchino Jr.) Date: Thu, 5 Jan 2006 11:37:32 -0600 (CST) Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <20060105173732.1723B1C93BEA@persephone.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.119 -> 1.120 --- Log message: Added the spec for the new "extractelement" instruction. --- Diffs of the changes: (+45 -1) LangRef.html | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 45 insertions(+), 1 deletion(-) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.119 llvm/docs/LangRef.html:1.120 --- llvm/docs/LangRef.html:1.119 Tue Nov 15 00:07:55 2005 +++ llvm/docs/LangRef.html Thu Jan 5 11:37:02 2006 @@ -100,6 +100,7 @@
  • 'phi' Instruction
  • 'cast .. to' Instruction
  • 'select' Instruction
  • +
  • 'extractelement' Instruction
  • 'call' Instruction
  • 'vaarg' Instruction
  • @@ -2230,8 +2231,51 @@ + + + +
    + +
    Syntax:
    + +
    +  <result> = extractelement <n x <ty>> <val>, uint <idx>    ; yields <ty>
    +
    + +
    Overview:
    + +

    +The 'extractelement' instruction extracts a single scalar +element from a vector at a specified index. +

    +
    Arguments:
    + +

    +The first operand of an 'extractelement' instruction is a +value of packed type. The second operand is +an index indicating the position from which to extract the element. +The index may be a variable.

    + +
    Semantics:
    + +

    +The result is a scalar of the same type as the element type of +val. Its value is the value at position idx of +val. If idx exceeds the length of val, the +results are undefined. +

    + +
    Example:
    + +
    +  %result = extractelement <4 x int> %vec, uint 0    ; yields int
    +
    +
    +
    @@ -3429,7 +3473,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/11/15 06:07:55 $ + Last modified: $Date: 2006/01/05 17:37:02 $ From lattner at cs.uiuc.edu Thu Jan 5 12:33:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Jan 2006 12:33:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200601051833.MAA12103@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.147 -> 1.148 --- Log message: Fix a compile crash building MultiSource/Applications/d with the new front-end. The PPC backend was generating random shift counts in this case, due to an uninitialized variable. --- Diffs of the changes: (+2 -2) PPCISelDAGToDAG.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.147 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.148 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.147 Fri Dec 23 19:00:15 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Jan 5 12:32:49 2006 @@ -952,13 +952,13 @@ if (isIntImmediate(N->getOperand(1), Imm) && N->getOperand(0).getOpcode() == ISD::OR && isIntImmediate(N->getOperand(0).getOperand(1), Imm2)) { - unsigned SH, MB, ME; + unsigned MB, ME; Imm = ~(Imm^Imm2); if (isRunOfOnes(Imm, MB, ME)) { SDOperand Tmp1 = Select(N->getOperand(0).getOperand(0)); SDOperand Tmp2 = Select(N->getOperand(0).getOperand(1)); return CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2, - getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); + getI32Imm(0), getI32Imm(MB), getI32Imm(ME)); } } From evan.cheng at apple.com Thu Jan 5 18:41:24 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 5 Jan 2006 18:41:24 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200601060041.SAA14440@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.124 -> 1.125 --- Log message: Bug fix wrt chain operand. --- Diffs of the changes: (+4 -7) DAGISelEmitter.cpp | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.124 llvm/utils/TableGen/DAGISelEmitter.cpp:1.125 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.124 Tue Jan 3 21:23:30 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Jan 5 18:41:12 2006 @@ -1902,6 +1902,10 @@ << ".getValue(" << CInfo.getNumResults() << "))) goto P" << PatternNo << "Fail; // Already selected for a chain use?\n"; } + if (!FoundChain) { + OS << " SDOperand Chain = " << RootName << ".getOperand(0);\n"; + FoundChain = true; + } } for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { @@ -1975,13 +1979,6 @@ } } - if (HasChain) { - if (!FoundChain) { - OS << " SDOperand Chain = " << RootName << ".getOperand(0);\n"; - FoundChain = true; - } - } - // If there is a node predicate for this, emit the call. if (!N->getPredicateFn().empty()) OS << " if (!" << N->getPredicateFn() << "(" << RootName From evan.cheng at apple.com Thu Jan 5 18:41:55 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 5 Jan 2006 18:41:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200601060041.SAA14452@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.253 -> 1.254 --- Log message: Support for custom lowering of ISD::RET. --- Diffs of the changes: (+16 -0) LegalizeDAG.cpp | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.253 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.254 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.253 Wed Jan 4 19:25:28 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Jan 5 18:41:43 2006 @@ -1302,6 +1302,22 @@ break; } } + + MVT::ValueType VT = Node->getValueType(0); + switch (TLI.getOperationAction(Node->getOpcode(), VT)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Tmp = TLI.LowerOperation(Result, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + // Nothing to do. + break; + } break; case ISD::STORE: { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. From evan.cheng at apple.com Thu Jan 5 18:43:15 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 5 Jan 2006 18:43:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86RegisterInfo.cpp Message-ID: <200601060043.SAA14470@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.21 -> 1.22 X86ISelLowering.h updated: 1.10 -> 1.11 X86InstrInfo.td updated: 1.188 -> 1.189 X86RegisterInfo.cpp updated: 1.115 -> 1.116 --- Log message: * Fast call support. * FP cmp, setcc, etc. --- Diffs of the changes: (+572 -177) X86ISelLowering.cpp | 341 +++++++++++++++++++++++++++++++++++++++++------ X86ISelLowering.h | 28 +++ X86InstrInfo.td | 377 +++++++++++++++++++++++++++++++++------------------- X86RegisterInfo.cpp | 3 4 files changed, 572 insertions(+), 177 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.21 llvm/lib/Target/X86/X86ISelLowering.cpp:1.22 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.21 Wed Jan 4 19:47:43 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Jan 5 18:43:03 2006 @@ -118,13 +118,20 @@ // These should be promoted to a larger select which is supported. setOperationAction(ISD::SELECT , MVT::i1 , Promote); setOperationAction(ISD::SELECT , MVT::i8 , Promote); - // X86 wants to expand cmov itself. if (X86DAGIsel) { + // X86 wants to expand cmov itself. setOperationAction(ISD::SELECT , MVT::i16 , Custom); setOperationAction(ISD::SELECT , MVT::i32 , Custom); + setOperationAction(ISD::SELECT , MVT::f32 , Custom); + setOperationAction(ISD::SELECT , MVT::f64 , Custom); setOperationAction(ISD::SETCC , MVT::i8 , Custom); setOperationAction(ISD::SETCC , MVT::i16 , Custom); setOperationAction(ISD::SETCC , MVT::i32 , Custom); + setOperationAction(ISD::SETCC , MVT::f32 , Custom); + setOperationAction(ISD::SETCC , MVT::f64 , Custom); + // X86 ret instruction may pop stack. + setOperationAction(ISD::RET , MVT::Other, Custom); + // Darwin ABI issue. setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom); } @@ -201,6 +208,12 @@ SelectionDAG &DAG) { assert((!isVarArg || CallingConv == CallingConv::C) && "Only C takes varargs!"); + + // If the callee is a GlobalAddress node (quite common, every direct call is) + // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. + if (GlobalAddressSDNode *G = dyn_cast(Callee)) + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); + if (CallingConv == CallingConv::Fast && EnableFastCC) return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); @@ -223,8 +236,8 @@ DAG.getConstant(1, MVT::i32)); SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, DAG.getConstant(0, MVT::i32)); - Copy = DAG.getCopyToReg(Chain, X86::EAX, Hi, SDOperand()); - Copy = DAG.getCopyToReg(Copy, X86::EDX, Lo, Copy.getValue(1)); + Copy = DAG.getCopyToReg(Chain, X86::EDX, Hi, SDOperand()); + Copy = DAG.getCopyToReg(Copy, X86::EAX, Lo, Copy.getValue(1)); break; } case MVT::f32: @@ -468,8 +481,8 @@ Ops.push_back(Chain); Ops.push_back(Callee); - Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - NodeTys, Ops); + // FIXME: Do not generate X86ISD::TAILCALL for now. + Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops); SDOperand InFlag = Chain.getValue(1); SDOperand RetVal; @@ -951,43 +964,145 @@ break; } - std::vector Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); - // Callee pops all arg values on the stack. - Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); - - // Pass register arguments as needed. - Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end()); - - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - RetVals, Ops); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); + if (X86DAGIsel) { + // Build a sequence of copy-to-reg nodes chained together with token chain + // and flag operands which copy the outgoing args into registers. + SDOperand InFlag; + for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) { + unsigned CCReg; + SDOperand RegToPass = RegValuesToPass[i]; + switch (RegToPass.getValueType()) { + default: assert(0 && "Bad thing to pass in regs"); + case MVT::i8: + CCReg = (i == 0) ? X86::AL : X86::DL; + break; + case MVT::i16: + CCReg = (i == 0) ? X86::AX : X86::DX; + break; + case MVT::i32: + CCReg = (i == 0) ? X86::EAX : X86::EDX; + break; + } - SDOperand ResultVal; - switch (RetTyVT) { - case MVT::isVoid: break; - default: - ResultVal = TheCall.getValue(1); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); - break; - case MVT::f32: - // FIXME: we would really like to remember that this FP_ROUND operation is - // okay to eliminate if we allow excess FP precision. - ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); - break; - case MVT::i64: - ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), - TheCall.getValue(2)); - break; - } + Chain = DAG.getCopyToReg(Chain, CCReg, RegToPass, InFlag); + InFlag = Chain.getValue(1); + } + + std::vector NodeTys; + NodeTys.push_back(MVT::Other); // Returns a chain + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + if (InFlag.Val) + Ops.push_back(InFlag); + + // FIXME: Do not generate X86ISD::TAILCALL for now. + Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops); + InFlag = Chain.getValue(1); + + SDOperand RetVal; + if (RetTyVT != MVT::isVoid) { + switch (RetTyVT) { + default: assert(0 && "Unknown value type to return!"); + case MVT::i1: + case MVT::i8: + RetVal = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i16: + RetVal = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i32: + RetVal = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i64: { + SDOperand Lo = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); + SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, MVT::i32, + Lo.getValue(2)); + RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); + Chain = Hi.getValue(1); + break; + } + case MVT::f32: + case MVT::f64: { + std::vector Tys; + Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(InFlag); + RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops); + Chain = RetVal.getValue(1); + if (X86ScalarSSE) { + unsigned Size = MVT::getSizeInBits(MVT::f64)/8; + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + Tys.clear(); + Tys.push_back(MVT::Other); + Ops.clear(); + Ops.push_back(Chain); + Ops.push_back(RetVal); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(RetTyVT)); + Chain = DAG.getNode(X86ISD::FST, Tys, Ops); + RetVal = DAG.getLoad(RetTyVT, Chain, StackSlot, + DAG.getSrcValue(NULL)); + Chain = RetVal.getValue(1); + } else if (RetTyVT == MVT::f32) + RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal); + break; + } + } + } + + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, + DAG.getConstant(ArgOffset, getPointerTy()), + DAG.getConstant(ArgOffset, getPointerTy())); + return std::make_pair(RetVal, Chain); + } else { + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); + // Callee pops all arg values on the stack. + Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); + + // Pass register arguments as needed. + Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end()); - return std::make_pair(ResultVal, Chain); + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + RetVals, Ops); + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); + + SDOperand ResultVal; + switch (RetTyVT) { + case MVT::isVoid: break; + default: + ResultVal = TheCall.getValue(1); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); + break; + case MVT::f32: + // FIXME: we would really like to remember that this FP_ROUND operation is + // okay to eliminate if we allow excess FP precision. + ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); + break; + case MVT::i64: + ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), + TheCall.getValue(2)); + break; + } + + return std::make_pair(ResultVal, Chain); + } } SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { @@ -1025,6 +1140,54 @@ // X86 Custom Lowering Hooks //===----------------------------------------------------------------------===// +/// SetCCToX86CondCode - do a one to one translation of a ISD::CondCode to +/// X86 specific CondCode. It returns a X86ISD::COND_INVALID if it cannot +/// do a direct translation. +static unsigned CCToX86CondCode(SDOperand CC, bool isFP) { + ISD::CondCode SetCCOpcode = cast(CC)->get(); + unsigned X86CC = X86ISD::COND_INVALID; + if (!isFP) { + switch (SetCCOpcode) { + default: break; + case ISD::SETEQ: X86CC = X86ISD::COND_E; break; + case ISD::SETGT: X86CC = X86ISD::COND_G; break; + case ISD::SETGE: X86CC = X86ISD::COND_GE; break; + case ISD::SETLT: X86CC = X86ISD::COND_L; break; + case ISD::SETLE: X86CC = X86ISD::COND_LE; break; + case ISD::SETNE: X86CC = X86ISD::COND_NE; break; + case ISD::SETULT: X86CC = X86ISD::COND_B; break; + case ISD::SETUGT: X86CC = X86ISD::COND_A; break; + case ISD::SETULE: X86CC = X86ISD::COND_BE; break; + case ISD::SETUGE: X86CC = X86ISD::COND_AE; break; + } + } else { + // On a floating point condition, the flags are set as follows: + // ZF PF CF op + // 0 | 0 | 0 | X > Y + // 0 | 0 | 1 | X < Y + // 1 | 0 | 0 | X == Y + // 1 | 1 | 1 | unordered + switch (SetCCOpcode) { + default: break; + case ISD::SETUEQ: + case ISD::SETEQ: X86CC = X86ISD::COND_E; break; + case ISD::SETOGT: + case ISD::SETGT: X86CC = X86ISD::COND_A; break; + case ISD::SETOGE: + case ISD::SETGE: X86CC = X86ISD::COND_AE; break; + case ISD::SETULT: + case ISD::SETLT: X86CC = X86ISD::COND_B; break; + case ISD::SETULE: + case ISD::SETLE: X86CC = X86ISD::COND_BE; break; + case ISD::SETONE: + case ISD::SETNE: X86CC = X86ISD::COND_NE; break; + case ISD::SETUO: X86CC = X86ISD::COND_P; break; + case ISD::SETO: X86CC = X86ISD::COND_NP; break; + } + } + return X86CC; +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -1100,7 +1263,87 @@ SDOperand CC = Op.getOperand(2); SDOperand Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Op.getOperand(0), Op.getOperand(1)); - return DAG.getNode(X86ISD::SETCC, MVT::i8, CC, Cond); + ISD::CondCode SetCCOpcode = cast(CC)->get(); + bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType()); + unsigned X86CC = CCToX86CondCode(CC, isFP); + if (X86CC != X86ISD::COND_INVALID) { + return DAG.getNode(X86ISD::SETCC, MVT::i8, + DAG.getConstant(X86CC, MVT::i8), Cond); + } else { + assert(isFP && "Illegal integer SetCC!"); + + std::vector Tys; + std::vector Ops; + switch (SetCCOpcode) { + default: assert(false && "Illegal floating point SetCC!"); + case ISD::SETOEQ: { // !PF & ZF + Tys.push_back(MVT::i8); + Tys.push_back(MVT::Flag); + Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8)); + Ops.push_back(Cond); + SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); + SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, + DAG.getConstant(X86ISD::COND_E, MVT::i8), + Tmp1.getValue(1)); + return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2); + } + case ISD::SETOLT: { // !PF & CF + Tys.push_back(MVT::i8); + Tys.push_back(MVT::Flag); + Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8)); + Ops.push_back(Cond); + SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); + SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, + DAG.getConstant(X86ISD::COND_B, MVT::i8), + Tmp1.getValue(1)); + return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2); + } + case ISD::SETOLE: { // !PF & (CF || ZF) + Tys.push_back(MVT::i8); + Tys.push_back(MVT::Flag); + Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8)); + Ops.push_back(Cond); + SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); + SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, + DAG.getConstant(X86ISD::COND_BE, MVT::i8), + Tmp1.getValue(1)); + return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2); + } + case ISD::SETUGT: { // PF | (!ZF & !CF) + Tys.push_back(MVT::i8); + Tys.push_back(MVT::Flag); + Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8)); + Ops.push_back(Cond); + SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); + SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, + DAG.getConstant(X86ISD::COND_A, MVT::i8), + Tmp1.getValue(1)); + return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2); + } + case ISD::SETUGE: { // PF | !CF + Tys.push_back(MVT::i8); + Tys.push_back(MVT::Flag); + Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8)); + Ops.push_back(Cond); + SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); + SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, + DAG.getConstant(X86ISD::COND_AE, MVT::i8), + Tmp1.getValue(1)); + return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2); + } + case ISD::SETUNE: { // PF | !ZF + Tys.push_back(MVT::i8); + Tys.push_back(MVT::Flag); + Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8)); + Ops.push_back(Cond); + SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); + SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, + DAG.getConstant(X86ISD::COND_NE, MVT::i8), + Tmp1.getValue(1)); + return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2); + } + } + } } case ISD::SELECT: { SDOperand Cond = Op.getOperand(0); @@ -1110,10 +1353,13 @@ Cond = Cond.getOperand(1); } else if (Cond.getOpcode() == ISD::SETCC) { CC = Cond.getOperand(2); + bool isFP = MVT::isFloatingPoint(Cond.getOperand(1).getValueType()); + unsigned X86CC = CCToX86CondCode(CC, isFP); + CC = DAG.getConstant(X86CC, MVT::i8); Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Cond.getOperand(0), Cond.getOperand(1)); } else { - CC = DAG.getCondCode(ISD::SETEQ); + CC = DAG.getConstant(X86ISD::COND_E, MVT::i8); Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond); } return DAG.getNode(X86ISD::CMOV, Op.getValueType(), @@ -1129,15 +1375,23 @@ Cond = Cond.getOperand(1); } else if (Cond.getOpcode() == ISD::SETCC) { CC = Cond.getOperand(2); + bool isFP = MVT::isFloatingPoint(Cond.getOperand(1).getValueType()); + unsigned X86CC = CCToX86CondCode(CC, isFP); + CC = DAG.getConstant(X86CC, MVT::i8); Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Cond.getOperand(0), Cond.getOperand(1)); } else { - CC = DAG.getCondCode(ISD::SETNE); + CC = DAG.getConstant(X86ISD::COND_NE, MVT::i8); Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond); } return DAG.getNode(X86ISD::BRCOND, Op.getValueType(), Op.getOperand(0), Op.getOperand(2), CC, Cond); } + case ISD::RET: { + // Can only be return void. + return DAG.getNode(X86ISD::RET, MVT::Other, Op.getOperand(0), + DAG.getConstant(getBytesToPopOnReturn(), MVT::i16)); + } case ISD::GlobalAddress: { GlobalValue *GV = cast(Op)->getGlobal(); SDOperand GVOp = DAG.getTargetGlobalAddress(GV, getPointerTy()); @@ -1176,6 +1430,7 @@ case X86ISD::SETCC: return "X86ISD::SETCC"; case X86ISD::CMOV: return "X86ISD::CMOV"; case X86ISD::BRCOND: return "X86ISD::BRCOND"; + case X86ISD::RET: return "X86ISD::RET"; case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG"; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.10 llvm/lib/Target/X86/X86ISelLowering.h:1.11 --- llvm/lib/Target/X86/X86ISelLowering.h:1.10 Wed Jan 4 18:27:02 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Thu Jan 5 18:43:03 2006 @@ -19,8 +19,8 @@ #include "llvm/CodeGen/SelectionDAG.h" namespace llvm { - // X86 Specific DAG Nodes namespace X86ISD { + // X86 Specific DAG Nodes enum NodeType { // Start the numbering where the builtin ops leave off. FIRST_NUMBER = ISD::BUILTIN_OP_END+X86::INSTRUCTION_LIST_END, @@ -108,10 +108,36 @@ /// or TEST instruction. BRCOND, + /// Return without a flag operand. Operand 1 is the number of bytes of + /// stack to pop, and operand 2 is the chain. + RET, + /// Return with a flag operand. Operand 1 is the number of bytes of stack /// to pop, operand 2 is the chain and operand 3 is a flag operand. RET_FLAG, }; + + // X86 specific condition code. These correspond to X86_*_COND in + // X86InstrInfo.td. They must be kept in synch. + enum CondCode { + COND_A = 0, + COND_AE = 1, + COND_B = 2, + COND_BE = 3, + COND_E = 4, + COND_G = 5, + COND_GE = 6, + COND_L = 7, + COND_LE = 8, + COND_NE = 9, + COND_NO = 10, + COND_NP = 11, + COND_NS = 12, + COND_O = 13, + COND_P = 14, + COND_S = 15, + COND_INVALID + }; } //===----------------------------------------------------------------------===// Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.188 llvm/lib/Target/X86/X86InstrInfo.td:1.189 --- llvm/lib/Target/X86/X86InstrInfo.td:1.188 Wed Jan 4 20:08:37 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Thu Jan 5 18:43:03 2006 @@ -17,22 +17,21 @@ // X86 specific DAG Nodes. // -def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisInt<1>, - SDTCisSameAs<1, 2>]>; +def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisSameAs<1, 2>]>; def SDTX86Cmov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, - SDTCisVT<3, OtherVT>, SDTCisVT<4, FlagVT>]>; + SDTCisVT<3, i8>, SDTCisVT<4, FlagVT>]>; def SDTX86BrCond : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, - SDTCisVT<1, OtherVT>, SDTCisVT<2, FlagVT>]>; + SDTCisVT<1, i8>, SDTCisVT<2, FlagVT>]>; def SDTX86SetCC : SDTypeProfile<1, 2, - [SDTCisVT<0, i8>, SDTCisVT<1, OtherVT>, + [SDTCisVT<0, i8>, SDTCisVT<1, i8>, SDTCisVT<2, FlagVT>]>; -def SDTX86RetFlag : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>; +def SDTX86Ret : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>; def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>; @@ -47,10 +46,11 @@ def X86test : SDNode<"X86ISD::TEST", SDTX86CmpTest, []>; def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov, []>; -def X86Brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, [SDNPHasChain]>; -def X86SetCC : SDNode<"X86ISD::SETCC", SDTX86SetCC, []>; +def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, [SDNPHasChain]>; +def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC, []>; -def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>; +def X86ret : SDNode<"X86ISD::RET", SDTX86Ret, [SDNPHasChain]>; +def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret, [SDNPHasChain]>; def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, [SDNPHasChain]>; def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, [SDNPHasChain]>; @@ -226,6 +226,26 @@ //===----------------------------------------------------------------------===// // Pattern fragments... // + +// X86 specific condition code. These correspond to CondCode in +// X86ISelLowering.h. They must be kept in synch. +def X86_COND_A : PatLeaf<(i8 0)>; +def X86_COND_AE : PatLeaf<(i8 1)>; +def X86_COND_B : PatLeaf<(i8 2)>; +def X86_COND_BE : PatLeaf<(i8 3)>; +def X86_COND_E : PatLeaf<(i8 4)>; +def X86_COND_G : PatLeaf<(i8 5)>; +def X86_COND_GE : PatLeaf<(i8 6)>; +def X86_COND_L : PatLeaf<(i8 7)>; +def X86_COND_LE : PatLeaf<(i8 8)>; +def X86_COND_NE : PatLeaf<(i8 9)>; +def X86_COND_NO : PatLeaf<(i8 10)>; +def X86_COND_NP : PatLeaf<(i8 11)>; +def X86_COND_NS : PatLeaf<(i8 12)>; +def X86_COND_O : PatLeaf<(i8 13)>; +def X86_COND_P : PatLeaf<(i8 14)>; +def X86_COND_S : PatLeaf<(i8 15)>; + def i16immSExt8 : PatLeaf<(i16 imm), [{ // i16immSExt8 predicate - True if the 16-bit immediate fits in a 8-bit // sign extended field. @@ -332,12 +352,13 @@ let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1, noResults = 1 in { // FIXME: temporary workaround for return without an incoming flag. - def RETVOID : I<0xC3, RawFrm, (ops), "ret", [(ret)]>; + def RETVOID : I<0xC3, RawFrm, (ops), "ret", [(X86ret 0)]>; + def RETIVOID : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", + [(X86ret imm:$amt)]>; let hasInFlag = 1 in { - def RET : I<0xC3, RawFrm, (ops), "ret", - [(X86retflag 0)]>; - def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", - [(X86retflag imm:$amt)]>; + def RET : I<0xC3, RawFrm, (ops), "ret", [(X86retflag 0)]>; + def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", + [(X86retflag imm:$amt)]>; } } @@ -350,31 +371,35 @@ def JMP : IBr<0xE9, (ops brtarget:$dst), "jmp $dst", [(br bb:$dst)]>; def JE : IBr<0x84, (ops brtarget:$dst), "je $dst", - [(X86Brcond bb:$dst, SETEQ, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_E, STATUS)]>, Imp<[STATUS],[]>, TB; def JNE : IBr<0x85, (ops brtarget:$dst), "jne $dst", - [(X86Brcond bb:$dst, SETNE, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_NE, STATUS)]>, Imp<[STATUS],[]>, TB; def JL : IBr<0x8C, (ops brtarget:$dst), "jl $dst", - [(X86Brcond bb:$dst, SETLT, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_L, STATUS)]>, Imp<[STATUS],[]>, TB; def JLE : IBr<0x8E, (ops brtarget:$dst), "jle $dst", - [(X86Brcond bb:$dst, SETLE, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_LE, STATUS)]>, Imp<[STATUS],[]>, TB; def JG : IBr<0x8F, (ops brtarget:$dst), "jg $dst", - [(X86Brcond bb:$dst, SETGT, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_G, STATUS)]>, Imp<[STATUS],[]>, TB; def JGE : IBr<0x8D, (ops brtarget:$dst), "jge $dst", - [(X86Brcond bb:$dst, SETGE, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_GE, STATUS)]>, Imp<[STATUS],[]>, TB; def JB : IBr<0x82, (ops brtarget:$dst), "jb $dst", - [(X86Brcond bb:$dst, SETULT, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_B, STATUS)]>, Imp<[STATUS],[]>, TB; def JBE : IBr<0x86, (ops brtarget:$dst), "jbe $dst", - [(X86Brcond bb:$dst, SETULE, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_BE, STATUS)]>, Imp<[STATUS],[]>, TB; def JA : IBr<0x87, (ops brtarget:$dst), "ja $dst", - [(X86Brcond bb:$dst, SETUGT, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_A, STATUS)]>, Imp<[STATUS],[]>, TB; def JAE : IBr<0x83, (ops brtarget:$dst), "jae $dst", - [(X86Brcond bb:$dst, SETUGE, STATUS)]>, Imp<[STATUS],[]>, TB; + [(X86brcond bb:$dst, X86_COND_AE, STATUS)]>, Imp<[STATUS],[]>, TB; -def JS : IBr<0x88, (ops brtarget:$dst), "js $dst", []>, TB; -def JNS : IBr<0x89, (ops brtarget:$dst), "jns $dst", []>, TB; -def JP : IBr<0x8A, (ops brtarget:$dst), "jp $dst", []>, TB; -def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst", []>, TB; +def JS : IBr<0x88, (ops brtarget:$dst), "js $dst", + [(X86brcond bb:$dst, X86_COND_S, STATUS)]>, Imp<[STATUS],[]>, TB; +def JNS : IBr<0x89, (ops brtarget:$dst), "jns $dst", + [(X86brcond bb:$dst, X86_COND_NS, STATUS)]>, Imp<[STATUS],[]>, TB; +def JP : IBr<0x8A, (ops brtarget:$dst), "jp $dst", + [(X86brcond bb:$dst, X86_COND_P, STATUS)]>, Imp<[STATUS],[]>, TB; +def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst", + [(X86brcond bb:$dst, X86_COND_NP, STATUS)]>, Imp<[STATUS],[]>, TB; //===----------------------------------------------------------------------===// // Call Instructions... @@ -388,9 +413,9 @@ def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst", []>; def CALL32r : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst", - []>; + [(call R32:$dst)]>; def CALL32m : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst", - []>; + [(call (loadi32 addr:$dst))]>; } def : Pat<(call tglobaladdr:$dst), @@ -658,303 +683,351 @@ (ops R16:$dst, R16:$src1, R16:$src2), "cmovb {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETULT, STATUS))]>, + X86_COND_B, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVB16rm : I<0x42, MRMSrcMem, // if , + X86_COND_B, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVB32rr : I<0x42, MRMSrcReg, // if , + X86_COND_B, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVB32rm : I<0x42, MRMSrcMem, // if , + X86_COND_B, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVAE16rr: I<0x43, MRMSrcReg, // if >=u, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), "cmovae {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETUGE, STATUS))]>, + X86_COND_AE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVAE16rm: I<0x43, MRMSrcMem, // if >=u, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), "cmovae {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), - SETUGE, STATUS))]>, + X86_COND_AE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVAE32rr: I<0x43, MRMSrcReg, // if >=u, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), "cmovae {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, - SETUGE, STATUS))]>, + X86_COND_AE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVAE32rm: I<0x43, MRMSrcMem, // if >=u, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), "cmovae {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), - SETUGE, STATUS))]>, + X86_COND_AE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVE16rr : I<0x44, MRMSrcReg, // if ==, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), "cmove {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETEQ, STATUS))]>, + X86_COND_E, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVE16rm : I<0x44, MRMSrcMem, // if ==, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), "cmove {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), - SETEQ, STATUS))]>, + X86_COND_E, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVE32rr : I<0x44, MRMSrcReg, // if ==, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), "cmove {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, - SETEQ, STATUS))]>, + X86_COND_E, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVE32rm : I<0x44, MRMSrcMem, // if ==, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), "cmove {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), - SETEQ, STATUS))]>, + X86_COND_E, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVNE16rr: I<0x45, MRMSrcReg, // if !=, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), "cmovne {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETNE, STATUS))]>, + X86_COND_NE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVNE16rm: I<0x45, MRMSrcMem, // if !=, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), "cmovne {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), - SETNE, STATUS))]>, + X86_COND_NE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVNE32rr: I<0x45, MRMSrcReg, // if !=, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), "cmovne {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, - SETNE, STATUS))]>, + X86_COND_NE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVNE32rm: I<0x45, MRMSrcMem, // if !=, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), "cmovne {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), - SETNE, STATUS))]>, + X86_COND_NE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVBE16rr: I<0x46, MRMSrcReg, // if <=u, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), "cmovbe {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETULE, STATUS))]>, + X86_COND_BE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVBE16rm: I<0x46, MRMSrcMem, // if <=u, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), "cmovbe {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), - SETULE, STATUS))]>, + X86_COND_BE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVBE32rr: I<0x46, MRMSrcReg, // if <=u, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), "cmovbe {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, - SETULE, STATUS))]>, + X86_COND_BE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVBE32rm: I<0x46, MRMSrcMem, // if <=u, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), "cmovbe {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), - SETULE, STATUS))]>, + X86_COND_BE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVA16rr : I<0x47, MRMSrcReg, // if >u, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), "cmova {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETUGT, STATUS))]>, + X86_COND_A, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVA16rm : I<0x47, MRMSrcMem, // if >u, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), "cmova {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), - SETUGT, STATUS))]>, + X86_COND_A, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVA32rr : I<0x47, MRMSrcReg, // if >u, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), "cmova {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, - SETUGT, STATUS))]>, + X86_COND_A, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVA32rm : I<0x47, MRMSrcMem, // if >u, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), "cmova {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), - SETUGT, STATUS))]>, + X86_COND_A, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVL16rr : I<0x4C, MRMSrcReg, // if , + X86_COND_L, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVL16rm : I<0x4C, MRMSrcMem, // if , + X86_COND_L, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVL32rr : I<0x4C, MRMSrcReg, // if , + X86_COND_L, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVL32rm : I<0x4C, MRMSrcMem, // if , + X86_COND_L, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVGE16rr: I<0x4D, MRMSrcReg, // if >=s, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), "cmovge {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETGE, STATUS))]>, + X86_COND_GE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVGE16rm: I<0x4D, MRMSrcMem, // if >=s, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), "cmovge {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), - SETGE, STATUS))]>, + X86_COND_GE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVGE32rr: I<0x4D, MRMSrcReg, // if >=s, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), "cmovge {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, - SETGE, STATUS))]>, + X86_COND_GE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVGE32rm: I<0x4D, MRMSrcMem, // if >=s, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), "cmovge {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), - SETGE, STATUS))]>, + X86_COND_GE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVLE16rr: I<0x4E, MRMSrcReg, // if <=s, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), "cmovle {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETLE, STATUS))]>, + X86_COND_LE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVLE16rm: I<0x4E, MRMSrcMem, // if <=s, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), "cmovle {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), - SETLE, STATUS))]>, + X86_COND_LE, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVLE32rr: I<0x4E, MRMSrcReg, // if <=s, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), "cmovle {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, - SETLE, STATUS))]>, + X86_COND_LE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVLE32rm: I<0x4E, MRMSrcMem, // if <=s, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), "cmovle {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), - SETLE, STATUS))]>, + X86_COND_LE, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVG16rr : I<0x4F, MRMSrcReg, // if >s, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), "cmovg {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, - SETGT, STATUS))]>, + X86_COND_G, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVG16rm : I<0x4F, MRMSrcMem, // if >s, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), "cmovg {$src2, $dst|$dst, $src2}", [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), - SETGT, STATUS))]>, + X86_COND_G, STATUS))]>, Imp<[STATUS],[]>, TB, OpSize; def CMOVG32rr : I<0x4F, MRMSrcReg, // if >s, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), "cmovg {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, - SETGT, STATUS))]>, + X86_COND_G, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVG32rm : I<0x4F, MRMSrcMem, // if >s, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), "cmovg {$src2, $dst|$dst, $src2}", [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), - SETGT, STATUS))]>, + X86_COND_G, STATUS))]>, Imp<[STATUS],[]>, TB; def CMOVS16rr : I<0x48, MRMSrcReg, // if signed, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), - "cmovs {$src2, $dst|$dst, $src2}", []>, TB, OpSize; + "cmovs {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, + X86_COND_S, STATUS))]>, + Imp<[STATUS],[]>, TB, OpSize; def CMOVS16rm : I<0x48, MRMSrcMem, // if signed, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), - "cmovs {$src2, $dst|$dst, $src2}", []>, TB, OpSize; + "cmovs {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), + X86_COND_S, STATUS))]>, + Imp<[STATUS],[]>, TB, OpSize; def CMOVS32rr : I<0x48, MRMSrcReg, // if signed, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), - "cmovs {$src2, $dst|$dst, $src2}", []>, TB; + "cmovs {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, + X86_COND_S, STATUS))]>, + Imp<[STATUS],[]>, TB; def CMOVS32rm : I<0x48, MRMSrcMem, // if signed, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), - "cmovs {$src2, $dst|$dst, $src2}", []>, TB; + "cmovs {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), + X86_COND_S, STATUS))]>, + Imp<[STATUS],[]>, TB; def CMOVNS16rr: I<0x49, MRMSrcReg, // if !signed, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), - "cmovns {$src2, $dst|$dst, $src2}", []>, TB, OpSize; + "cmovns {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, + X86_COND_NS, STATUS))]>, + Imp<[STATUS],[]>, TB, OpSize; def CMOVNS16rm: I<0x49, MRMSrcMem, // if !signed, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), - "cmovns {$src2, $dst|$dst, $src2}", []>, TB, OpSize; + "cmovns {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), + X86_COND_NS, STATUS))]>, + Imp<[STATUS],[]>, TB, OpSize; def CMOVNS32rr: I<0x49, MRMSrcReg, // if !signed, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), - "cmovns {$src2, $dst|$dst, $src2}", []>, TB; + "cmovns {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, + X86_COND_NS, STATUS))]>, + Imp<[STATUS],[]>, TB; def CMOVNS32rm: I<0x49, MRMSrcMem, // if !signed, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), - "cmovns {$src2, $dst|$dst, $src2}", []>, TB; + "cmovns {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), + X86_COND_NS, STATUS))]>, + Imp<[STATUS],[]>, TB; def CMOVP16rr : I<0x4A, MRMSrcReg, // if parity, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), - "cmovp {$src2, $dst|$dst, $src2}", []>, TB, OpSize; + "cmovp {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, + X86_COND_P, STATUS))]>, + Imp<[STATUS],[]>, TB, OpSize; def CMOVP16rm : I<0x4A, MRMSrcMem, // if parity, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), - "cmovp {$src2, $dst|$dst, $src2}", []>, TB, OpSize; + "cmovp {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), + X86_COND_P, STATUS))]>, + Imp<[STATUS],[]>, TB, OpSize; def CMOVP32rr : I<0x4A, MRMSrcReg, // if parity, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), - "cmovp {$src2, $dst|$dst, $src2}", []>, TB; + "cmovp {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, + X86_COND_P, STATUS))]>, + Imp<[STATUS],[]>, TB; def CMOVP32rm : I<0x4A, MRMSrcMem, // if parity, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), - "cmovp {$src2, $dst|$dst, $src2}", []>, TB; + "cmovp {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), + X86_COND_P, STATUS))]>, + Imp<[STATUS],[]>, TB; def CMOVNP16rr : I<0x4B, MRMSrcReg, // if !parity, R16 = R16 (ops R16:$dst, R16:$src1, R16:$src2), - "cmovnp {$src2, $dst|$dst, $src2}", []>, TB, OpSize; + "cmovnp {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (X86cmov R16:$src1, R16:$src2, + X86_COND_NP, STATUS))]>, + Imp<[STATUS],[]>, TB, OpSize; def CMOVNP16rm : I<0x4B, MRMSrcMem, // if !parity, R16 = [mem16] (ops R16:$dst, R16:$src1, i16mem:$src2), - "cmovnp {$src2, $dst|$dst, $src2}", []>, TB, OpSize; + "cmovnp {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (X86cmov R16:$src1, (loadi16 addr:$src2), + X86_COND_NP, STATUS))]>, + Imp<[STATUS],[]>, TB, OpSize; def CMOVNP32rr : I<0x4B, MRMSrcReg, // if !parity, R32 = R32 (ops R32:$dst, R32:$src1, R32:$src2), - "cmovnp {$src2, $dst|$dst, $src2}", []>, TB; + "cmovnp {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (X86cmov R32:$src1, R32:$src2, + X86_COND_NP, STATUS))]>, + Imp<[STATUS],[]>, TB; def CMOVNP32rm : I<0x4B, MRMSrcMem, // if !parity, R32 = [mem32] (ops R32:$dst, R32:$src1, i32mem:$src2), - "cmovnp {$src2, $dst|$dst, $src2}", []>, TB; + "cmovnp {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (X86cmov R32:$src1, (loadi32 addr:$src2), + X86_COND_NP, STATUS))]>, + Imp<[STATUS],[]>, TB; // unary instructions @@ -1863,109 +1936,146 @@ def SETEr : I<0x94, MRM0r, (ops R8 :$dst), - "sete $dst", [(set R8:$dst, (X86SetCC SETEQ, STATUS))]>, + "sete $dst", + [(set R8:$dst, (X86setcc X86_COND_E, STATUS))]>, TB; // R8 = == def SETEm : I<0x94, MRM0m, (ops i8mem:$dst), - "sete $dst", [(store (X86SetCC SETEQ, STATUS), addr:$dst)]>, + "sete $dst", + [(store (X86setcc X86_COND_E, STATUS), addr:$dst)]>, TB; // [mem8] = == def SETNEr : I<0x95, MRM0r, (ops R8 :$dst), - "setne $dst", [(set R8:$dst, (X86SetCC SETNE, STATUS))]>, + "setne $dst", + [(set R8:$dst, (X86setcc X86_COND_NE, STATUS))]>, TB; // R8 = != def SETNEm : I<0x95, MRM0m, (ops i8mem:$dst), - "setne $dst", [(store (X86SetCC SETNE, STATUS), addr:$dst)]>, + "setne $dst", + [(store (X86setcc X86_COND_NE, STATUS), addr:$dst)]>, TB; // [mem8] = != def SETLr : I<0x9C, MRM0r, (ops R8 :$dst), - "setl $dst", [(set R8:$dst, (X86SetCC SETLT, STATUS))]>, + "setl $dst", + [(set R8:$dst, (X86setcc X86_COND_L, STATUS))]>, TB; // R8 = < signed def SETLm : I<0x9C, MRM0m, (ops i8mem:$dst), - "setl $dst", [(store (X86SetCC SETLT, STATUS), addr:$dst)]>, + "setl $dst", + [(store (X86setcc X86_COND_L, STATUS), addr:$dst)]>, TB; // [mem8] = < signed def SETGEr : I<0x9D, MRM0r, (ops R8 :$dst), - "setge $dst", [(set R8:$dst, (X86SetCC SETGE, STATUS))]>, + "setge $dst", + [(set R8:$dst, (X86setcc X86_COND_GE, STATUS))]>, TB; // R8 = >= signed def SETGEm : I<0x9D, MRM0m, (ops i8mem:$dst), - "setge $dst", [(store (X86SetCC SETGE, STATUS), addr:$dst)]>, + "setge $dst", + [(store (X86setcc X86_COND_GE, STATUS), addr:$dst)]>, TB; // [mem8] = >= signed def SETLEr : I<0x9E, MRM0r, (ops R8 :$dst), - "setle $dst", [(set R8:$dst, (X86SetCC SETLE, STATUS))]>, + "setle $dst", + [(set R8:$dst, (X86setcc X86_COND_LE, STATUS))]>, TB; // R8 = <= signed def SETLEm : I<0x9E, MRM0m, (ops i8mem:$dst), - "setle $dst", [(store (X86SetCC SETLE, STATUS), addr:$dst)]>, + "setle $dst", + [(store (X86setcc X86_COND_LE, STATUS), addr:$dst)]>, TB; // [mem8] = <= signed def SETGr : I<0x9F, MRM0r, (ops R8 :$dst), - "setg $dst", [(set R8:$dst, (X86SetCC SETGT, STATUS))]>, + "setg $dst", + [(set R8:$dst, (X86setcc X86_COND_G, STATUS))]>, TB; // R8 = > signed def SETGm : I<0x9F, MRM0m, (ops i8mem:$dst), - "setg $dst", [(store (X86SetCC SETGT, STATUS), addr:$dst)]>, + "setg $dst", + [(store (X86setcc X86_COND_G, STATUS), addr:$dst)]>, TB; // [mem8] = > signed def SETBr : I<0x92, MRM0r, (ops R8 :$dst), - "setb $dst", [(set R8:$dst, (X86SetCC SETULT, STATUS))]>, + "setb $dst", + [(set R8:$dst, (X86setcc X86_COND_B, STATUS))]>, TB; // R8 = < unsign def SETBm : I<0x92, MRM0m, (ops i8mem:$dst), - "setb $dst", [(store (X86SetCC SETULT, STATUS), addr:$dst)]>, + "setb $dst", + [(store (X86setcc X86_COND_B, STATUS), addr:$dst)]>, TB; // [mem8] = < unsign def SETAEr : I<0x93, MRM0r, (ops R8 :$dst), - "setae $dst", [(set R8:$dst, (X86SetCC SETUGE, STATUS))]>, + "setae $dst", + [(set R8:$dst, (X86setcc X86_COND_AE, STATUS))]>, TB; // R8 = >= unsign def SETAEm : I<0x93, MRM0m, (ops i8mem:$dst), - "setae $dst", [(store (X86SetCC SETUGE, STATUS), addr:$dst)]>, + "setae $dst", + [(store (X86setcc X86_COND_AE, STATUS), addr:$dst)]>, TB; // [mem8] = >= unsign def SETBEr : I<0x96, MRM0r, (ops R8 :$dst), - "setbe $dst", [(set R8:$dst, (X86SetCC SETULE, STATUS))]>, + "setbe $dst", + [(set R8:$dst, (X86setcc X86_COND_BE, STATUS))]>, TB; // R8 = <= unsign def SETBEm : I<0x96, MRM0m, (ops i8mem:$dst), - "setbe $dst", [(store (X86SetCC SETULE, STATUS), addr:$dst)]>, + "setbe $dst", + [(store (X86setcc X86_COND_BE, STATUS), addr:$dst)]>, TB; // [mem8] = <= unsign def SETAr : I<0x97, MRM0r, (ops R8 :$dst), - "seta $dst", [(set R8:$dst, (X86SetCC SETUGT, STATUS))]>, + "seta $dst", + [(set R8:$dst, (X86setcc X86_COND_A, STATUS))]>, TB; // R8 = > signed def SETAm : I<0x97, MRM0m, (ops i8mem:$dst), - "seta $dst", [(store (X86SetCC SETUGT, STATUS), addr:$dst)]>, + "seta $dst", + [(store (X86setcc X86_COND_A, STATUS), addr:$dst)]>, TB; // [mem8] = > signed + def SETSr : I<0x98, MRM0r, (ops R8 :$dst), - "sets $dst", []>, TB; // R8 = + "sets $dst", + [(set R8:$dst, (X86setcc X86_COND_S, STATUS))]>, + TB; // R8 = def SETSm : I<0x98, MRM0m, (ops i8mem:$dst), - "sets $dst", []>, TB; // [mem8] = + "sets $dst", + [(store (X86setcc X86_COND_S, STATUS), addr:$dst)]>, + TB; // [mem8] = def SETNSr : I<0x99, MRM0r, (ops R8 :$dst), - "setns $dst", []>, TB; // R8 = ! + "setns $dst", + [(set R8:$dst, (X86setcc X86_COND_NS, STATUS))]>, + TB; // R8 = ! def SETNSm : I<0x99, MRM0m, (ops i8mem:$dst), - "setns $dst", []>, TB; // [mem8] = ! + "setns $dst", + [(store (X86setcc X86_COND_NS, STATUS), addr:$dst)]>, + TB; // [mem8] = ! def SETPr : I<0x9A, MRM0r, (ops R8 :$dst), - "setp $dst", []>, TB; // R8 = parity + "setp $dst", + [(set R8:$dst, (X86setcc X86_COND_P, STATUS))]>, + TB; // R8 = parity def SETPm : I<0x9A, MRM0m, (ops i8mem:$dst), - "setp $dst", []>, TB; // [mem8] = parity + "setp $dst", + [(store (X86setcc X86_COND_P, STATUS), addr:$dst)]>, + TB; // [mem8] = parity def SETNPr : I<0x9B, MRM0r, (ops R8 :$dst), - "setnp $dst", []>, TB; // R8 = not parity + "setnp $dst", + [(set R8:$dst, (X86setcc X86_COND_NP, STATUS))]>, + TB; // R8 = not parity def SETNPm : I<0x9B, MRM0m, (ops i8mem:$dst), - "setnp $dst", []>, TB; // [mem8] = not parity + "setnp $dst", + [(store (X86setcc X86_COND_NP, STATUS), addr:$dst)]>, + TB; // [mem8] = not parity // Integer comparisons def CMP8rr : I<0x38, MRMDestReg, @@ -2191,28 +2301,30 @@ [(set FR64:$dst, (fsqrt FR64:$src))]>, Requires<[HasSSE2]>, XD; -def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$dst, FR64:$src), - "ucomisd {$src, $dst|$dst, $src}", []>, +def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), + "ucomisd {$src2, $src1|$src1, $src2}", + [(set STATUS, (X86cmp FR64:$src1, FR64:$src2))]>, Requires<[HasSSE2]>, TB, OpSize; -def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$dst, f64mem:$src), - "ucomisd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, TB, OpSize; -def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$dst, FR32:$src), - "ucomiss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; -def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$dst, f32mem:$src), - "ucomiss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, TB; +def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), + "ucomisd {$src2, $src1|$src1, $src2}", + [(set STATUS, (X86cmp FR64:$src1, (loadf64 addr:$src2)))]>, + Imp<[],[STATUS]>, Requires<[HasSSE2]>, TB, OpSize; +def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2), + "ucomiss {$src2, $src1|$src1, $src2}", + [(set STATUS, (X86cmp FR32:$src1, FR32:$src2))]>, + Imp<[],[STATUS]>, Requires<[HasSSE1]>, TB; +def UCOMISSrm: I<0x2E, MRMSrcMem, (ops FR32:$src1, f32mem:$src2), + "ucomiss {$src2, $src1|$src1, $src2}", + [(set STATUS, (X86cmp FR32:$src1, (loadf32 addr:$src2)))]>, + Imp<[],[STATUS]>, Requires<[HasSSE1]>, TB; // Pseudo-instructions that map fld0 to xorps/xorpd for sse. // FIXME: remove when we can teach regalloc that xor reg, reg is ok. def FLD0SS : I<0x57, MRMSrcReg, (ops FR32:$dst), - "xorps $dst, $dst", - [(set FR32:$dst, fp32imm0)]>, + "xorps $dst, $dst", [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>, TB; def FLD0SD : I<0x57, MRMSrcReg, (ops FR64:$dst), - "xorpd $dst, $dst", - [(set FR64:$dst, fp64imm0)]>, + "xorpd $dst, $dst", [(set FR64:$dst, fp64imm0)]>, Requires<[HasSSE2]>, TB, OpSize; let isTwoAddress = 1 in { @@ -2605,10 +2717,11 @@ // Floating point compares. -def FpUCOMr : FpI<(ops RST:$lhs, RST:$rhs), CompareFP, +def FpUCOMr : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP, []>; // FPSW = cmp ST(0) with ST(i) -def FpUCOMIr : FpI<(ops RST:$lhs, RST:$rhs), CompareFP, - []>; // CC = cmp ST(0) with ST(i) +def FpUCOMIr : FpI<(ops RFP:$lhs, RFP:$rhs), CompareFP, + [(set STATUS, (X86cmp RFP:$lhs, RFP:$rhs))]>, + Imp<[],[STATUS]>; // CC = cmp ST(0) with ST(i) def FUCOMr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i) (ops RST:$reg), Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.115 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.116 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.115 Sat Dec 24 03:48:35 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Thu Jan 5 18:43:03 2006 @@ -568,7 +568,8 @@ switch (MBBI->getOpcode()) { case X86::RET: case X86::RETI: - case X86::RETVOID: // FIXME: See X86InstrInfo.td + case X86::RETVOID: // FIXME: See X86InstrInfo.td + case X86::RETIVOID: // FIXME: See X86InstrInfo.td case X86::TAILJMPd: case X86::TAILJMPr: case X86::TAILJMPm: break; // These are ok From lattner at cs.uiuc.edu Thu Jan 5 18:59:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Jan 2006 18:59:58 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Prolangs-C++/family/family.cpp Message-ID: <200601060059.SAA14657@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource/Benchmarks/Prolangs-C++/family: family.cpp updated: 1.2 -> 1.3 --- Log message: fix some undefined behavior in this testcase, though it is not causing a problem --- Diffs of the changes: (+12 -12) family.cpp | 24 ++++++++++++------------ 1 files changed, 12 insertions(+), 12 deletions(-) Index: llvm-test/MultiSource/Benchmarks/Prolangs-C++/family/family.cpp diff -u llvm-test/MultiSource/Benchmarks/Prolangs-C++/family/family.cpp:1.2 llvm-test/MultiSource/Benchmarks/Prolangs-C++/family/family.cpp:1.3 --- llvm-test/MultiSource/Benchmarks/Prolangs-C++/family/family.cpp:1.2 Mon Oct 4 19:59:55 2004 +++ llvm-test/MultiSource/Benchmarks/Prolangs-C++/family/family.cpp Thu Jan 5 18:59:46 2006 @@ -9,24 +9,24 @@ char *lastName; public: Parent(void) { - lastName = new char; // was char[5]; + lastName = new char[100]; // was char[5]; strcpy(lastName, "None"); } Parent (char *aLastName) { - strlen(aLastName), lastName = new char; // was char[strlen(aLastName) + 1] + strlen(aLastName), lastName = new char[100]; // was char[strlen(aLastName) + 1] strcpy(lastName,aLastName); } Parent (Parent& aParent) { - strlen(aParent.lastName), lastName = new char; + strlen(aParent.lastName), lastName = new char[100]; strcpy(lastName,aParent.lastName); } char *getLastName(void) { return lastName;} void setLastName(char *aName) { - strlen(aName), lastName = new char; + strlen(aName), lastName = new char[100]; strcpy(lastName,aName); } @@ -35,7 +35,7 @@ } ~Parent(void) { - delete lastName; + delete [] lastName; } }; @@ -44,18 +44,18 @@ char *firstName; public: Child(void) { - firstName = new char; + firstName = new char[100]; strcpy(firstName,"None"); } Child (char *aLastName, char *aFirstName) : Parent (aLastName) { - strlen(aFirstName), firstName = new char; + strlen(aFirstName), firstName = new char[100]; strcpy(firstName,aFirstName); } Child(Child& aChild) { setLastName(aChild.getLastName()); - strlen(aChild.firstName), firstName = new char; + strlen(aChild.firstName), firstName = new char[100]; strcpy(firstName,aChild.firstName); } @@ -64,12 +64,12 @@ } void setFirstName(char *aName) { - strlen(aName), firstName = new char; + strlen(aName), firstName = new char[100]; strcpy(firstName,aName); } ~Child(void) { - delete firstName; + delete [] firstName; } virtual void answerName(void) { @@ -84,11 +84,11 @@ public: GrandChild(char *aLastName,char *aFirstName,char *aGrandFatherName):Child(aLastName, aFirstName) { - strlen(aGrandFatherName), grandFatherName = new char; + strlen(aGrandFatherName), grandFatherName = new char[100]; strcpy(grandFatherName, aGrandFatherName); } - ~GrandChild(void) { delete grandFatherName;} + ~GrandChild(void) { delete [] grandFatherName;} virtual void answerName(void) { Child::answerName(); From lattner at cs.uiuc.edu Thu Jan 5 19:04:15 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Jan 2006 19:04:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200601060104.TAA14815@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.58 -> 1.59 --- Log message: linkonce symbols have an extra indirection, just like weak ones do. This fixes Prolangs-C++/family and Prolangs-C++/primes. --- Diffs of the changes: (+2 -1) PPCISelLowering.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.58 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.59 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.58 Wed Jan 4 19:47:43 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Thu Jan 5 19:04:03 2006 @@ -379,6 +379,7 @@ // Only lower GlobalAddress on Darwin. if (!getTargetMachine().getSubtarget().isDarwin()) break; + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); if (PICEnabled) { // With PIC, the first instruction is actually "GR+hi(&G)". @@ -389,7 +390,7 @@ SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); - if (!GV->hasWeakLinkage() && !GV->isExternal()) + if (!GV->hasWeakLinkage() && !GV->hasLinkOnceLinkage() && !GV->isExternal()) return Lo; // If the global is weak or external, we have to go through the lazy From evan.cheng at apple.com Thu Jan 5 19:06:43 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 5 Jan 2006 19:06:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200601060106.TAA14874@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.21 -> 1.22 --- Log message: fold (shl x, 1) -> (add x, x) --- Diffs of the changes: (+0 -20) X86ISelDAGToDAG.cpp | 20 -------------------- 1 files changed, 20 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.21 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.22 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.21 Wed Jan 4 20:08:37 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Thu Jan 5 19:06:31 2006 @@ -363,26 +363,6 @@ switch (Node->getOpcode()) { default: break; - case ISD::SHL: - if (ConstantSDNode *CN = dyn_cast(Node->getOperand(1))) { - if (CN->getValue() == 1) { - // X = SHL Y, 1 -> X = ADD Y, Y - switch (NVT) { - default: assert(0 && "Cannot shift this type!"); - case MVT::i8: Opc = X86::ADD8rr; break; - case MVT::i16: Opc = X86::ADD16rr; break; - case MVT::i32: Opc = X86::ADD32rr; break; - } - SDOperand Tmp0 = Select(Node->getOperand(0)); - if (Node->hasOneUse()) - return CurDAG->SelectNodeTo(Node, Opc, NVT, Tmp0, Tmp0); - else - return CodeGenMap[N] = - CurDAG->getTargetNode(Opc, NVT, Tmp0, Tmp0); - } - } - break; - case ISD::TRUNCATE: { unsigned Reg; MVT::ValueType VT; From evan.cheng at apple.com Thu Jan 5 19:06:43 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 5 Jan 2006 19:06:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200601060106.TAA14878@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.77 -> 1.78 --- Log message: fold (shl x, 1) -> (add x, x) --- Diffs of the changes: (+3 -0) DAGCombiner.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.77 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.78 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.77 Wed Jan 4 19:25:28 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Jan 5 19:06:31 2006 @@ -1282,6 +1282,9 @@ // fold (shl x, 0) -> x if (N1C && N1C->isNullValue()) return N0; + // fold (shl x, 1) -> (add x, x) + if (N1C && N1C->getValue() == 1) + return DAG.getNode(ISD::ADD, VT, N0, N0); // if (shl x, c) is known to be zero, return 0 if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) return DAG.getConstant(0, VT); From evan.cheng at apple.com Thu Jan 5 19:56:14 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 5 Jan 2006 19:56:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200601060156.TAA15088@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.78 -> 1.79 --- Log message: Revert the previous check-in. Leave shl x, 1 along for target to deal with. --- Diffs of the changes: (+0 -3) DAGCombiner.cpp | 3 --- 1 files changed, 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.78 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.79 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.78 Thu Jan 5 19:06:31 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Jan 5 19:56:02 2006 @@ -1282,9 +1282,6 @@ // fold (shl x, 0) -> x if (N1C && N1C->isNullValue()) return N0; - // fold (shl x, 1) -> (add x, x) - if (N1C && N1C->getValue() == 1) - return DAG.getNode(ISD::ADD, VT, N0, N0); // if (shl x, c) is known to be zero, return 0 if (N1C && MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits),TLI)) return DAG.getConstant(0, VT); From evan.cheng at apple.com Thu Jan 5 20:30:35 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 5 Jan 2006 20:30:35 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200601060230.UAA15837@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.125 -> 1.126 --- Log message: Tweak pattern complexity calc. --- Diffs of the changes: (+4 -9) DAGISelEmitter.cpp | 13 ++++--------- 1 files changed, 4 insertions(+), 9 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.125 llvm/utils/TableGen/DAGISelEmitter.cpp:1.126 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.125 Thu Jan 5 18:41:12 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Jan 5 20:30:23 2006 @@ -1691,12 +1691,7 @@ /// patterns before small ones. This is used to determine the size of a /// pattern. static unsigned getPatternSize(TreePatternNode *P, DAGISelEmitter &ISE) { - assert(isExtIntegerInVTs(P->getExtTypes()) || - isExtFloatingPointInVTs(P->getExtTypes()) || - P->getExtTypeNum(0) == MVT::isVoid || - P->getExtTypeNum(0) == MVT::Flag && - "Not a valid pattern node to size!"); - unsigned Size = 1; // The node itself. + unsigned Size = 2; // The node itself. // FIXME: This is a hack to statically increase the priority of patterns // which maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. @@ -1713,10 +1708,10 @@ if (!Child->isLeaf() && Child->getExtTypeNum(0) != MVT::Other) Size += getPatternSize(Child, ISE); else if (Child->isLeaf()) { + Size += getPatternSize(Child, ISE); if (dynamic_cast(Child->getLeafValue())) - ++Size; // Matches a ConstantSDNode. - else if (NodeIsComplexPattern(Child)) - Size += getPatternSize(Child, ISE); + // Matches a ConstantSDNode. More specific to any immediate. + ++Size; } } From evan.cheng at apple.com Thu Jan 5 20:32:11 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 5 Jan 2006 20:32:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200601060232.UAA15930@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.189 -> 1.190 --- Log message: Addd (shl x, 1) ==> (shl x, x) peepholes. --- Diffs of the changes: (+10 -1) X86InstrInfo.td | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.189 llvm/lib/Target/X86/X86InstrInfo.td:1.190 --- llvm/lib/Target/X86/X86InstrInfo.td:1.189 Thu Jan 5 18:43:03 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Thu Jan 5 20:31:59 2006 @@ -1343,7 +1343,6 @@ } // Shift instructions -// FIXME: provide shorter instructions when imm8 == 1 def SHL8rCL : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src), "shl{b} {%cl, $dst|$dst, %CL}", [(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>; @@ -2756,3 +2755,13 @@ //===----------------------------------------------------------------------===// def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", []>, TB, Imp<[],[EAX,EDX]>; + + +//===----------------------------------------------------------------------===// +// Some peepholes +//===----------------------------------------------------------------------===// + +// (shl x, 1) ==> (add x, x) +def : Pat<(shl R8 :$src1, (i8 1)), (ADD8rr R8 :$src1, R8 :$src1)>; +def : Pat<(shl R16:$src1, (i8 1)), (ADD16rr R16:$src1, R16:$src1)>; +def : Pat<(shl R32:$src1, (i8 1)), (ADD32rr R32:$src1, R32:$src1)>; From lattner at cs.uiuc.edu Thu Jan 5 23:48:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 5 Jan 2006 23:48:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200601060548.XAA16611@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.254 -> 1.255 --- Log message: Unbreak the build :( --- Diffs of the changes: (+2 -2) LegalizeDAG.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.254 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.255 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.254 Thu Jan 5 18:41:43 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Jan 5 23:47:48 2006 @@ -1303,8 +1303,8 @@ } } - MVT::ValueType VT = Node->getValueType(0); - switch (TLI.getOperationAction(Node->getOpcode(), VT)) { + switch (TLI.getOperationAction(Node->getOpcode(), + Node->getValueType(0))) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Custom: { SDOperand Tmp = TLI.LowerOperation(Result, DAG); From lattner at cs.uiuc.edu Fri Jan 6 01:12:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 01:12:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200601060712.BAA16972@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.406 -> 1.407 --- Log message: Extract a bunch of code out of visitShiftInst into FoldShiftByConstant. No functionality changes. --- Diffs of the changes: (+190 -181) InstructionCombining.cpp | 371 ++++++++++++++++++++++++----------------------- 1 files changed, 190 insertions(+), 181 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.406 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.407 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.406 Sat Nov 5 03:21:28 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan 6 01:12:35 2006 @@ -119,6 +119,8 @@ Instruction *FoldGEPSetCC(User *GEPLHS, Value *RHS, Instruction::BinaryOps Cond, Instruction &I); Instruction *visitShiftInst(ShiftInst &I); + Instruction *FoldShiftByConstant(Value *Op0, ConstantUInt *Op1, + ShiftInst &I); Instruction *visitCastInst(CastInst &CI); Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI); @@ -3438,75 +3440,84 @@ } } - if (ConstantUInt *CUI = dyn_cast(Op1)) { - // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr - // of a signed value. - // - unsigned TypeBits = Op0->getType()->getPrimitiveSizeInBits(); - if (CUI->getValue() >= TypeBits) { - if (!Op0->getType()->isSigned() || isLeftShift) - return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType())); - else { - I.setOperand(1, ConstantUInt::get(Type::UByteTy, TypeBits-1)); - return &I; - } - } - - // ((X*C1) << C2) == (X * (C1 << C2)) - if (BinaryOperator *BO = dyn_cast(Op0)) - if (BO->getOpcode() == Instruction::Mul && isLeftShift) - if (Constant *BOOp = dyn_cast(BO->getOperand(1))) - return BinaryOperator::createMul(BO->getOperand(0), - ConstantExpr::getShl(BOOp, CUI)); + if (ConstantUInt *CUI = dyn_cast(Op1)) + if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I)) + return Res; + return 0; +} - // Try to fold constant and into select arguments. - if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldOpIntoSelect(I, SI, this)) - return R; - if (isa(Op0)) - if (Instruction *NV = FoldOpIntoPhi(I)) - return NV; +Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantUInt *Op1, + ShiftInst &I) { + bool isLeftShift = I.getOpcode() == Instruction::Shl; - if (Op0->hasOneUse()) { - // If this is a SHL of a sign-extending cast, see if we can turn the input - // into a zero extending cast (a simple strength reduction). - if (CastInst *CI = dyn_cast(Op0)) { - const Type *SrcTy = CI->getOperand(0)->getType(); - if (isLeftShift && SrcTy->isInteger() && SrcTy->isSigned() && - SrcTy->getPrimitiveSizeInBits() < - CI->getType()->getPrimitiveSizeInBits()) { - // We can change it to a zero extension if we are shifting out all of - // the sign extended bits. To check this, form a mask of all of the - // sign extend bits, then shift them left and see if we have anything - // left. - Constant *Mask = ConstantIntegral::getAllOnesValue(SrcTy); // 1111 - Mask = ConstantExpr::getZeroExtend(Mask, CI->getType()); // 00001111 - Mask = ConstantExpr::getNot(Mask); // 1's in the sign bits: 11110000 - if (ConstantExpr::getShl(Mask, CUI)->isNullValue()) { - // If the shift is nuking all of the sign bits, change this to a - // zero extension cast. To do this, cast the cast input to - // unsigned, then to the requested size. - Value *CastOp = CI->getOperand(0); - Instruction *NC = - new CastInst(CastOp, CastOp->getType()->getUnsignedVersion(), - CI->getName()+".uns"); - NC = InsertNewInstBefore(NC, I); - // Finally, insert a replacement for CI. - NC = new CastInst(NC, CI->getType(), CI->getName()); - CI->setName(""); - NC = InsertNewInstBefore(NC, I); - WorkList.push_back(CI); // Delete CI later. - I.setOperand(0, NC); - return &I; // The SHL operand was modified. - } + // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr + // of a signed value. + // + unsigned TypeBits = Op0->getType()->getPrimitiveSizeInBits(); + if (Op1->getValue() >= TypeBits) { + if (!Op0->getType()->isSigned() || isLeftShift) + return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType())); + else { + I.setOperand(1, ConstantUInt::get(Type::UByteTy, TypeBits-1)); + return &I; + } + } + + // ((X*C1) << C2) == (X * (C1 << C2)) + if (BinaryOperator *BO = dyn_cast(Op0)) + if (BO->getOpcode() == Instruction::Mul && isLeftShift) + if (Constant *BOOp = dyn_cast(BO->getOperand(1))) + return BinaryOperator::createMul(BO->getOperand(0), + ConstantExpr::getShl(BOOp, Op1)); + + // Try to fold constant and into select arguments. + if (SelectInst *SI = dyn_cast(Op0)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) + return R; + if (isa(Op0)) + if (Instruction *NV = FoldOpIntoPhi(I)) + return NV; + + if (Op0->hasOneUse()) { + // If this is a SHL of a sign-extending cast, see if we can turn the input + // into a zero extending cast (a simple strength reduction). + if (CastInst *CI = dyn_cast(Op0)) { + const Type *SrcTy = CI->getOperand(0)->getType(); + if (isLeftShift && SrcTy->isInteger() && SrcTy->isSigned() && + SrcTy->getPrimitiveSizeInBits() < + CI->getType()->getPrimitiveSizeInBits()) { + // We can change it to a zero extension if we are shifting out all of + // the sign extended bits. To check this, form a mask of all of the + // sign extend bits, then shift them left and see if we have anything + // left. + Constant *Mask = ConstantIntegral::getAllOnesValue(SrcTy); // 1111 + Mask = ConstantExpr::getZeroExtend(Mask, CI->getType()); // 00001111 + Mask = ConstantExpr::getNot(Mask); // 1's in the sign bits: 11110000 + if (ConstantExpr::getShl(Mask, Op1)->isNullValue()) { + // If the shift is nuking all of the sign bits, change this to a + // zero extension cast. To do this, cast the cast input to + // unsigned, then to the requested size. + Value *CastOp = CI->getOperand(0); + Instruction *NC = + new CastInst(CastOp, CastOp->getType()->getUnsignedVersion(), + CI->getName()+".uns"); + NC = InsertNewInstBefore(NC, I); + // Finally, insert a replacement for CI. + NC = new CastInst(NC, CI->getType(), CI->getName()); + CI->setName(""); + NC = InsertNewInstBefore(NC, I); + WorkList.push_back(CI); // Delete CI later. + I.setOperand(0, NC); + return &I; // The SHL operand was modified. } } - - if (BinaryOperator *Op0BO = dyn_cast(Op0)) { - // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C) - Value *V1, *V2; - ConstantInt *CC; - switch (Op0BO->getOpcode()) { + } + + if (BinaryOperator *Op0BO = dyn_cast(Op0)) { + // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C) + Value *V1, *V2; + ConstantInt *CC; + switch (Op0BO->getOpcode()) { default: break; case Instruction::Add: case Instruction::And: @@ -3516,85 +3527,85 @@ // Turn (Y + (X >> C)) << C -> (X + (Y << C)) & (~0 << C) if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() && match(Op0BO->getOperand(1), - m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == CUI) { + m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == Op1) { Instruction *YS = new ShiftInst(Instruction::Shl, - Op0BO->getOperand(0), CUI, + Op0BO->getOperand(0), Op1, Op0BO->getName()); InsertNewInstBefore(YS, I); // (Y << C) Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS, V1, - Op0BO->getOperand(1)->getName()); + Op0BO->getOperand(1)->getName()); InsertNewInstBefore(X, I); // (X + (Y << C)) Constant *C2 = ConstantInt::getAllOnesValue(X->getType()); - C2 = ConstantExpr::getShl(C2, CUI); + C2 = ConstantExpr::getShl(C2, Op1); return BinaryOperator::createAnd(X, C2); } - + // Turn (Y + ((X >> C) & CC)) << C -> ((X & (CC << C)) + (Y << C)) if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() && match(Op0BO->getOperand(1), m_And(m_Shr(m_Value(V1), m_Value(V2)), - m_ConstantInt(CC))) && V2 == CUI && - cast(Op0BO->getOperand(1))->getOperand(0)->hasOneUse()) { + m_ConstantInt(CC))) && V2 == Op1 && + cast(Op0BO->getOperand(1))->getOperand(0)->hasOneUse()) { Instruction *YS = new ShiftInst(Instruction::Shl, - Op0BO->getOperand(0), CUI, + Op0BO->getOperand(0), Op1, Op0BO->getName()); InsertNewInstBefore(YS, I); // (Y << C) Instruction *XM = - BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, CUI), + BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, Op1), V1->getName()+".mask"); InsertNewInstBefore(XM, I); // X & (CC << C) return BinaryOperator::create(Op0BO->getOpcode(), YS, XM); } - + // FALL THROUGH. case Instruction::Sub: // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C) if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() && match(Op0BO->getOperand(0), - m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == CUI) { + m_Shr(m_Value(V1), m_ConstantInt(CC))) && CC == Op1) { Instruction *YS = new ShiftInst(Instruction::Shl, - Op0BO->getOperand(1), CUI, + Op0BO->getOperand(1), Op1, Op0BO->getName()); InsertNewInstBefore(YS, I); // (Y << C) Instruction *X = BinaryOperator::create(Op0BO->getOpcode(), YS, V1, - Op0BO->getOperand(0)->getName()); + Op0BO->getOperand(0)->getName()); InsertNewInstBefore(X, I); // (X + (Y << C)) Constant *C2 = ConstantInt::getAllOnesValue(X->getType()); - C2 = ConstantExpr::getShl(C2, CUI); + C2 = ConstantExpr::getShl(C2, Op1); return BinaryOperator::createAnd(X, C2); } - + if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() && match(Op0BO->getOperand(0), m_And(m_Shr(m_Value(V1), m_Value(V2)), - m_ConstantInt(CC))) && V2 == CUI && - cast(Op0BO->getOperand(0))->getOperand(0)->hasOneUse()) { + m_ConstantInt(CC))) && V2 == Op1 && + cast(Op0BO->getOperand(0))->getOperand(0)->hasOneUse()) { Instruction *YS = new ShiftInst(Instruction::Shl, - Op0BO->getOperand(1), CUI, + Op0BO->getOperand(1), Op1, Op0BO->getName()); InsertNewInstBefore(YS, I); // (Y << C) Instruction *XM = - BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, CUI), + BinaryOperator::createAnd(V1, ConstantExpr::getShl(CC, Op1), V1->getName()+".mask"); InsertNewInstBefore(XM, I); // X & (CC << C) return BinaryOperator::create(Op0BO->getOpcode(), YS, XM); } - + break; - } - - - // If the operand is an bitwise operator with a constant RHS, and the - // shift is the only use, we can pull it out of the shift. - if (ConstantInt *Op0C = dyn_cast(Op0BO->getOperand(1))) { - bool isValid = true; // Valid only for And, Or, Xor - bool highBitSet = false; // Transform if high bit of constant set? - - switch (Op0BO->getOpcode()) { + } + + + // If the operand is an bitwise operator with a constant RHS, and the + // shift is the only use, we can pull it out of the shift. + if (ConstantInt *Op0C = dyn_cast(Op0BO->getOperand(1))) { + bool isValid = true; // Valid only for And, Or, Xor + bool highBitSet = false; // Transform if high bit of constant set? + + switch (Op0BO->getOpcode()) { default: isValid = false; break; // Do not perform transform! case Instruction::Add: isValid = isLeftShift; @@ -3606,99 +3617,97 @@ case Instruction::And: highBitSet = true; break; - } - - // If this is a signed shift right, and the high bit is modified - // by the logical operation, do not perform the transformation. - // The highBitSet boolean indicates the value of the high bit of - // the constant which would cause it to be modified for this - // operation. - // - if (isValid && !isLeftShift && !I.getType()->isUnsigned()) { - uint64_t Val = Op0C->getRawValue(); - isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet; - } - - if (isValid) { - Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, CUI); - - Instruction *NewShift = - new ShiftInst(I.getOpcode(), Op0BO->getOperand(0), CUI, - Op0BO->getName()); - Op0BO->setName(""); - InsertNewInstBefore(NewShift, I); - - return BinaryOperator::create(Op0BO->getOpcode(), NewShift, - NewRHS); - } + } + + // If this is a signed shift right, and the high bit is modified + // by the logical operation, do not perform the transformation. + // The highBitSet boolean indicates the value of the high bit of + // the constant which would cause it to be modified for this + // operation. + // + if (isValid && !isLeftShift && !I.getType()->isUnsigned()) { + uint64_t Val = Op0C->getRawValue(); + isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet; + } + + if (isValid) { + Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, Op1); + + Instruction *NewShift = + new ShiftInst(I.getOpcode(), Op0BO->getOperand(0), Op1, + Op0BO->getName()); + Op0BO->setName(""); + InsertNewInstBefore(NewShift, I); + + return BinaryOperator::create(Op0BO->getOpcode(), NewShift, + NewRHS); } } } - - // If this is a shift of a shift, see if we can fold the two together... - if (ShiftInst *Op0SI = dyn_cast(Op0)) - if (ConstantUInt *ShiftAmt1C = - dyn_cast(Op0SI->getOperand(1))) { - unsigned ShiftAmt1 = (unsigned)ShiftAmt1C->getValue(); - unsigned ShiftAmt2 = (unsigned)CUI->getValue(); - - // Check for (A << c1) << c2 and (A >> c1) >> c2 - if (I.getOpcode() == Op0SI->getOpcode()) { - unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift... - if (Op0->getType()->getPrimitiveSizeInBits() < Amt) - Amt = Op0->getType()->getPrimitiveSizeInBits(); - return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0), - ConstantUInt::get(Type::UByteTy, Amt)); - } - - // Check for (A << c1) >> c2 or visaversa. If we are dealing with - // signed types, we can only support the (A >> c1) << c2 configuration, - // because it can not turn an arbitrary bit of A into a sign bit. - if (I.getType()->isUnsigned() || isLeftShift) { - // Calculate bitmask for what gets shifted off the edge... - Constant *C = ConstantIntegral::getAllOnesValue(I.getType()); - if (isLeftShift) - C = ConstantExpr::getShl(C, ShiftAmt1C); - else - C = ConstantExpr::getShr(C, ShiftAmt1C); - - Instruction *Mask = - BinaryOperator::createAnd(Op0SI->getOperand(0), C, - Op0SI->getOperand(0)->getName()+".mask"); - InsertNewInstBefore(Mask, I); - - // Figure out what flavor of shift we should use... - if (ShiftAmt1 == ShiftAmt2) - return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 - else if (ShiftAmt1 < ShiftAmt2) { - return new ShiftInst(I.getOpcode(), Mask, - ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); - } else { - return new ShiftInst(Op0SI->getOpcode(), Mask, - ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); - } + } + + // If this is a shift of a shift, see if we can fold the two together. + if (ShiftInst *Op0SI = dyn_cast(Op0)) + if (ConstantUInt *ShiftAmt1C = + dyn_cast(Op0SI->getOperand(1))) { + unsigned ShiftAmt1 = (unsigned)ShiftAmt1C->getValue(); + unsigned ShiftAmt2 = (unsigned)Op1->getValue(); + + // Check for (A << c1) << c2 and (A >> c1) >> c2 + if (I.getOpcode() == Op0SI->getOpcode()) { + unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift. + if (Op0->getType()->getPrimitiveSizeInBits() < Amt) + Amt = Op0->getType()->getPrimitiveSizeInBits(); + return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0), + ConstantUInt::get(Type::UByteTy, Amt)); + } + + // Check for (A << c1) >> c2 or visaversa. If we are dealing with + // signed types, we can only support the (A >> c1) << c2 configuration, + // because it can not turn an arbitrary bit of A into a sign bit. + if (I.getType()->isUnsigned() || isLeftShift) { + // Calculate bitmask for what gets shifted off the edge... + Constant *C = ConstantIntegral::getAllOnesValue(I.getType()); + if (isLeftShift) + C = ConstantExpr::getShl(C, ShiftAmt1C); + else + C = ConstantExpr::getShr(C, ShiftAmt1C); + + Instruction *Mask = + BinaryOperator::createAnd(Op0SI->getOperand(0), C, + Op0SI->getOperand(0)->getName()+".mask"); + InsertNewInstBefore(Mask, I); + + // Figure out what flavor of shift we should use... + if (ShiftAmt1 == ShiftAmt2) + return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 + else if (ShiftAmt1 < ShiftAmt2) { + return new ShiftInst(I.getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); } else { - // We can handle signed (X << C1) >> C2 if it's a sign extend. In - // this case, C1 == C2 and C1 is 8, 16, or 32. - if (ShiftAmt1 == ShiftAmt2) { - const Type *SExtType = 0; - switch (ShiftAmt1) { - case 8 : SExtType = Type::SByteTy; break; - case 16: SExtType = Type::ShortTy; break; - case 32: SExtType = Type::IntTy; break; - } - - if (SExtType) { - Instruction *NewTrunc = new CastInst(Op0SI->getOperand(0), - SExtType, "sext"); - InsertNewInstBefore(NewTrunc, I); - return new CastInst(NewTrunc, I.getType()); - } + return new ShiftInst(Op0SI->getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + } + } else { + // We can handle signed (X << C1) >> C2 if it's a sign extend. In + // this case, C1 == C2 and C1 is 8, 16, or 32. + if (ShiftAmt1 == ShiftAmt2) { + const Type *SExtType = 0; + switch (ShiftAmt1) { + case 8 : SExtType = Type::SByteTy; break; + case 16: SExtType = Type::ShortTy; break; + case 32: SExtType = Type::IntTy; break; + } + + if (SExtType) { + Instruction *NewTrunc = new CastInst(Op0SI->getOperand(0), + SExtType, "sext"); + InsertNewInstBefore(NewTrunc, I); + return new CastInst(NewTrunc, I.getType()); } } } - } - + } return 0; } From lattner at cs.uiuc.edu Fri Jan 6 01:22:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 01:22:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200601060722.BAA17058@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.407 -> 1.408 --- Log message: Simplify the code a bit more --- Diffs of the changes: (+5 -3) InstructionCombining.cpp | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.407 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.408 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.407 Fri Jan 6 01:12:35 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan 6 01:22:22 2006 @@ -3449,13 +3449,15 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantUInt *Op1, ShiftInst &I) { bool isLeftShift = I.getOpcode() == Instruction::Shl; + bool isSignedShift = Op0->getType()->isSigned(); + bool isUnsignedShift = !isSignedShift; // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr // of a signed value. // unsigned TypeBits = Op0->getType()->getPrimitiveSizeInBits(); if (Op1->getValue() >= TypeBits) { - if (!Op0->getType()->isSigned() || isLeftShift) + if (isUnsignedShift || isLeftShift) return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType())); else { I.setOperand(1, ConstantUInt::get(Type::UByteTy, TypeBits-1)); @@ -3625,7 +3627,7 @@ // the constant which would cause it to be modified for this // operation. // - if (isValid && !isLeftShift && !I.getType()->isUnsigned()) { + if (isValid && !isLeftShift && isSignedShift) { uint64_t Val = Op0C->getRawValue(); isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet; } @@ -3665,7 +3667,7 @@ // Check for (A << c1) >> c2 or visaversa. If we are dealing with // signed types, we can only support the (A >> c1) << c2 configuration, // because it can not turn an arbitrary bit of A into a sign bit. - if (I.getType()->isUnsigned() || isLeftShift) { + if (isUnsignedShift || isLeftShift) { // Calculate bitmask for what gets shifted off the edge... Constant *C = ConstantIntegral::getAllOnesValue(I.getType()); if (isLeftShift) From lattner at cs.uiuc.edu Fri Jan 6 01:48:40 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 01:48:40 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/shift.ll Message-ID: <200601060748.BAA17157@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: shift.ll updated: 1.21 -> 1.22 --- Log message: A case that instcombine is not catching. --- Diffs of the changes: (+7 -0) shift.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/shift.ll diff -u llvm/test/Regression/Transforms/InstCombine/shift.ll:1.21 llvm/test/Regression/Transforms/InstCombine/shift.ll:1.22 --- llvm/test/Regression/Transforms/InstCombine/shift.ll:1.21 Sun Sep 18 00:10:39 2005 +++ llvm/test/Regression/Transforms/InstCombine/shift.ll Fri Jan 6 01:48:28 2006 @@ -180,3 +180,10 @@ ret uint %tmp.6 } +int %test26(uint %A) { ;; handle casts between shifts. + %B = shr uint %A, ubyte 1 + %C = cast uint %B to int + %D = shl int %C, ubyte 1 + ret int %D +} + From lattner at cs.uiuc.edu Fri Jan 6 01:52:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 01:52:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200601060752.BAA17224@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.408 -> 1.409 --- Log message: Enhance the shift-shift folding code to allow a no-op cast to occur in between the shifts. This allows us to fold this (which is the 'integer add a constant' sequence from cozmic's scheme compmiler): int %x(uint %anf-temporary776) { %anf-temporary777 = shr uint %anf-temporary776, ubyte 1 %anf-temporary800 = cast uint %anf-temporary777 to int %anf-temporary804 = shl int %anf-temporary800, ubyte 1 %anf-temporary805 = add int %anf-temporary804, -2 %anf-temporary806 = or int %anf-temporary805, 1 ret int %anf-temporary806 } into this: int %x(uint %anf-temporary776) { %anf-temporary776 = cast uint %anf-temporary776 to int %anf-temporary776.mask1 = add int %anf-temporary776, -2 %anf-temporary805 = or int %anf-temporary776.mask1, 1 ret int %anf-temporary805 } note that instcombine already knew how to eliminate the AND that the two shifts fold into. This is tested by InstCombine/shift.ll:test26 -Chris --- Diffs of the changes: (+88 -55) InstructionCombining.cpp | 143 ++++++++++++++++++++++++++++------------------- 1 files changed, 88 insertions(+), 55 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.408 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.409 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.408 Fri Jan 6 01:22:22 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan 6 01:52:12 2006 @@ -3648,68 +3648,101 @@ } } - // If this is a shift of a shift, see if we can fold the two together. + // Find out if this is a shift of a shift by a constant. + ShiftInst *ShiftOp = 0; if (ShiftInst *Op0SI = dyn_cast(Op0)) - if (ConstantUInt *ShiftAmt1C = - dyn_cast(Op0SI->getOperand(1))) { - unsigned ShiftAmt1 = (unsigned)ShiftAmt1C->getValue(); - unsigned ShiftAmt2 = (unsigned)Op1->getValue(); + ShiftOp = Op0SI; + else if (CastInst *CI = dyn_cast(Op0)) { + // If this is a noop-integer case of a shift instruction, use the shift. + if (CI->getOperand(0)->getType()->isInteger() && + CI->getOperand(0)->getType()->getPrimitiveSizeInBits() == + CI->getType()->getPrimitiveSizeInBits() && + isa(CI->getOperand(0))) { + ShiftOp = cast(CI->getOperand(0)); + } + } + + if (ShiftOp && isa(ShiftOp->getOperand(1))) { + // Find the operands and properties of the input shift. Note that the + // signedness of the input shift may differ from the current shift if there + // is a noop cast between the two. + bool isShiftOfLeftShift = ShiftOp->getOpcode() == Instruction::Shl; + bool isShiftOfSignedShift = ShiftOp->getType()->isSigned(); + bool isShiftOfUnsignedShift = !isSignedShift; + + ConstantUInt *ShiftAmt1C = cast(ShiftOp->getOperand(1)); + + unsigned ShiftAmt1 = (unsigned)ShiftAmt1C->getValue(); + unsigned ShiftAmt2 = (unsigned)Op1->getValue(); + + // Check for (A << c1) << c2 and (A >> c1) >> c2. + if (isLeftShift == isShiftOfLeftShift) { + // Do not fold these shifts if the first one is signed and the second one + // is unsigned and this is a right shift. Further, don't do any folding + // on them. + if (isShiftOfSignedShift && isUnsignedShift && !isLeftShift) + return 0; - // Check for (A << c1) << c2 and (A >> c1) >> c2 - if (I.getOpcode() == Op0SI->getOpcode()) { - unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift. - if (Op0->getType()->getPrimitiveSizeInBits() < Amt) - Amt = Op0->getType()->getPrimitiveSizeInBits(); - return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0), - ConstantUInt::get(Type::UByteTy, Amt)); - } + unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift. + if (Amt > Op0->getType()->getPrimitiveSizeInBits()) + Amt = Op0->getType()->getPrimitiveSizeInBits(); - // Check for (A << c1) >> c2 or visaversa. If we are dealing with - // signed types, we can only support the (A >> c1) << c2 configuration, - // because it can not turn an arbitrary bit of A into a sign bit. - if (isUnsignedShift || isLeftShift) { - // Calculate bitmask for what gets shifted off the edge... - Constant *C = ConstantIntegral::getAllOnesValue(I.getType()); - if (isLeftShift) - C = ConstantExpr::getShl(C, ShiftAmt1C); - else - C = ConstantExpr::getShr(C, ShiftAmt1C); - - Instruction *Mask = - BinaryOperator::createAnd(Op0SI->getOperand(0), C, - Op0SI->getOperand(0)->getName()+".mask"); - InsertNewInstBefore(Mask, I); - - // Figure out what flavor of shift we should use... - if (ShiftAmt1 == ShiftAmt2) - return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 - else if (ShiftAmt1 < ShiftAmt2) { - return new ShiftInst(I.getOpcode(), Mask, - ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); - } else { - return new ShiftInst(Op0SI->getOpcode(), Mask, - ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); - } + Value *Op = ShiftOp->getOperand(0); + if (isShiftOfSignedShift != isSignedShift) + Op = InsertNewInstBefore(new CastInst(Op, I.getType(), "tmp"), I); + return new ShiftInst(I.getOpcode(), Op, + ConstantUInt::get(Type::UByteTy, Amt)); + } + + // Check for (A << c1) >> c2 or (A >> c1) << c2. If we are dealing with + // signed types, we can only support the (A >> c1) << c2 configuration, + // because it can not turn an arbitrary bit of A into a sign bit. + if (isUnsignedShift || isLeftShift) { + // Calculate bitmask for what gets shifted off the edge. + Constant *C = ConstantIntegral::getAllOnesValue(I.getType()); + if (isLeftShift) + C = ConstantExpr::getShl(C, ShiftAmt1C); + else + C = ConstantExpr::getShr(C, ShiftAmt1C); // must be an unsigned shr. + + Value *Op = ShiftOp->getOperand(0); + if (isShiftOfSignedShift != isSignedShift) + Op = InsertNewInstBefore(new CastInst(Op, I.getType(),Op->getName()),I); + + Instruction *Mask = + BinaryOperator::createAnd(Op, C, Op->getName()+".mask"); + InsertNewInstBefore(Mask, I); + + // Figure out what flavor of shift we should use... + if (ShiftAmt1 == ShiftAmt2) + return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 + else if (ShiftAmt1 < ShiftAmt2) { + return new ShiftInst(I.getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); } else { - // We can handle signed (X << C1) >> C2 if it's a sign extend. In - // this case, C1 == C2 and C1 is 8, 16, or 32. - if (ShiftAmt1 == ShiftAmt2) { - const Type *SExtType = 0; - switch (ShiftAmt1) { - case 8 : SExtType = Type::SByteTy; break; - case 16: SExtType = Type::ShortTy; break; - case 32: SExtType = Type::IntTy; break; - } - - if (SExtType) { - Instruction *NewTrunc = new CastInst(Op0SI->getOperand(0), - SExtType, "sext"); - InsertNewInstBefore(NewTrunc, I); - return new CastInst(NewTrunc, I.getType()); - } + return new ShiftInst(ShiftOp->getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + } + } else { + // We can handle signed (X << C1) >> C2 if it's a sign extend. In + // this case, C1 == C2 and C1 is 8, 16, or 32. + if (ShiftAmt1 == ShiftAmt2) { + const Type *SExtType = 0; + switch (ShiftAmt1) { + case 8 : SExtType = Type::SByteTy; break; + case 16: SExtType = Type::ShortTy; break; + case 32: SExtType = Type::IntTy; break; + } + + if (SExtType) { + Instruction *NewTrunc = new CastInst(ShiftOp->getOperand(0), + SExtType, "sext"); + InsertNewInstBefore(NewTrunc, I); + return new CastInst(NewTrunc, I.getType()); } } } + } return 0; } From lattner at cs.uiuc.edu Fri Jan 6 11:56:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 11:56:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp Message-ID: <200601061756.LAA28049@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelPattern.cpp updated: 1.190 -> 1.191 --- Log message: silence a bogus gcc warning --- Diffs of the changes: (+1 -1) X86ISelPattern.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.190 llvm/lib/Target/X86/X86ISelPattern.cpp:1.191 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.190 Wed Dec 21 01:47:04 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Fri Jan 6 11:55:49 2006 @@ -2989,7 +2989,7 @@ // Copy the return address of the caller into a virtual register so we don't // clobber it. - SDOperand RetVal; + SDOperand RetVal(0, 0); if (ESPOffset) { SDOperand RetValAddr = X86Lowering.getReturnAddressFrameIndex(*TheDAG); RetVal = TheDAG->getLoad(MVT::i32, TheDAG->getEntryNode(), From lattner at cs.uiuc.edu Fri Jan 6 11:56:28 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 11:56:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601061756.LAA28084@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.40 -> 1.41 --- Log message: silence a bogus gcc warning --- Diffs of the changes: (+1 -1) SparcV8ISelDAGToDAG.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.40 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.41 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.40 Wed Jan 4 19:47:43 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Fri Jan 6 11:56:17 2006 @@ -379,7 +379,7 @@ for (unsigned i = 0, e = Args.size(); i != e; ++i) { SDOperand Val = Args[i].first; MVT::ValueType ObjectVT = Val.getValueType(); - SDOperand ValToStore; + SDOperand ValToStore(0, 0); unsigned ObjSize; switch (ObjectVT) { default: assert(0 && "Unhandled argument type!"); From lattner at cs.uiuc.edu Fri Jan 6 11:56:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 11:56:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelLowering.cpp Message-ID: <200601061756.LAA28119@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelLowering.cpp updated: 1.11 -> 1.12 --- Log message: silence a bogus gcc warning --- Diffs of the changes: (+1 -1) IA64ISelLowering.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/IA64/IA64ISelLowering.cpp diff -u llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.11 llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.12 --- llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.11 Wed Jan 4 19:47:43 2006 +++ llvm/lib/Target/IA64/IA64ISelLowering.cpp Fri Jan 6 11:56:38 2006 @@ -300,7 +300,7 @@ { SDOperand Val = Args[i].first; MVT::ValueType ObjectVT = Val.getValueType(); - SDOperand ValToStore, ValToConvert; + SDOperand ValToStore(0, 0), ValToConvert; unsigned ObjSize=8; switch (ObjectVT) { default: assert(0 && "unexpected argument type!"); From lattner at cs.uiuc.edu Fri Jan 6 12:00:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 12:00:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200601061800.MAA28195@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.409 -> 1.410 --- Log message: silence some bogus gcc warnings on fenris --- Diffs of the changes: (+11 -10) InstructionCombining.cpp | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.409 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.410 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.409 Fri Jan 6 01:52:12 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan 6 11:59:59 2006 @@ -721,8 +721,8 @@ if (Instruction *NV = FoldOpIntoPhi(I)) return NV; - ConstantInt *XorRHS; - Value *XorLHS; + ConstantInt *XorRHS = 0; + Value *XorLHS = 0; if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { unsigned TySizeBits = I.getType()->getPrimitiveSizeInBits(); int64_t RHSSExt = cast(RHSC)->getSExtValue(); @@ -821,7 +821,7 @@ if (Instruction *R = AssociativeOpt(I, AddMaskingAnd(C2))) return R; if (ConstantInt *CRHS = dyn_cast(RHS)) { - Value *X; + Value *X = 0; if (match(LHS, m_Not(m_Value(X)))) { // ~X + C --> (C-1) - X Constant *C= ConstantExpr::getSub(CRHS, ConstantInt::get(I.getType(), 1)); return BinaryOperator::createSub(C, X); @@ -1772,7 +1772,7 @@ // calling MaskedValueIsZero, to avoid inefficient cases where we traipse // through many levels of ands. { - Value *X; ConstantInt *C1; + Value *X = 0; ConstantInt *C1 = 0; if (match(Op0, m_And(m_Value(X), m_ConstantInt(C1)))) return BinaryOperator::createAnd(X, ConstantExpr::getAnd(C1, AndRHS)); } @@ -2076,7 +2076,7 @@ cast(ConstantExpr::getNot(RHS)))) return ReplaceInstUsesWith(I, RHS); - ConstantInt *C1; Value *X; + ConstantInt *C1 = 0; Value *X = 0; // (X & C1) | C2 --> (X | C2) & (C1|C2) if (match(Op0, m_And(m_Value(X), m_ConstantInt(C1))) && isOnlyUse(Op0)) { Instruction *Or = BinaryOperator::createOr(X, RHS, Op0->getName()); @@ -2103,7 +2103,8 @@ return NV; } - Value *A, *B; ConstantInt *C1, *C2; + Value *A = 0, *B = 0; + ConstantInt *C1 = 0, *C2 = 0; if (match(Op0, m_And(m_Value(A), m_Value(B)))) if (A == Op1 || B == Op1) // (A & ?) | A --> A @@ -2140,7 +2141,7 @@ // .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0 // replace with V+N. if (C1 == ConstantExpr::getNot(C2)) { - Value *V1, *V2; + Value *V1 = 0, *V2 = 0; if ((C2->getRawValue() & (C2->getRawValue()+1)) == 0 && // C2 == 0+1+ match(A, m_Add(m_Value(V1), m_Value(V2)))) { // Add commutes, try both ways. @@ -2415,9 +2416,9 @@ } // (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 - Value *A, *B; ConstantInt *C1, *C2; - if (match(Op0, m_And(m_Value(A), m_ConstantInt(C1))) && - match(Op1, m_And(m_Value(B), m_ConstantInt(C2))) && + ConstantInt *C1 = 0, *C2 = 0; + if (match(Op0, m_And(m_Value(), m_ConstantInt(C1))) && + match(Op1, m_And(m_Value(), m_ConstantInt(C2))) && ConstantExpr::getAnd(C1, C2)->isNullValue()) return BinaryOperator::createOr(Op0, Op1); From alenhar2 at cs.uiuc.edu Fri Jan 6 13:42:03 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 6 Jan 2006 13:42:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Message-ID: <200601061942.NAA02559@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelDAGToDAG.cpp updated: 1.26 -> 1.27 --- Log message: make 0 codegen much better --- Diffs of the changes: (+4 -0) AlphaISelDAGToDAG.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -u llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.26 llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.27 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.26 Mon Jan 2 15:15:53 2006 +++ llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Fri Jan 6 13:41:51 2006 @@ -241,6 +241,10 @@ } case ISD::Constant: { uint64_t uval = cast(N)->getValue(); + + if (uval == 0) + return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), Alpha::R31, MVT::i64); + int64_t val = (int64_t)uval; int32_t val32 = (int32_t)val; if (val <= IMM_HIGH + IMM_HIGH * IMM_MULT && From evan.cheng at apple.com Fri Jan 6 14:36:33 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 6 Jan 2006 14:36:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200601062036.OAA02913@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.22 -> 1.23 --- Log message: ISEL code for MULHU, MULHS, and UNDEF. --- Diffs of the changes: (+82 -7) X86ISelDAGToDAG.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 82 insertions(+), 7 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.22 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.23 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.22 Thu Jan 5 19:06:31 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Jan 6 14:36:21 2006 @@ -100,6 +100,8 @@ SDOperand &Index, SDOperand &Disp); bool SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale, SDOperand &Index, SDOperand &Disp); + bool TryFoldLoad(SDOperand N, SDOperand &Base, SDOperand &Scale, + SDOperand &Index, SDOperand &Disp); inline void getAddressOperands(X86ISelAddressMode &AM, SDOperand &Base, SDOperand &Scale, SDOperand &Index, @@ -294,8 +296,16 @@ return false; } -static bool isRegister0(SDOperand Op) -{ +bool X86DAGToDAGISel::TryFoldLoad(SDOperand N, SDOperand &Base, + SDOperand &Scale, SDOperand &Index, + SDOperand &Disp) { + if (N.getOpcode() == ISD::LOAD && N.hasOneUse() && + CodeGenMap.count(N.getValue(1))) + return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp); + return false; +} + +static bool isRegister0(SDOperand Op) { if (RegisterSDNode *R = dyn_cast(Op)) return (R->getReg() == 0); return false; @@ -354,14 +364,67 @@ SDOperand X86DAGToDAGISel::Select(SDOperand N) { SDNode *Node = N.Val; MVT::ValueType NVT = Node->getValueType(0); - unsigned Opc; + unsigned Opc, MOpc; + unsigned Opcode = Node->getOpcode(); - if (Node->getOpcode() >= ISD::BUILTIN_OP_END && - Node->getOpcode() < X86ISD::FIRST_NUMBER) + if (Opcode >= ISD::BUILTIN_OP_END && Opcode < X86ISD::FIRST_NUMBER) return N; // Already selected. - switch (Node->getOpcode()) { + switch (Opcode) { default: break; + case ISD::MULHU: + case ISD::MULHS: { + if (Opcode == ISD::MULHU) + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: Opc = X86::MUL8r; MOpc = X86::MUL8m; break; + case MVT::i16: Opc = X86::MUL16r; MOpc = X86::MUL16m; break; + case MVT::i32: Opc = X86::MUL32r; MOpc = X86::MUL32m; break; + } + else + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: Opc = X86::IMUL8r; MOpc = X86::IMUL8m; break; + case MVT::i16: Opc = X86::IMUL16r; MOpc = X86::IMUL16m; break; + case MVT::i32: Opc = X86::IMUL32r; MOpc = X86::IMUL32m; break; + } + + unsigned LoReg, HiReg; + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: LoReg = X86::AL; HiReg = X86::AH; break; + case MVT::i16: LoReg = X86::AX; HiReg = X86::DX; break; + case MVT::i32: LoReg = X86::EAX; HiReg = X86::EDX; break; + } + + SDOperand N0 = Node->getOperand(0); + SDOperand N1 = Node->getOperand(1); + + bool foldedLoad = false; + SDOperand Tmp0, Tmp1, Tmp2, Tmp3; + foldedLoad = TryFoldLoad(N1, Tmp0, Tmp1, Tmp2, Tmp3); + SDOperand Chain = foldedLoad ? Select(N1.getOperand(0)) + : CurDAG->getEntryNode(); + + SDOperand InFlag; + Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT), + Select(N0), InFlag); + InFlag = Chain.getValue(1); + + if (foldedLoad) { + Chain = CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1, + Tmp2, Tmp3, Chain, InFlag); + InFlag = Chain.getValue(1); + } else { + InFlag = CurDAG->getTargetNode(Opc, MVT::Flag, Select(N1), InFlag); + } + + SDOperand Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag); + CodeGenMap[N.getValue(0)] = Result; + CodeGenMap[N.getValue(1)] = Result.getValue(1); + CodeGenMap[N.getValue(2)] = Result.getValue(2); + return Result.getValue(N.ResNo); + } case ISD::TRUNCATE: { unsigned Reg; @@ -387,9 +450,21 @@ Result = CurDAG->getCopyFromReg(Chain, Reg, VT, InFlag); - return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result); + if (N.Val->hasOneUse()) + return CurDAG->SelectNodeTo(N.Val, Opc, VT, Result); + else + return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result); break; } + + case ISD::UNDEF: { + Opc = (NVT == MVT::f64) ? (X86Vector >= SSE2 ? X86::FLD0SD : X86::FpLD0) + : X86::IMPLICIT_DEF; + if (N.Val->hasOneUse()) + return CurDAG->SelectNodeTo(N.Val, Opc, NVT); + else + return CodeGenMap[N] = CurDAG->getTargetNode(Opc, NVT); + } } return SelectCode(N); From evan.cheng at apple.com Fri Jan 6 16:19:56 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 6 Jan 2006 16:19:56 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200601062219.QAA03352@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.126 -> 1.127 --- Log message: Pattern complexity calculation fix. --- Diffs of the changes: (+9 -4) DAGISelEmitter.cpp | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.126 llvm/utils/TableGen/DAGISelEmitter.cpp:1.127 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.126 Thu Jan 5 20:30:23 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Jan 6 16:19:44 2006 @@ -1691,6 +1691,11 @@ /// patterns before small ones. This is used to determine the size of a /// pattern. static unsigned getPatternSize(TreePatternNode *P, DAGISelEmitter &ISE) { + assert(isExtIntegerInVTs(P->getExtTypes()) || + isExtFloatingPointInVTs(P->getExtTypes()) || + P->getExtTypeNum(0) == MVT::isVoid || + P->getExtTypeNum(0) == MVT::Flag && + "Not a valid pattern node to size!"); unsigned Size = 2; // The node itself. // FIXME: This is a hack to statically increase the priority of patterns @@ -1700,7 +1705,7 @@ // calculate the complexity of all patterns a dag can potentially map to. const ComplexPattern *AM = NodeGetComplexPattern(P, ISE); if (AM) - Size += AM->getNumOperands(); + Size += AM->getNumOperands() * 2; // Count children in the count if they are also nodes. for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) { @@ -1708,10 +1713,10 @@ if (!Child->isLeaf() && Child->getExtTypeNum(0) != MVT::Other) Size += getPatternSize(Child, ISE); else if (Child->isLeaf()) { - Size += getPatternSize(Child, ISE); if (dynamic_cast(Child->getLeafValue())) - // Matches a ConstantSDNode. More specific to any immediate. - ++Size; + Size += 3; // Matches a ConstantSDNode. + else if (NodeIsComplexPattern(Child)) + Size += getPatternSize(Child, ISE); } } From bocchino at persephone.cs.uiuc.edu Fri Jan 6 16:49:53 2006 From: bocchino at persephone.cs.uiuc.edu (Robert L. Bocchino Jr.) Date: Fri, 6 Jan 2006 16:49:53 -0600 (CST) Subject: [llvm-commits] CVS: llvm/docs/WritingAnLLVMPass.html Message-ID: <20060106224953.1E4951C9C218@persephone.cs.uiuc.edu> Changes in directory llvm/docs: WritingAnLLVMPass.html updated: 1.42 -> 1.43 --- Log message: Fixed a typo; "= 1" was missing. --- Diffs of the changes: (+2 -2) WritingAnLLVMPass.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/docs/WritingAnLLVMPass.html diff -u llvm/docs/WritingAnLLVMPass.html:1.42 llvm/docs/WritingAnLLVMPass.html:1.43 --- llvm/docs/WritingAnLLVMPass.html:1.42 Mon Nov 28 17:25:41 2005 +++ llvm/docs/WritingAnLLVMPass.html Fri Jan 6 16:49:23 2006 @@ -177,7 +177,7 @@ # Make the shared library become a loadable module so the tools can # dlopen/dlsym on the resulting library. -LOADABLE_MODULE +LOADABLE_MODULE = 1 # Include the makefile implementation stuff include $(LEVEL)/Makefile.common @@ -1593,7 +1593,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/11/28 23:25:41 $ + Last modified: $Date: 2006/01/06 22:49:23 $ From bocchino at persephone.cs.uiuc.edu Fri Jan 6 16:51:49 2006 From: bocchino at persephone.cs.uiuc.edu (Robert L. Bocchino Jr.) Date: Fri, 6 Jan 2006 16:51:49 -0600 (CST) Subject: [llvm-commits] CVS: llvm/projects/sample/lib/sample/Makefile Message-ID: <20060106225149.3B6211C9C23F@persephone.cs.uiuc.edu> Changes in directory llvm/projects/sample/lib/sample: Makefile updated: 1.5 -> 1.6 --- Log message: Fixed Makefile so it does, indeed, build a dynamic library. --- Diffs of the changes: (+2 -1) Makefile | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/projects/sample/lib/sample/Makefile diff -u llvm/projects/sample/lib/sample/Makefile:1.5 llvm/projects/sample/lib/sample/Makefile:1.6 --- llvm/projects/sample/lib/sample/Makefile:1.5 Sat Oct 23 10:30:30 2004 +++ llvm/projects/sample/lib/sample/Makefile Fri Jan 6 16:51:19 2006 @@ -9,7 +9,8 @@ # Give the name of a library. This will build a dynamic version. # LIBRARYNAME=sample -#SHARED_LIBRARY=1 +SHARED_LIBRARY=1 +LOADABLE_MODULE=1 #DONT_BUILD_RELINKED=1 #ARCHIVE_LIBRARY=1 From evan.cheng at apple.com Fri Jan 6 17:19:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 6 Jan 2006 17:19:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200601062319.RAA07495@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.23 -> 1.24 --- Log message: * Added integer div / rem. * Fixed a load folding bug. --- Diffs of the changes: (+98 -4) X86ISelDAGToDAG.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 98 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.23 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.24 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.23 Fri Jan 6 14:36:21 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Jan 6 17:19:29 2006 @@ -300,7 +300,7 @@ SDOperand &Scale, SDOperand &Index, SDOperand &Disp) { if (N.getOpcode() == ISD::LOAD && N.hasOneUse() && - CodeGenMap.count(N.getValue(1))) + CodeGenMap.count(N.getValue(1)) == 0) return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp); return false; } @@ -403,6 +403,15 @@ bool foldedLoad = false; SDOperand Tmp0, Tmp1, Tmp2, Tmp3; foldedLoad = TryFoldLoad(N1, Tmp0, Tmp1, Tmp2, Tmp3); + // MULHU and MULHS are commmutative + if (!foldedLoad) { + foldedLoad = TryFoldLoad(N0, Tmp0, Tmp1, Tmp2, Tmp3); + if (foldedLoad) { + N0 = Node->getOperand(1); + N1 = Node->getOperand(0); + } + } + SDOperand Chain = foldedLoad ? Select(N1.getOperand(0)) : CurDAG->getEntryNode(); @@ -421,9 +430,94 @@ SDOperand Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag); CodeGenMap[N.getValue(0)] = Result; - CodeGenMap[N.getValue(1)] = Result.getValue(1); - CodeGenMap[N.getValue(2)] = Result.getValue(2); - return Result.getValue(N.ResNo); + if (foldedLoad) + CodeGenMap[N1.getValue(1)] = Result.getValue(1); + return Result; + } + + case ISD::SDIV: + case ISD::UDIV: + case ISD::SREM: + case ISD::UREM: { + bool isSigned = Opcode == ISD::SDIV || Opcode == ISD::SREM; + bool isDiv = Opcode == ISD::SDIV || Opcode == ISD::UDIV; + if (!isSigned) + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: Opc = X86::DIV8r; MOpc = X86::DIV8m; break; + case MVT::i16: Opc = X86::DIV16r; MOpc = X86::DIV16m; break; + case MVT::i32: Opc = X86::DIV32r; MOpc = X86::DIV32m; break; + } + else + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: Opc = X86::IDIV8r; MOpc = X86::IDIV8m; break; + case MVT::i16: Opc = X86::IDIV16r; MOpc = X86::IDIV16m; break; + case MVT::i32: Opc = X86::IDIV32r; MOpc = X86::IDIV32m; break; + } + + unsigned LoReg, HiReg; + unsigned ClrOpcode, SExtOpcode; + switch (NVT) { + default: assert(0 && "Unsupported VT!"); + case MVT::i8: + LoReg = X86::AL; HiReg = X86::AH; + ClrOpcode = X86::MOV8ri; + SExtOpcode = X86::CBW; + break; + case MVT::i16: + LoReg = X86::AX; HiReg = X86::DX; + ClrOpcode = X86::MOV16ri; + SExtOpcode = X86::CWD; + break; + case MVT::i32: + LoReg = X86::EAX; HiReg = X86::EDX; + ClrOpcode = X86::MOV32ri; + SExtOpcode = X86::CDQ; + break; + } + + SDOperand N0 = Node->getOperand(0); + SDOperand N1 = Node->getOperand(1); + + bool foldedLoad = false; + SDOperand Tmp0, Tmp1, Tmp2, Tmp3; + foldedLoad = TryFoldLoad(N1, Tmp0, Tmp1, Tmp2, Tmp3); + SDOperand Chain = foldedLoad ? Select(N1.getOperand(0)) + : CurDAG->getEntryNode(); + + SDOperand InFlag; + Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT), + Select(N0), InFlag); + InFlag = Chain.getValue(1); + + if (isSigned) { + // Sign extend the low part into the high part. + InFlag = CurDAG->getTargetNode(SExtOpcode, MVT::Flag, InFlag); + } else { + // Zero out the high part, effectively zero extending the input. + SDOperand ClrNode = + CurDAG->getTargetNode(ClrOpcode, NVT, + CurDAG->getTargetConstant(0, NVT)); + Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(HiReg, NVT), + ClrNode, InFlag); + InFlag = Chain.getValue(1); + } + + if (foldedLoad) { + Chain = CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1, + Tmp2, Tmp3, Chain, InFlag); + InFlag = Chain.getValue(1); + } else { + InFlag = CurDAG->getTargetNode(Opc, MVT::Flag, Select(N1), InFlag); + } + + SDOperand Result = CurDAG->getCopyFromReg(Chain, isDiv ? LoReg : HiReg, + NVT, InFlag); + CodeGenMap[N.getValue(0)] = Result; + if (foldedLoad) + CodeGenMap[N1.getValue(1)] = Result.getValue(1); + return Result; } case ISD::TRUNCATE: { From lattner at cs.uiuc.edu Fri Jan 6 19:32:40 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 19:32:40 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200601070132.TAA09175@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.410 -> 1.411 --- Log message: fix some 176.gcc miscompilation from my previous patch. --- Diffs of the changes: (+33 -7) InstructionCombining.cpp | 40 +++++++++++++++++++++++++++++++++------- 1 files changed, 33 insertions(+), 7 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.410 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.411 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.410 Fri Jan 6 11:59:59 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jan 6 19:32:28 2006 @@ -3669,7 +3669,7 @@ // is a noop cast between the two. bool isShiftOfLeftShift = ShiftOp->getOpcode() == Instruction::Shl; bool isShiftOfSignedShift = ShiftOp->getType()->isSigned(); - bool isShiftOfUnsignedShift = !isSignedShift; + bool isShiftOfUnsignedShift = !isShiftOfSignedShift; ConstantUInt *ShiftAmt1C = cast(ShiftOp->getOperand(1)); @@ -3704,7 +3704,7 @@ if (isLeftShift) C = ConstantExpr::getShl(C, ShiftAmt1C); else - C = ConstantExpr::getShr(C, ShiftAmt1C); // must be an unsigned shr. + C = ConstantExpr::getUShr(C, ShiftAmt1C); Value *Op = ShiftOp->getOperand(0); if (isShiftOfSignedShift != isSignedShift) @@ -3715,17 +3715,43 @@ InsertNewInstBefore(Mask, I); // Figure out what flavor of shift we should use... - if (ShiftAmt1 == ShiftAmt2) + if (ShiftAmt1 == ShiftAmt2) { return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 - else if (ShiftAmt1 < ShiftAmt2) { + } else if (ShiftAmt1 < ShiftAmt2) { return new ShiftInst(I.getOpcode(), Mask, ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); - } else { - return new ShiftInst(ShiftOp->getOpcode(), Mask, + } else if (isShiftOfUnsignedShift || isShiftOfLeftShift) { + if (isShiftOfUnsignedShift && !isShiftOfLeftShift && isSignedShift) { + // Make sure to emit an unsigned shift right, not a signed one. + Mask = InsertNewInstBefore(new CastInst(Mask, + Mask->getType()->getUnsignedVersion(), + Op->getName()), I); + Mask = new ShiftInst(Instruction::Shr, Mask, ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + InsertNewInstBefore(Mask, I); + return new CastInst(Mask, I.getType()); + } else { + return new ShiftInst(ShiftOp->getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + } + } else { + // (X >>s C1) << C2 where C1 > C2 === (X >>s (C1-C2)) & mask + Op = InsertNewInstBefore(new CastInst(Mask, + I.getType()->getSignedVersion(), + Mask->getName()), I); + Instruction *Shift = + new ShiftInst(ShiftOp->getOpcode(), Op, + ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + InsertNewInstBefore(Shift, I); + + C = ConstantIntegral::getAllOnesValue(Shift->getType()); + C = ConstantExpr::getShl(C, Op1); + Mask = BinaryOperator::createAnd(Shift, C, Op->getName()+".mask"); + InsertNewInstBefore(Mask, I); + return new CastInst(Mask, I.getType()); } } else { - // We can handle signed (X << C1) >> C2 if it's a sign extend. In + // We can handle signed (X << C1) >>s C2 if it's a sign extend. In // this case, C1 == C2 and C1 is 8, 16, or 32. if (ShiftAmt1 == ShiftAmt2) { const Type *SExtType = 0; From lattner at cs.uiuc.edu Fri Jan 6 19:37:37 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 6 Jan 2006 19:37:37 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr Message-ID: <200601070137.TAA09221@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2004-06-17-UnorderedCompares.c.tr updated: 1.5 -> 1.6 --- Log message: Modify this test to not depend on the host math.h implementation --- Diffs of the changes: (+12 -13) 2004-06-17-UnorderedCompares.c.tr | 25 ++++++++++++------------- 1 files changed, 12 insertions(+), 13 deletions(-) Index: llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr diff -u llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr:1.5 llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr:1.6 --- llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr:1.5 Tue Nov 8 15:11:32 2005 +++ llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr Fri Jan 6 19:37:25 2006 @@ -1,22 +1,21 @@ // RUN: %llvmgcc -xc -std=c99 %s -c -o - | llvm-dis | grep -v llvm.isunordered | not grep call -// XFAIL: sparc|ia64 #include _Bool A, B, C, D, E, F; void TestF(float X, float Y) { - A = isgreater(X, Y); - B = isgreaterequal(X, Y); - C = isless(X, Y); - D = islessequal(X, Y); - E = islessgreater(X, Y); - F = isunordered(X, Y); + A = __builtin_isgreater(X, Y); + B = __builtin_isgreaterequal(X, Y); + C = __builtin_isless(X, Y); + D = __builtin_islessequal(X, Y); + E = __builtin_islessgreater(X, Y); + F = __builtin_isunordered(X, Y); } void TestD(double X, double Y) { - A = isgreater(X, Y); - B = isgreaterequal(X, Y); - C = isless(X, Y); - D = islessequal(X, Y); - E = islessgreater(X, Y); - F = isunordered(X, Y); + A = __builtin_isgreater(X, Y); + B = __builtin_isgreaterequal(X, Y); + C = __builtin_isless(X, Y); + D = __builtin_islessequal(X, Y); + E = __builtin_islessgreater(X, Y); + F = __builtin_isunordered(X, Y); } From lattner at cs.uiuc.edu Sat Jan 7 00:12:19 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Jan 2006 00:12:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JIT.cpp Message-ID: <200601070612.AAA10447@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JIT.cpp updated: 1.58 -> 1.59 --- Log message: wrap long line --- Diffs of the changes: (+2 -1) JIT.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/ExecutionEngine/JIT/JIT.cpp diff -u llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.58 llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.59 --- llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.58 Thu Jul 28 07:44:13 2005 +++ llvm/lib/ExecutionEngine/JIT/JIT.cpp Sat Jan 7 00:12:07 2006 @@ -294,7 +294,8 @@ // actually initialize the global after current function has finished // compilation. uint64_t S = getTargetData().getTypeSize(GV->getType()->getElementType()); - unsigned char A = getTargetData().getTypeAlignment(GV->getType()->getElementType()); + unsigned char A = + getTargetData().getTypeAlignment(GV->getType()->getElementType()); Ptr = MCE->allocateGlobal(S, A); state.getPendingGlobals(locked).push_back(GV); } From lattner at cs.uiuc.edu Sat Jan 7 00:21:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Jan 2006 00:21:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Message-ID: <200601070621.AAA10533@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JITEmitter.cpp updated: 1.76 -> 1.77 --- Log message: Wrap long lines. --- Diffs of the changes: (+8 -6) JITEmitter.cpp | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) Index: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp diff -u llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.76 llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.77 --- llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.76 Mon Aug 1 12:35:40 2005 +++ llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Sat Jan 7 00:20:51 2006 @@ -105,8 +105,8 @@ } JITMemoryManager::~JITMemoryManager() { - for (std::list::iterator ib = Blocks.begin(), ie = Blocks.end(); - ib != ie; ++ib) + for (std::list::iterator ib = Blocks.begin(), + ie = Blocks.end(); ib != ie; ++ib) sys::Memory::ReleaseRWX(*ib); Blocks.clear(); } @@ -352,14 +352,15 @@ // a little bit after the stub. As such, use upper_bound to find it. std::map::iterator I = JR.state.getStubToFunctionMap(locked).upper_bound(Stub); - assert(I != JR.state.getStubToFunctionMap(locked).begin() && "This is not a known stub!"); + assert(I != JR.state.getStubToFunctionMap(locked).begin() && + "This is not a known stub!"); Function *F = (--I)->second; // We might like to remove the stub from the StubToFunction map. // We can't do that! Multiple threads could be stuck, waiting to acquire the // lock above. As soon as the 1st function finishes compiling the function, - // the next one will be released, and needs to be able to find the function it needs - // to call. + // the next one will be released, and needs to be able to find the function it + // needs to call. //JR.state.getStubToFunctionMap(locked).erase(I); DEBUG(std::cerr << "JIT: Lazily resolving function '" << F->getName() @@ -534,7 +535,8 @@ MR.setGOTIndex(idx); if (((void**)MemMgr.getGOTBase())[idx] != ResultPtr) { DEBUG(std::cerr << "GOT was out of date for " << ResultPtr - << " pointing at " << ((void**)MemMgr.getGOTBase())[idx] << "\n"); + << " pointing at " << ((void**)MemMgr.getGOTBase())[idx] + << "\n"); ((void**)MemMgr.getGOTBase())[idx] = ResultPtr; } } From lattner at cs.uiuc.edu Sat Jan 7 00:22:28 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Jan 2006 00:22:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Message-ID: <200601070622.AAA10599@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCCodeEmitter.cpp updated: 1.42 -> 1.43 --- Log message: Fix the PPC JIT failures last night, which were due to mishandling of linkonce globals --- Diffs of the changes: (+1 -0) PPCCodeEmitter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.42 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.43 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.42 Sun Dec 11 01:37:41 2005 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Sat Jan 7 00:22:16 2006 @@ -194,6 +194,7 @@ } else if (MO.isGlobalAddress() || MO.isExternalSymbol()) { bool isExternal = MO.isExternalSymbol() || MO.getGlobal()->hasWeakLinkage() || + MO.getGlobal()->hasLinkOnceLinkage() || MO.getGlobal()->isExternal(); unsigned Reloc = 0; if (MI.getOpcode() == PPC::BL) From lattner at cs.uiuc.edu Sat Jan 7 17:17:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Jan 2006 17:17:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/PassManagerT.h Message-ID: <200601072317.RAA21824@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.63 -> 1.64 --- Log message: Patch #7 from Saem: "added the asserts and casts, fixed the comments and started the break down of the larger methods. A few more patches and the breakdown should be complete." --- Diffs of the changes: (+37 -36) PassManagerT.h | 73 ++++++++++++++++++++++++++++----------------------------- 1 files changed, 37 insertions(+), 36 deletions(-) Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.63 llvm/lib/VMCore/PassManagerT.h:1.64 --- llvm/lib/VMCore/PassManagerT.h:1.63 Wed Jan 4 01:47:13 2006 +++ llvm/lib/VMCore/PassManagerT.h Sat Jan 7 17:16:58 2006 @@ -123,8 +123,6 @@ static TimingInfo *TheTimeInfo; -// FIXME:I'm not sure if this is the best way, but this was the only way I -// could get around the recursive template issues. -- Saem struct BBTraits { typedef BasicBlock UnitType; @@ -138,7 +136,7 @@ typedef BasicBlockPassManager SubPassClass; // BatcherClass - The type to use for collation of subtypes... This class is - // never instantiated for the PassManager, but it must be an + // never instantiated for the BasicBlockPassManager, but it must be an // instance of PassClass to typecheck. // typedef PassClass BatcherClass; @@ -287,7 +285,10 @@ LastUserOf[I->second].push_back(I->first); // Output debug information... - if (Parent == 0) PMDebug::PerformPassStartupStuff((dynamic_cast(this))); + assert(dynamic_cast(this) && + "It wasn't the PassClass I thought it was"); + if (Parent == 0) + PMDebug::PerformPassStartupStuff((dynamic_cast(this))); // Run all of the passes for (unsigned i = 0, e = Passes.size(); i < e; ++i) { @@ -491,6 +492,8 @@ // frees the analysis AFTER this pass manager runs. // if (Parent) { + assert(dynamic_cast(this) && + "It wasn't the Pass type I thought it was."); Parent->markPassUsed(P, dynamic_cast(this)); } else { assert(getAnalysisOrNullUp(P) && @@ -508,6 +511,7 @@ } virtual unsigned getNumContainedPasses() const { return Passes.size(); } + virtual const Pass *getContainedPass(unsigned N) const { assert(N < Passes.size() && "Pass number out of range!"); return Passes[N]; @@ -522,24 +526,16 @@ // Get information about what analyses the pass uses... AnalysisUsage AnUsage; P->getAnalysisUsage(AnUsage); - const std::vector &Required = AnUsage.getRequiredSet(); - - // Loop over all of the analyses used by this pass, - for (std::vector::const_iterator I = Required.begin(), - E = Required.end(); I != E; ++I) { - if (getAnalysisOrNullDown(*I) == 0) { - Pass *AP = (*I)->createPass(); - if (ImmutablePass *IP = dynamic_cast (AP)) { add(IP); } - else if (PassClass *RP = dynamic_cast (AP)) { add(RP); } - else { assert (0 && "Wrong kind of pass for this PassManager"); } - } - } - + + addRequiredPasses(AnUsage.getRequiredSet()); + // Tell the pass to add itself to this PassManager... the way it does so // depends on the class of the pass, and is critical to laying out passes in // an optimal order.. // - P->addToPassManager(dynamic_cast(this), AnUsage); + assert(dynamic_cast(this) && + "It wasn't the right passmanager type."); + P->addToPassManager(static_cast(this), AnUsage); } // add - H4x0r an ImmutablePass into a PassManager that might not be @@ -549,19 +545,9 @@ // Get information about what analyses the pass uses... AnalysisUsage AnUsage; P->getAnalysisUsage(AnUsage); - const std::vector &Required = AnUsage.getRequiredSet(); - - // Loop over all of the analyses used by this pass, - for (std::vector::const_iterator I = Required.begin(), - E = Required.end(); I != E; ++I) { - if (getAnalysisOrNullDown(*I) == 0) { - Pass *AP = (*I)->createPass(); - if (ImmutablePass *IP = dynamic_cast (AP)) add(IP); - else if (PassClass *RP = dynamic_cast (AP)) add(RP); - else assert (0 && "Wrong kind of pass for this PassManager"); - } - } - + + addRequiredPasses(AnUsage.getRequiredSet()); + // Add the ImmutablePass to this PassManager. addPass(P, AnUsage); } @@ -581,11 +567,10 @@ const std::vector &RequiredSet = AnUsage.getRequiredSet(); // FIXME: If this pass being added isn't killed by any of the passes in the - // batcher class then we can reorder to pass to execute before the batcher + // batcher class then we can reorder the pass to execute before the batcher // does, which will potentially allow us to batch more passes! // - // const std::vector &ProvidedSet = AnUsage.getProvidedSet(); - if (Batcher /*&& ProvidedSet.empty()*/) + if (Batcher) closeBatcher(); // This pass cannot be batched! // Set the Resolver instance variable in the Pass so that it knows where to @@ -638,8 +623,13 @@ // together a function at a time. // void addPass(SubPassClass *MP, AnalysisUsage &AnUsage) { - if (Batcher == 0) // If we don't have a batcher yet, make one now. - Batcher = new BatcherClass((dynamic_cast(this))); + + if (Batcher == 0) { // If we don't have a batcher yet, make one now. + assert(dynamic_cast(this) && + "It wasn't the PassManager type I thought it was"); + Batcher = new BatcherClass((static_cast(this))); + } + // The Batcher will queue the passes up MP->addToPassManager(Batcher, AnUsage); } @@ -652,6 +642,17 @@ } } + void addRequiredPasses(const std::vector &Required) { + for (std::vector::const_iterator I = Required.begin(), + E = Required.end(); I != E; ++I) { + if (getAnalysisOrNullDown(*I) == 0) { + Pass *AP = (*I)->createPass(); + if (ImmutablePass *IP = dynamic_cast (AP)) add(IP); + else if (PassClass *RP = dynamic_cast (AP)) add(RP); + else assert (0 && "Wrong kind of pass for this PassManager"); + } + } + } public: // When an ImmutablePass is added, it gets added to the top level pass // manager. From lattner at cs.uiuc.edu Sat Jan 7 20:33:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 7 Jan 2006 20:33:04 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Module.h Message-ID: <200601080233.UAA22603@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Module.h updated: 1.65 -> 1.66 --- Log message: Fix out of date comments, patch by Marco Matthies. --- Diffs of the changes: (+2 -4) Module.h | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.65 llvm/include/llvm/Module.h:1.66 --- llvm/include/llvm/Module.h:1.65 Sun Dec 4 23:30:21 2005 +++ llvm/include/llvm/Module.h Sat Jan 7 20:32:52 2006 @@ -74,10 +74,8 @@ std::string ModuleID; // Human readable identifier for the module std::string TargetTriple; // Platform target triple Module compiled on - // These flags are probably not the right long-term way to handle this kind of - // target information, but it is sufficient for now. - Endianness Endian; // True if target is little endian - PointerSize PtrSize; // True if target has 32-bit pointers (false = 64-bit) + Endianness Endian; // Endianness assumed in the module + PointerSize PtrSize; // Pointer size assumed in the module friend class Constant; From lattner at cs.uiuc.edu Sun Jan 8 02:20:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 8 Jan 2006 02:20:10 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ET-Forest.h Dominators.h PostDominators.h Message-ID: <200601080820.CAA28864@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ET-Forest.h added (r1.1) Dominators.h updated: 1.51 -> 1.52 PostDominators.h updated: 1.9 -> 1.10 --- Log message: Initial implementation of the ET-Forest data structure for dominators and post-dominators. This code was written/adapted by Daniel Berlin! --- Diffs of the changes: (+447 -1) Dominators.h | 116 ++++++++++++++++++++ ET-Forest.h | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ PostDominators.h | 23 ++++ 3 files changed, 447 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Analysis/ET-Forest.h diff -c /dev/null llvm/include/llvm/Analysis/ET-Forest.h:1.1 *** /dev/null Sun Jan 8 02:20:08 2006 --- llvm/include/llvm/Analysis/ET-Forest.h Sun Jan 8 02:19:58 2006 *************** *** 0 **** --- 1,309 ---- + //===- llvm/Analysis/ET-Forest.h - ET-Forest implementation -----*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was written by Daniel Berlin from code written by Pavel Nejedy, and + // is distributed under the University of Illinois Open Source License. See + // LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines the following classes: + // 1. ETNode: A node in the ET forest. + // 2. ETOccurrence: An occurrence of the node in the splay tree + // storing the DFS path information. + // + // The ET-forest structure is described in: + // D. D. Sleator and R. E. Tarjan. A data structure for dynamic trees. + // J. G'omput. System Sci., 26(3):362 381, 1983. + // + // Basically, the ET-Forest is storing the dominator tree (ETNode), + // and a splay tree containing the depth first path information for + // those nodes (ETOccurrence). This enables us to answer queries + // about domination (DominatedBySlow), and ancestry (NCA) in + // logarithmic time, and perform updates to the information in + // logarithmic time. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_ANALYSIS_ETFOREST_H + #define LLVM_ANALYSIS_ETFOREST_H + + #include + + namespace llvm { + class ETNode; + + /// ETOccurrence - An occurrence for a node in the et tree + /// + /// The et occurrence tree is really storing the sequences you get from + /// doing a DFS over the ETNode's. It is stored as a modified splay + /// tree. + /// ET occurrences can occur at multiple places in the ordering depending + /// on how many ET nodes have it as their father. To handle + /// this, they are separate from the nodes. + /// + class ETOccurrence { + public: + ETOccurrence(ETNode *n): OccFor(n), Parent(NULL), Left(NULL), Right(NULL), + Depth(0), Min(0), MinOccurrence(this) {}; + + void setParent(ETOccurrence *n) { + Parent = n; + } + + // Add D to our current depth + void setDepthAdd(int d) { + Min += d; + Depth += d; + } + + // Reset our depth to D + void setDepth(int d) { + Min += d - Depth; + Depth = d; + } + + // Set Left to N + void setLeft(ETOccurrence *n) { + assert(n != this && "Trying to set our left to ourselves"); + Left = n; + if (n) + n->setParent(this); + } + + // Set Right to N + void setRight(ETOccurrence *n) { + assert(n != this && "Trying to set our right to ourselves"); + Right = n; + if (n) + n->setParent(this); + } + + // Splay us to the root of the tree + void Splay(void); + + // Recompute the minimum occurrence for this occurrence. + void recomputeMin(void) { + ETOccurrence *themin = Left; + + // The min may be our Right, too. + if (!themin || (Right && themin->Min > Right->Min)) + themin = Right; + + if (themin && themin->Min < 0) { + Min = themin->Min + Depth; + MinOccurrence = themin->MinOccurrence; + } else { + Min = Depth; + MinOccurrence = this; + } + } + private: + friend class ETNode; + + // Node we represent + ETNode *OccFor; + + // Parent in the splay tree + ETOccurrence *Parent; + + // Left Son in the splay tree + ETOccurrence *Left; + + // Right Son in the splay tree + ETOccurrence *Right; + + // Depth of the node is the sum of the depth on the path to the + // root. + int Depth; + + // Subtree occurrence's minimum depth + int Min; + + // Subtree occurrence with minimum depth + ETOccurrence *MinOccurrence; + }; + + + class ETNode { + public: + ETNode(void *d) : data(d), Father(NULL), Left(NULL), + Right(NULL), Son(NULL), ParentOcc(NULL) { + RightmostOcc = new ETOccurrence(this); + }; + + // This does *not* maintain the tree structure. + // If you want to remove a node from the forest structure, use + // removeFromForest() + ~ETNode() { + delete RightmostOcc; + } + + void removeFromForest() { + // Split us away from all our sons. + while (Son) + Son->Split(); + + // And then split us away from our father. + if (Father) + Father->Split(); + } + + // Split us away from our parents and children, so that we can be + // reparented. NB: setFather WILL NOT DO WHAT YOU WANT IF YOU DO NOT + // SPLIT US FIRST. + void Split(); + + // Set our parent node to the passed in node + void setFather(ETNode *); + + // Nearest Common Ancestor of two et nodes. + ETNode *NCA(ETNode *); + + // Return true if we are below the passed in node in the forest. + bool Below(ETNode *); + /* + Given a dominator tree, we can determine whether one thing + dominates another in constant time by using two DFS numbers: + + 1. The number for when we visit a node on the way down the tree + 2. The number for when we visit a node on the way back up the tree + + You can view these as bounds for the range of dfs numbers the + nodes in the subtree of the dominator tree rooted at that node + will contain. + + The dominator tree is always a simple acyclic tree, so there are + only three possible relations two nodes in the dominator tree have + to each other: + + 1. Node A is above Node B (and thus, Node A dominates node B) + + A + | + C + / \ + B D + + + In the above case, DFS_Number_In of A will be <= DFS_Number_In of + B, and DFS_Number_Out of A will be >= DFS_Number_Out of B. This is + because we must hit A in the dominator tree *before* B on the walk + down, and we will hit A *after* B on the walk back up + + 2. Node A is below node B (and thus, node B dominates node B) + + B + | + A + / \ + C D + + In the above case, DFS_Number_In of A will be >= DFS_Number_In of + B, and DFS_Number_Out of A will be <= DFS_Number_Out of B. + + This is because we must hit A in the dominator tree *after* B on + the walk down, and we will hit A *before* B on the walk back up + + 3. Node A and B are siblings (and thus, neither dominates the other) + + C + | + D + / \ + A B + + In the above case, DFS_Number_In of A will *always* be <= + DFS_Number_In of B, and DFS_Number_Out of A will *always* be <= + DFS_Number_Out of B. This is because we will always finish the dfs + walk of one of the subtrees before the other, and thus, the dfs + numbers for one subtree can't intersect with the range of dfs + numbers for the other subtree. If you swap A and B's position in + the dominator tree, the comparison changes direction, but the point + is that both comparisons will always go the same way if there is no + dominance relationship. + + Thus, it is sufficient to write + + A_Dominates_B(node A, node B) { + return DFS_Number_In(A) <= DFS_Number_In(B) && + DFS_Number_Out(A) >= DFS_Number_Out(B); + } + + A_Dominated_by_B(node A, node B) { + return DFS_Number_In(A) >= DFS_Number_In(A) && + DFS_Number_Out(A) <= DFS_Number_Out(B); + } + */ + bool DominatedBy(ETNode *other) const { + return this->DFSNumIn >= other->DFSNumIn && + this->DFSNumOut <= other->DFSNumOut; + } + + // This method is slower, but doesn't require the DFS numbers to + // be up to date. + bool DominatedBySlow(ETNode *other) { + return this->Below(other); + } + + void assignDFSNumber(int &num) { + DFSNumIn = num++; + + if (Son) { + Son->assignDFSNumber(num); + for (ETNode *son = Son->Right; son != Son; son = son->Right) + son->assignDFSNumber(num); + } + DFSNumOut = num++; + } + + bool hasFather() const { + return Father != NULL; + } + + // Do not let people play around with fathers. + const ETNode *getFather() const { + return Father; + } + + template + T *getData() const { + return static_cast(data); + } + + unsigned getDFSNumIn() const { + return DFSNumIn; + } + + unsigned getDFSNumOut() const { + return DFSNumOut; + } + + private: + // Data represented by the node + void *data; + + // DFS Numbers + unsigned DFSNumIn, DFSNumOut; + + // Father + ETNode *Father; + + // Brothers. Node, this ends up being a circularly linked list. + // Thus, if you want to get all the brothers, you need to stop when + // you hit node == this again. + ETNode *Left, *Right; + + // First Son + ETNode *Son; + + // Rightmost occurrence for this node + ETOccurrence *RightmostOcc; + + // Parent occurrence for this node + ETOccurrence *ParentOcc; + }; + } // end llvm namespace + + #endif Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.51 llvm/include/llvm/Analysis/Dominators.h:1.52 --- llvm/include/llvm/Analysis/Dominators.h:1.51 Mon Nov 28 19:07:12 2005 +++ llvm/include/llvm/Analysis/Dominators.h Sun Jan 8 02:19:58 2006 @@ -13,7 +13,9 @@ // 2. DominatorSet: Calculates the [reverse] dominator set for a function // 3. DominatorTree: Represent the ImmediateDominator as an explicit tree // structure. -// 4. DominanceFrontier: Calculate and hold the dominance frontier for a +// 4. ETForest: Efficient data structure for dominance comparisons and +// nearest-common-ancestor queries. +// 5. DominanceFrontier: Calculate and hold the dominance frontier for a // function. // // These data structures are listed in increasing order of complexity. It @@ -25,6 +27,7 @@ #ifndef LLVM_ANALYSIS_DOMINATORS_H #define LLVM_ANALYSIS_DOMINATORS_H +#include "llvm/Analysis/ET-Forest.h" #include "llvm/Pass.h" #include @@ -389,6 +392,116 @@ //===------------------------------------- +/// ET-Forest Class - Class used to construct forwards and backwards +/// ET-Forests +/// +struct ETForestBase : public DominatorBase { + ETForestBase(bool isPostDom) : DominatorBase(isPostDom), Nodes(), + DFSInfoValid(false) {} + + virtual void releaseMemory() { reset(); } + + typedef std::map ETMapType; + + + /// dominates - Return true if A dominates B. + /// + inline bool dominates(BasicBlock *A, BasicBlock *B) const { + if (A == B) + return true; + + ETNode *NodeA = getNode(A); + ETNode *NodeB = getNode(B); + + if (DFSInfoValid) + return NodeB->DominatedBy(NodeA); + else + return NodeB->DominatedBySlow(NodeA); + } + + /// properlyDominates - Return true if A dominates B and A != B. + /// + bool properlyDominates(BasicBlock *A, BasicBlock *B) const { + return dominates(A, B) && A != B; + } + + /// Return the nearest common dominator of A and B. + BasicBlock *nearestCommonDominator(BasicBlock *A, BasicBlock *B) const { + ETNode *NodeA = getNode(A); + ETNode *NodeB = getNode(B); + + ETNode *Common = NodeA->NCA(NodeB); + if (!Common) + return NULL; + return Common->getData(); + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + } + //===--------------------------------------------------------------------===// + // API to update Forest information based on modifications + // to the CFG... + + /// addNewBlock - Add a new block to the CFG, with the specified immediate + /// dominator. + /// + void addNewBlock(BasicBlock *BB, BasicBlock *IDom); + + /// setImmediateDominator - Update the immediate dominator information to + /// change the current immediate dominator for the specified block + /// to another block. This method requires that BB for NewIDom + /// already have an ETNode, otherwise just use addNewBlock. + /// + void setImmediateDominator(BasicBlock *BB, BasicBlock *NewIDom); + /// print - Convert to human readable form + /// + virtual void print(std::ostream &OS, const Module* = 0) const; +protected: + /// getNode - return the (Post)DominatorTree node for the specified basic + /// block. This is the same as using operator[] on this class. + /// + inline ETNode *getNode(BasicBlock *BB) const { + ETMapType::const_iterator i = Nodes.find(BB); + return (i != Nodes.end()) ? i->second : 0; + } + + inline ETNode *operator[](BasicBlock *BB) const { + return getNode(BB); + } + + void reset(); + ETMapType Nodes; + bool DFSInfoValid; + +}; + +//==------------------------------------- +/// ETForest Class - Concrete subclass of ETForestBase that is used to +/// compute a forwards ET-Forest. + +struct ETForest : public ETForestBase { + ETForest() : ETForestBase(false) {} + + BasicBlock *getRoot() const { + assert(Roots.size() == 1 && "Should always have entry node!"); + return Roots[0]; + } + + virtual bool runOnFunction(Function &F) { + reset(); // Reset from the last time we were run... + ImmediateDominators &ID = getAnalysis(); + Roots = ID.getRoots(); + calculate(ID); + return false; + } + + void calculate(const ImmediateDominators &ID); + ETNode *getNodeForBlock(BasicBlock *BB); +}; + +//===------------------------------------- /// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to /// compute a normal dominator tree. /// @@ -518,6 +631,7 @@ const DominatorTree::Node *Node); }; + // Make sure that any clients of this file link in Dominators.cpp static IncludeFile DOMINATORS_INCLUDE_FILE((void*)&DominatorSet::stub); Index: llvm/include/llvm/Analysis/PostDominators.h diff -u llvm/include/llvm/Analysis/PostDominators.h:1.9 llvm/include/llvm/Analysis/PostDominators.h:1.10 --- llvm/include/llvm/Analysis/PostDominators.h:1.9 Thu Apr 21 15:16:32 2005 +++ llvm/include/llvm/Analysis/PostDominators.h Sun Jan 8 02:19:58 2006 @@ -84,6 +84,29 @@ }; +/// PostETForest Class - Concrete subclass of ETForestBase that is used to +/// compute a forwards post-dominator ET-Forest. +struct PostETForest : public ETForestBase { + PostETForest() : ETForestBase(true) {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + } + + virtual bool runOnFunction(Function &F) { + reset(); // Reset from the last time we were run... + ImmediatePostDominators &ID = getAnalysis(); + Roots = ID.getRoots(); + calculate(ID); + return false; + } + + void calculate(const ImmediatePostDominators &ID); + ETNode *getNodeForBlock(BasicBlock *BB); +}; + + /// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is /// used to compute the a post-dominance frontier. /// From lattner at cs.uiuc.edu Sun Jan 8 02:20:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 8 Jan 2006 02:20:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200601080820.CAA29120@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.65 -> 1.66 --- Log message: Initial implementation of the ET-Forest data structure for dominators and post-dominators. This code was written/adapted by Daniel Berlin! --- Diffs of the changes: (+443 -0) Dominators.cpp | 443 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 443 insertions(+) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.65 llvm/lib/VMCore/Dominators.cpp:1.66 --- llvm/lib/VMCore/Dominators.cpp:1.65 Mon Dec 26 02:35:06 2005 +++ llvm/lib/VMCore/Dominators.cpp Sun Jan 8 02:20:27 2006 @@ -472,3 +472,446 @@ } } +//===----------------------------------------------------------------------===// +// ETOccurrence Implementation +//===----------------------------------------------------------------------===// + +void ETOccurrence::Splay() { + ETOccurrence *father; + ETOccurrence *grandfather; + int occdepth; + int fatherdepth; + + while (Parent) { + occdepth = Depth; + + father = Parent; + fatherdepth = Parent->Depth; + grandfather = father->Parent; + + // If we have no grandparent, a single zig or zag will do. + if (!grandfather) { + setDepthAdd(fatherdepth); + MinOccurrence = father->MinOccurrence; + Min = father->Min; + + // See what we have to rotate + if (father->Left == this) { + // Zig + father->setLeft(Right); + setRight(father); + if (father->Left) + father->Left->setDepthAdd(occdepth); + } else { + // Zag + father->setRight(Left); + setLeft(father); + if (father->Right) + father->Right->setDepthAdd(occdepth); + } + father->setDepth(-occdepth); + Parent = NULL; + + father->recomputeMin(); + return; + } + + // If we have a grandfather, we need to do some + // combination of zig and zag. + int grandfatherdepth = grandfather->Depth; + + setDepthAdd(fatherdepth + grandfatherdepth); + MinOccurrence = grandfather->MinOccurrence; + Min = grandfather->Min; + + ETOccurrence *greatgrandfather = grandfather->Parent; + + if (grandfather->Left == father) { + if (father->Left == this) { + // Zig zig + grandfather->setLeft(father->Right); + father->setLeft(Right); + setRight(father); + father->setRight(grandfather); + + father->setDepth(-occdepth); + + if (father->Left) + father->Left->setDepthAdd(occdepth); + + grandfather->setDepth(-fatherdepth); + if (grandfather->Left) + grandfather->Left->setDepthAdd(fatherdepth); + } else { + // Zag zig + grandfather->setLeft(Right); + father->setRight(Left); + setLeft(father); + setRight(grandfather); + + father->setDepth(-occdepth); + if (father->Right) + father->Right->setDepthAdd(occdepth); + grandfather->setDepth(-occdepth - fatherdepth); + if (grandfather->Left) + grandfather->Left->setDepthAdd(occdepth + fatherdepth); + } + } else { + if (father->Left == this) { + // Zig zag + grandfather->setRight(Left); + father->setLeft(Right); + setLeft(grandfather); + setRight(father); + + father->setDepth(-occdepth); + if (father->Left) + father->Left->setDepthAdd(occdepth); + grandfather->setDepth(-occdepth - fatherdepth); + if (grandfather->Right) + grandfather->Right->setDepthAdd(occdepth + fatherdepth); + } else { // Zag Zag + grandfather->setRight(father->Left); + father->setRight(Left); + setLeft(father); + father->setLeft(grandfather); + + father->setDepth(-occdepth); + if (father->Right) + father->Right->setDepthAdd(occdepth); + grandfather->setDepth(-fatherdepth); + if (grandfather->Right) + grandfather->Right->setDepthAdd(fatherdepth); + } + } + + // Might need one more rotate depending on greatgrandfather. + setParent(greatgrandfather); + if (greatgrandfather) { + if (greatgrandfather->Left == grandfather) + greatgrandfather->Left = this; + else + greatgrandfather->Right = this; + + } + grandfather->recomputeMin(); + father->recomputeMin(); + } +} + +//===----------------------------------------------------------------------===// +// ETNode implementation +//===----------------------------------------------------------------------===// + +void ETNode::Split() { + ETOccurrence *right, *left; + ETOccurrence *rightmost = RightmostOcc; + ETOccurrence *parent; + + // Update the occurrence tree first. + RightmostOcc->Splay(); + + // Find the leftmost occurrence in the rightmost subtree, then splay + // around it. + for (right = rightmost->Right; rightmost->Left; rightmost = rightmost->Left); + + right->Splay(); + + // Start splitting + right->Left->Parent = NULL; + parent = ParentOcc; + parent->Splay(); + ParentOcc = NULL; + + left = parent->Left; + parent->Right->Parent = NULL; + + right->setLeft(left); + + right->recomputeMin(); + + rightmost->Splay(); + rightmost->Depth = 0; + rightmost->Min = 0; + + delete parent; + + // Now update *our* tree + + if (Father->Son == this) + Father->Son = Right; + + if (Father->Son == this) + Father->Son = NULL; + else { + Left->Right = Right; + Right->Left = Left; + } + Left = Right = NULL; + Father = NULL; +} + +void ETNode::setFather(ETNode *NewFather) { + ETOccurrence *rightmost; + ETOccurrence *leftpart; + ETOccurrence *NewFatherOcc; + ETOccurrence *temp; + + // First update the path in the splay tree + NewFatherOcc = new ETOccurrence(NewFather); + + rightmost = NewFather->RightmostOcc; + rightmost->Splay(); + + leftpart = rightmost->Left; + + temp = RightmostOcc; + temp->Splay(); + + NewFatherOcc->setLeft(leftpart); + NewFatherOcc->setRight(temp); + + temp->Depth++; + temp->Min++; + NewFatherOcc->recomputeMin(); + + rightmost->setLeft(NewFatherOcc); + + if (NewFatherOcc->Min + rightmost->Depth < rightmost->Min) { + rightmost->Min = NewFatherOcc->Min + rightmost->Depth; + rightmost->MinOccurrence = NewFatherOcc->MinOccurrence; + } + + ParentOcc = NewFatherOcc; + + // Update *our* tree + ETNode *left; + ETNode *right; + + Father = NewFather; + right = Father->Son; + + if (right) + left = right->Left; + else + left = right = this; + + left->Right = this; + right->Left = this; + Left = left; + Right = right; + + Father->Son = this; +} + +bool ETNode::Below(ETNode *other) { + ETOccurrence *up = other->RightmostOcc; + ETOccurrence *down = RightmostOcc; + + if (this == other) + return true; + + up->Splay(); + + ETOccurrence *left, *right; + left = up->Left; + right = up->Right; + + if (!left) + return false; + + left->Parent = NULL; + + if (right) + right->Parent = NULL; + + down->Splay(); + + if (left == down || left->Parent != NULL) { + if (right) + right->Parent = up; + up->setLeft(down); + } else { + left->Parent = up; + + // If the two occurrences are in different trees, put things + // back the way they were. + if (right && right->Parent != NULL) + up->setRight(down); + else + up->setRight(right); + return false; + } + + if (down->Depth <= 0) + return false; + + return !down->Right || down->Right->Min + down->Depth >= 0; +} + +ETNode *ETNode::NCA(ETNode *other) { + ETOccurrence *occ1 = RightmostOcc; + ETOccurrence *occ2 = other->RightmostOcc; + + ETOccurrence *left, *right, *ret; + ETOccurrence *occmin; + int mindepth; + + if (this == other) + return this; + + occ1->Splay(); + left = occ1->Left; + right = occ1->Right; + + if (left) + left->Parent = NULL; + + if (right) + right->Parent = NULL; + occ2->Splay(); + + if (left == occ2 || (left && left->Parent != NULL)) { + ret = occ2->Right; + + occ1->setLeft(occ2); + if (right) + right->Parent = occ1; + } else { + ret = occ2->Left; + + occ1->setRight(occ2); + if (left) + left->Parent = occ1; + } + + if (occ2->Depth > 0) { + occmin = occ1; + mindepth = occ1->Depth; + } else { + occmin = occ2; + mindepth = occ2->Depth + occ1->Depth; + } + + if (ret && ret->Min + occ1->Depth + occ2->Depth < mindepth) + return ret->MinOccurrence->OccFor; + else + return occmin->OccFor; +} + +//===----------------------------------------------------------------------===// +// ETForest implementation +//===----------------------------------------------------------------------===// + +static RegisterAnalysis +D("etforest", "ET Forest Construction", true); + +void ETForestBase::reset() { + for (ETMapType::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) + delete I->second; + Nodes.clear(); +} + +ETNode *ETForest::getNodeForBlock(BasicBlock *BB) { + ETNode *&BBNode = Nodes[BB]; + if (BBNode) return BBNode; + + // Haven't calculated this node yet? Get or calculate the node for the + // immediate dominator. + BasicBlock *IDom = getAnalysis()[BB]; + + // If we are unreachable, we may not have an immediate dominator. + if (!IDom) + return BBNode = new ETNode(BB); + else { + ETNode *IDomNode = getNodeForBlock(IDom); + + // Add a new tree node for this BasicBlock, and link it as a child of + // IDomNode + BBNode = new ETNode(BB); + BBNode->setFather(IDomNode); + return BBNode; + } +} + +void ETForest::calculate(const ImmediateDominators &ID) { + assert(Roots.size() == 1 && "ETForest should have 1 root block!"); + BasicBlock *Root = Roots[0]; + Nodes[Root] = new ETNode(Root); // Add a node for the root + + Function *F = Root->getParent(); + // Loop over all of the reachable blocks in the function... + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) + if (BasicBlock *ImmDom = ID.get(I)) { // Reachable block. + ETNode *&BBNode = Nodes[I]; + if (!BBNode) { // Haven't calculated this node yet? + // Get or calculate the node for the immediate dominator + ETNode *IDomNode = getNodeForBlock(ImmDom); + + // Add a new ETNode for this BasicBlock, and set it's parent + // to it's immediate dominator. + BBNode = new ETNode(I); + BBNode->setFather(IDomNode); + } + } + + int dfsnum = 0; + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { + if (!getNodeForBlock(I)->hasFather()) + getNodeForBlock(I)->assignDFSNumber(dfsnum); + } + DFSInfoValid = true; +} + +//===----------------------------------------------------------------------===// +// ETForestBase Implementation +//===----------------------------------------------------------------------===// + +void ETForestBase::addNewBlock(BasicBlock *BB, BasicBlock *IDom) { + ETNode *&BBNode = Nodes[BB]; + assert(!BBNode && "BasicBlock already in ET-Forest"); + + BBNode = new ETNode(BB); + BBNode->setFather(getNode(IDom)); + DFSInfoValid = false; +} + +void ETForestBase::setImmediateDominator(BasicBlock *BB, BasicBlock *newIDom) { + assert(getNode(BB) && "BasicBlock not in ET-Forest"); + assert(getNode(newIDom) && "IDom not in ET-Forest"); + + ETNode *Node = getNode(BB); + if (Node->hasFather()) { + if (Node->getFather()->getData() == newIDom) + return; + Node->Split(); + } + Node->setFather(getNode(newIDom)); + DFSInfoValid= false; +} + +void ETForestBase::print(std::ostream &o, const Module *) const { + o << "=============================--------------------------------\n"; + o << "ET Forest:\n"; + o << "DFS Info "; + if (DFSInfoValid) + o << "is"; + else + o << "is not"; + o << " up to date\n"; + + Function *F = getRoots()[0]->getParent(); + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { + o << " DFS Numbers For Basic Block:"; + WriteAsOperand(o, I, false); + o << " are:"; + if (ETNode *EN = getNode(I)) { + o << "In: " << EN->getDFSNumIn(); + o << " Out: " << EN->getDFSNumOut() << "\n"; + } else { + o << "No associated ETNode"; + } + o << "\n"; + } + o << "\n"; +} From lattner at cs.uiuc.edu Sun Jan 8 02:22:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 8 Jan 2006 02:22:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PostDominators.cpp Message-ID: <200601080822.CAA29859@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PostDominators.cpp updated: 1.53 -> 1.54 --- Log message: Initial implementation of the ET-Forest data structure for dominators and post-dominators. This code was written/adapted by Daniel Berlin! --- Diffs of the changes: (+63 -0) PostDominators.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 63 insertions(+) Index: llvm/lib/Analysis/PostDominators.cpp diff -u llvm/lib/Analysis/PostDominators.cpp:1.53 llvm/lib/Analysis/PostDominators.cpp:1.54 --- llvm/lib/Analysis/PostDominators.cpp:1.53 Fri Nov 18 01:28:26 2005 +++ llvm/lib/Analysis/PostDominators.cpp Sun Jan 8 02:22:18 2006 @@ -205,6 +205,69 @@ } } } +//===----------------------------------------------------------------------===// +// PostETForest Implementation +//===----------------------------------------------------------------------===// + +static RegisterAnalysis +G("postetforest", "Post-ET-Forest Construction", true); + +ETNode *PostETForest::getNodeForBlock(BasicBlock *BB) { + ETNode *&BBNode = Nodes[BB]; + if (BBNode) return BBNode; + + // Haven't calculated this node yet? Get or calculate the node for the + // immediate dominator. + BasicBlock *IDom = getAnalysis()[BB]; + + // If we are unreachable, we may not have an immediate dominator. + if (!IDom) + return BBNode = new ETNode(BB); + else { + ETNode *IDomNode = getNodeForBlock(IDom); + + // Add a new tree node for this BasicBlock, and link it as a child of + // IDomNode + BBNode = new ETNode(BB); + BBNode->setFather(IDomNode); + return BBNode; + } +} + +void PostETForest::calculate(const ImmediatePostDominators &ID) { + for (unsigned i = 0, e = Roots.size(); i != e; ++i) + Nodes[Roots[i]] = new ETNode(Roots[i]); // Add a node for the root + + // Iterate over all nodes in inverse depth first order. + for (unsigned i = 0, e = Roots.size(); i != e; ++i) + for (idf_iterator I = idf_begin(Roots[i]), + E = idf_end(Roots[i]); I != E; ++I) { + BasicBlock *BB = *I; + ETNode *&BBNode = Nodes[BB]; + if (!BBNode) { + ETNode *IDomNode = NULL; + + if (ID.get(BB)) + IDomNode = getNodeForBlock(ID.get(BB)); + + // Add a new ETNode for this BasicBlock, and set it's parent + // to it's immediate dominator. + BBNode = new ETNode(BB); + if (IDomNode) + BBNode->setFather(IDomNode); + } + } + + int dfsnum = 0; + // Iterate over all nodes in depth first order... + for (unsigned i = 0, e = Roots.size(); i != e; ++i) + for (idf_iterator I = idf_begin(Roots[i]), + E = idf_end(Roots[i]); I != E; ++I) { + if (!getNodeForBlock(*I)->hasFather()) + getNodeForBlock(*I)->assignDFSNumber(dfsnum); + } + DFSInfoValid = true; +} //===----------------------------------------------------------------------===// // PostDominanceFrontier Implementation From lattner at cs.uiuc.edu Sun Jan 8 02:25:55 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 8 Jan 2006 02:25:55 -0600 Subject: [llvm-commits] CVS: llvm/CREDITS.TXT Message-ID: <200601080825.CAA31151@zion.cs.uiuc.edu> Changes in directory llvm: CREDITS.TXT updated: 1.44 -> 1.45 --- Log message: Add an entry --- Diffs of the changes: (+4 -0) CREDITS.TXT | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/CREDITS.TXT diff -u llvm/CREDITS.TXT:1.44 llvm/CREDITS.TXT:1.45 --- llvm/CREDITS.TXT:1.44 Thu Dec 22 00:09:08 2005 +++ llvm/CREDITS.TXT Sun Jan 8 02:25:38 2006 @@ -20,6 +20,10 @@ E: natebegeman at mac.com D: Primary PowerPC backend developer +N: Daniel Berlin +E: dberlin at dberlin.org +D: ET-Forest implementation. + N: Misha Brukman E: brukman+llvm at uiuc.edu W: http://misha.brukman.net From lattner at cs.uiuc.edu Sun Jan 8 03:10:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 8 Jan 2006 03:10:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoadValueNumbering.cpp Message-ID: <200601080910.DAA21013@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoadValueNumbering.cpp updated: 1.33 -> 1.34 --- Log message: Fix a problem exposed by the et-forest work. Load-vn needs these passes live whenever it is live, not just when load-vn is computed initially --- Diffs of the changes: (+3 -3) LoadValueNumbering.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/Analysis/LoadValueNumbering.cpp diff -u llvm/lib/Analysis/LoadValueNumbering.cpp:1.33 llvm/lib/Analysis/LoadValueNumbering.cpp:1.34 --- llvm/lib/Analysis/LoadValueNumbering.cpp:1.33 Mon Jun 20 10:25:22 2005 +++ llvm/lib/Analysis/LoadValueNumbering.cpp Sun Jan 8 03:10:04 2006 @@ -95,10 +95,10 @@ /// void LoadVN::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequiredTransitive(); AU.addRequired(); - AU.addRequired(); - AU.addRequired(); + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); } static bool isPathTransparentTo(BasicBlock *CurBlock, BasicBlock *Dom, From lattner at cs.uiuc.edu Sun Jan 8 03:10:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 8 Jan 2006 03:10:57 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ET-Forest.h Message-ID: <200601080910.DAA21051@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ET-Forest.h updated: 1.1 -> 1.2 --- Log message: Fix the build on platforms where doesn't define NULL --- Diffs of the changes: (+1 -0) ET-Forest.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/include/llvm/Analysis/ET-Forest.h diff -u llvm/include/llvm/Analysis/ET-Forest.h:1.1 llvm/include/llvm/Analysis/ET-Forest.h:1.2 --- llvm/include/llvm/Analysis/ET-Forest.h:1.1 Sun Jan 8 02:19:58 2006 +++ llvm/include/llvm/Analysis/ET-Forest.h Sun Jan 8 03:10:46 2006 @@ -30,6 +30,7 @@ #define LLVM_ANALYSIS_ETFOREST_H #include +#include namespace llvm { class ETNode; From jeffc at jolt-lang.org Sun Jan 8 12:29:56 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sun, 8 Jan 2006 12:29:56 -0600 Subject: [llvm-commits] CVS: llvm/win32/Analysis/Analysis.vcproj Message-ID: <200601081829.MAA29685@zion.cs.uiuc.edu> Changes in directory llvm/win32/Analysis: Analysis.vcproj updated: 1.16 -> 1.17 --- Log message: Visual Studio hates being left out. --- Diffs of the changes: (+3 -0) Analysis.vcproj | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/win32/Analysis/Analysis.vcproj diff -u llvm/win32/Analysis/Analysis.vcproj:1.16 llvm/win32/Analysis/Analysis.vcproj:1.17 --- llvm/win32/Analysis/Analysis.vcproj:1.16 Fri Dec 16 18:14:46 2005 +++ llvm/win32/Analysis/Analysis.vcproj Sun Jan 8 12:29:44 2006 @@ -257,6 +257,9 @@ RelativePath="..\..\include\llvm\Analysis\Dominators.h"> + + Changes in directory llvm/tools/bugpoint: ListReducer.h updated: 1.14 -> 1.15 --- Log message: Fix line length of a comment. --- Diffs of the changes: (+2 -2) ListReducer.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/tools/bugpoint/ListReducer.h diff -u llvm/tools/bugpoint/ListReducer.h:1.14 llvm/tools/bugpoint/ListReducer.h:1.15 --- llvm/tools/bugpoint/ListReducer.h:1.14 Mon Aug 1 21:16:17 2005 +++ llvm/tools/bugpoint/ListReducer.h Sun Jan 8 16:40:10 2006 @@ -95,8 +95,8 @@ } // Okay, we trimmed as much off the top and the bottom of the list as we - // could. If there is more two elements in the list, try deleting interior - // elements and testing that. + // could. If there is more than two elements in the list, try deleting + // interior elements and testing that. // if (TheList.size() > 2) { bool Changed = true; From reid at x10sys.com Sun Jan 8 16:41:34 2006 From: reid at x10sys.com (Reid Spencer) Date: Sun, 8 Jan 2006 16:41:34 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/System/Program.h Message-ID: <200601082241.QAA30434@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/System: Program.h updated: 1.7 -> 1.8 --- Log message: Add some documentation. --- Diffs of the changes: (+2 -0) Program.h | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/include/llvm/System/Program.h diff -u llvm/include/llvm/System/Program.h:1.7 llvm/include/llvm/System/Program.h:1.8 --- llvm/include/llvm/System/Program.h:1.7 Thu May 5 17:31:47 2005 +++ llvm/include/llvm/System/Program.h Sun Jan 8 16:41:22 2006 @@ -50,6 +50,8 @@ /// executed. It is presumed this is the result of the FindProgramByName /// method. /// @returns an integer result code indicating the status of the program. + /// A zero or positive value indicates the result code of the program. A + /// negative value is the signal number on which it terminated. /// @throws std::string on a variety of error conditions or if the invoked /// program aborted abnormally. /// @see FindProgrambyName From reid at x10sys.com Sun Jan 8 16:57:19 2006 From: reid at x10sys.com (Reid Spencer) Date: Sun, 8 Jan 2006 16:57:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/PassManagerT.h Message-ID: <200601082257.QAA30481@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: PassManagerT.h updated: 1.64 -> 1.65 --- Log message: Saem Ghani's PassManager Patch #8: This fixes a "gccass" regression. The -debug-pass=Structure option now prints all the appropriate output --- Diffs of the changes: (+16 -2) PassManagerT.h | 18 ++++++++++++++++-- 1 files changed, 16 insertions(+), 2 deletions(-) Index: llvm/lib/VMCore/PassManagerT.h diff -u llvm/lib/VMCore/PassManagerT.h:1.64 llvm/lib/VMCore/PassManagerT.h:1.65 --- llvm/lib/VMCore/PassManagerT.h:1.64 Sat Jan 7 17:16:58 2006 +++ llvm/lib/VMCore/PassManagerT.h Sun Jan 8 16:57:07 2006 @@ -288,7 +288,7 @@ assert(dynamic_cast(this) && "It wasn't the PassClass I thought it was"); if (Parent == 0) - PMDebug::PerformPassStartupStuff((dynamic_cast(this))); + PMDebug::PerformPassStartupStuff((dynamic_cast(this))); // Run all of the passes for (unsigned i = 0, e = Passes.size(); i < e; ++i) { @@ -399,8 +399,9 @@ } // dumpPassStructure - Implement the -debug-passes=PassStructure option - virtual void dumpPassStructure(unsigned Offset = 0) { + inline void dumpPassStructure(unsigned Offset = 0) { // Print out the immutable passes... + for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) ImmutablePasses[i]->dumpPassStructure(0); @@ -653,6 +654,7 @@ } } } + public: // When an ImmutablePass is added, it gets added to the top level pass // manager. @@ -723,6 +725,10 @@ virtual ~BasicBlockPassManager() {} + virtual void dumpPassStructure(unsigned Offset = 0) { + PassManagerT::dumpPassStructure(Offset); + } + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPMName() const { return "BasicBlock"; } @@ -761,6 +767,10 @@ virtual ~FunctionPassManagerT() {} + virtual void dumpPassStructure(unsigned Offset = 0) { + PassManagerT::dumpPassStructure(Offset); + } + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPMName() const { return "Function"; } @@ -804,6 +814,10 @@ virtual ~ModulePassManager() {} + virtual void dumpPassStructure(unsigned Offset = 0) { + PassManagerT::dumpPassStructure(Offset); + } + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. virtual const char *getPassName() const { return "Module Pass Manager"; }