From lattner at cs.uiuc.edu Mon Nov 18 00:58:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 00:58:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211180657.AAA28804@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.6 -> 1.7 --- Log message: Start trying to print instructions more correctly. For now we also print out the opcode for each instruction as well. --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.6 llvm/lib/Target/X86/Printer.cpp:1.7 --- llvm/lib/Target/X86/Printer.cpp:1.6 Sun Nov 17 17:20:37 2002 +++ llvm/lib/Target/X86/Printer.cpp Mon Nov 18 00:56:51 2002 @@ -67,10 +67,99 @@ return false; } +static void printOp(std::ostream &O, const MachineOperand &MO, + const MRegisterInfo &RI) { + switch (MO.getType()) { + case MachineOperand::MO_VirtualRegister: + if (MO.getReg() < MRegisterInfo::FirstVirtualRegister) + O << RI.get(MO.getReg()).Name; + else + O << "%reg" << MO.getReg(); + return; + + default: + O << ""; return; + } +} + +static inline void toHexDigit(std::ostream &O, unsigned char V) { + if (V >= 10) + O << (char)('A'+V-10); + else + O << (char)('0'+V); +} + +static std::ostream &toHex(std::ostream &O, unsigned char V) { + toHexDigit(O, V >> 4); + toHexDigit(O, V & 0xF); + return O; +} + // print - Print out an x86 instruction in intel syntax void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O, const TargetMachine &TM) const { - // FIXME: This sucks. - O << getName(MI->getOpCode()) << "\n"; + unsigned Opcode = MI->getOpcode(); + const MachineInstrDescriptor &Desc = get(Opcode); + + if (Desc.TSFlags & X86II::TB) + O << "0F "; + + switch (Desc.TSFlags & X86II::FormMask) { + case X86II::OtherFrm: + O << "\t"; + O << "-"; MI->print(O, TM); + break; + case X86II::RawFrm: + toHex(O, getBaseOpcodeFor(Opcode)) << "\t"; + O << getName(MI->getOpCode()) << " "; + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + if (i) O << ", "; + printOp(O, MI->getOperand(i), RI); + } + O << "\n"; + return; + + + case X86II::AddRegFrm: + O << "\t-"; MI->print(O, TM); break; + + case X86II::MRMDestReg: + // There are two acceptable forms of MRMDestReg instructions, those with 3 + // and 2 operands: + // + // 3 Operands: in this form, the first two registers (the destination, and + // the first operand) should be the same, post register allocation. The 3rd + // operand is an additional input. This should be for things like add + // instructions. + // + // 2 Operands: this is for things like mov that do not read a second input + // + assert(((MI->getNumOperands() == 3 && + (MI->getOperand(0).getType()==MachineOperand::MO_VirtualRegister&& + MI->getOperand(1).getType()==MachineOperand::MO_VirtualRegister))|| + (MI->getNumOperands() == 2 && + (MI->getOperand(0).getType()==MachineOperand::MO_VirtualRegister))) + && MI->getOperand(MI->getNumOperands()-1).getType() == + MachineOperand::MO_VirtualRegister && + "Bad format for MRMDestReg!"); + + if (MI->getNumOperands() == 3 && + MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) + O << "**"; + + O << "\t"; + O << getName(MI->getOpCode()) << " "; + printOp(O, MI->getOperand(0), RI); + O << ", "; + printOp(O, MI->getOperand(MI->getNumOperands()-1), RI); + O << "\n"; + return; + case X86II::MRMDestMem: + case X86II::MRMSrcReg: + case X86II::MRMSrcMem: + default: + O << "\t-"; MI->print(O, TM); break; + } } From lattner at cs.uiuc.edu Mon Nov 18 00:58:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 00:58:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.h X86InstrInfo.cpp Message-ID: <200211180657.AAA28813@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.h updated: 1.10 -> 1.11 X86InstrInfo.cpp updated: 1.7 -> 1.8 --- Log message: Expose base opcode --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.10 llvm/lib/Target/X86/X86InstrInfo.h:1.11 --- llvm/lib/Target/X86/X86InstrInfo.h:1.10 Sun Nov 17 23:37:11 2002 +++ llvm/lib/Target/X86/X86InstrInfo.h Mon Nov 18 00:56:24 2002 @@ -54,6 +54,7 @@ /// TODO: Mod/RM that uses a fixed opcode extension, like /0 + FormMask = 7, //===------------------------------------------------------------------===// // Actual flags... @@ -82,6 +83,12 @@ /// virtual void print(const MachineInstr *MI, std::ostream &O, const TargetMachine &TM) const; + + // getBaseOpcodeFor - This function returns the "base" X86 opcode for the + // specified opcode number. + // + unsigned char getBaseOpcodeFor(unsigned Opcode) const; + //===--------------------------------------------------------------------===// Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.7 llvm/lib/Target/X86/X86InstrInfo.cpp:1.8 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.7 Sun Nov 17 23:37:11 2002 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Mon Nov 18 00:56:24 2002 @@ -25,3 +25,16 @@ } +static unsigned char BaseOpcodes[] = { +#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS) BASEOPCODE, +#include "X86InstrInfo.def" +}; + +// getBaseOpcodeFor - This function returns the "base" X86 opcode for the +// specified opcode number. +// +unsigned char X86InstrInfo::getBaseOpcodeFor(unsigned Opcode) const { + assert(Opcode < sizeof(BaseOpcodes)/sizeof(BaseOpcodes[0]) && + "Opcode out of range!"); + return BaseOpcodes[Opcode]; +} From lattner at cs.uiuc.edu Mon Nov 18 00:58:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 00:58:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200211180657.AAA28825@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.88 -> 1.89 --- Log message: Add helper method --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.88 llvm/include/llvm/CodeGen/MachineInstr.h:1.89 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.88 Sun Nov 17 17:21:26 2002 +++ llvm/include/llvm/CodeGen/MachineInstr.h Mon Nov 18 00:57:05 2002 @@ -190,6 +190,10 @@ return regNum; } + inline unsigned getReg() const { + assert(hasAllocatedReg() && "Cannot call MachineOperand::getReg()!"); + return regNum; + } friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); From hldnbrnd at cs.uiuc.edu Mon Nov 18 14:57:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Mon Nov 18 14:57:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200211182056.OAA03383@niobe.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.73 -> 1.74 --- Log message: (null) --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.73 llvm/lib/CWriter/Writer.cpp:1.74 --- llvm/lib/CWriter/Writer.cpp:1.73 Thu Nov 7 16:12:53 2002 +++ llvm/lib/CWriter/Writer.cpp Mon Nov 18 14:55:50 2002 @@ -23,6 +23,7 @@ #include "Support/STLExtras.h" #include #include +#include using std::string; using std::map; using std::ostream; @@ -64,7 +65,7 @@ return false; } - ostream &printType(const Type *Ty, const string &VariableName = "", + ostream &printType(std::ostream &Out, const Type *Ty, const string &VariableName = "", bool IgnoreName = false, bool namedContext = true); void writeOperand(Value *Operand); @@ -176,7 +177,7 @@ // Pass the Type* and the variable name and this prints out the variable // declaration. // -ostream &CWriter::printType(const Type *Ty, const string &NameSoFar, +ostream &CWriter::printType(std::ostream &Out, const Type *Ty, const string &NameSoFar, bool IgnoreName, bool namedContext) { if (Ty->isPrimitiveType()) switch (Ty->getPrimitiveID()) { @@ -208,22 +209,24 @@ switch (Ty->getPrimitiveID()) { case Type::FunctionTyID: { const FunctionType *MTy = cast(Ty); - printType(MTy->getReturnType(), ""); - Out << " (" << NameSoFar << ") ("; - + std::stringstream FunctionInards; + FunctionInards << " (" << NameSoFar << ") ("; for (FunctionType::ParamTypes::const_iterator I = MTy->getParamTypes().begin(), E = MTy->getParamTypes().end(); I != E; ++I) { if (I != MTy->getParamTypes().begin()) - Out << ", "; - printType(*I, ""); + FunctionInards << ", "; + printType(FunctionInards, *I, ""); } if (MTy->isVarArg()) { if (!MTy->getParamTypes().empty()) - Out << ", "; - Out << "..."; + FunctionInards << ", "; + FunctionInards << "..."; } - return Out << ")"; + FunctionInards << ")"; + string tstr = FunctionInards.str(); + printType(Out, MTy->getReturnType(), tstr); + return Out; } case Type::StructTyID: { const StructType *STy = cast(Ty); @@ -233,7 +236,7 @@ I = STy->getElementTypes().begin(), E = STy->getElementTypes().end(); I != E; ++I) { Out << " "; - printType(*I, "field" + utostr(Idx++)); + printType(Out, *I, "field" + utostr(Idx++)); Out << ";\n"; } return Out << "}"; @@ -250,13 +253,13 @@ PTy->getElementType()->getPrimitiveID() == Type::ArrayTyID) ptrName = "(" + ptrName + ")"; // - return printType(PTy->getElementType(), ptrName); - } + return printType(Out, PTy->getElementType(), ptrName); + }Out <<"--"; case Type::ArrayTyID: { const ArrayType *ATy = cast(Ty); unsigned NumElements = ATy->getNumElements(); - return printType(ATy->getElementType(), + return printType(Out, ATy->getElementType(), NameSoFar + "[" + utostr(NumElements) + "]"); } @@ -340,7 +343,7 @@ switch (CE->getOpcode()) { case Instruction::Cast: Out << "(("; - printType(CPV->getType()); + printType(Out, CPV->getType()); Out << ")"; printConstant(cast(CPV->getOperand(0))); Out << ")"; @@ -553,7 +556,7 @@ for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) { if (I->hasExternalLinkage()) { Out << "extern "; - printType(I->getType()->getElementType(), getValueName(I)); + printType(Out, I->getType()->getElementType(), getValueName(I)); Out << ";\n"; } } @@ -581,7 +584,7 @@ for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) if (!I->isExternal()) { Out << "extern "; - printType(I->getType()->getElementType(), getValueName(I)); + printType(Out, I->getType()->getElementType(), getValueName(I)); Out << ";\n"; } @@ -595,7 +598,7 @@ if (!I->isExternal()) { if (I->hasInternalLinkage()) Out << "static "; - printType(I->getType()->getElementType(), getValueName(I)); + printType(Out, I->getType()->getElementType(), getValueName(I)); Out << " = " ; writeOperand(I->getInitializer()); @@ -641,7 +644,7 @@ const Type *Ty = cast(I->second); string Name = "l_" + makeNameProper(I->first); Out << "typedef "; - printType(Ty, Name); + printType(Out, Ty, Name); Out << ";\n"; } @@ -678,7 +681,7 @@ //Print structure type out.. StructPrinted.insert(STy); string Name = TypeNames[STy]; - printType(STy, Name, true); + printType(Out, STy, Name, true); Out << ";\n\n"; } @@ -696,31 +699,29 @@ // to include the general one. if (getValueName(F) == "malloc") needsMalloc = false; - if (F->hasInternalLinkage()) Out << "static "; - + if (F->hasInternalLinkage()) Out << "static "; // Loop over the arguments, printing them... const FunctionType *FT = cast(F->getFunctionType()); - // Print out the return type and name... - printType(F->getReturnType()); - Out << getValueName(F) << "("; + std::stringstream FunctionInards; + + // Print out the name... + FunctionInards << getValueName(F) << "("; if (!F->isExternal()) { if (!F->aempty()) { string ArgName; if (F->abegin()->hasName() || !Prototype) ArgName = getValueName(F->abegin()); - - printType(F->afront().getType(), ArgName); - + printType(FunctionInards, F->afront().getType(), ArgName); for (Function::const_aiterator I = ++F->abegin(), E = F->aend(); I != E; ++I) { - Out << ", "; + FunctionInards << ", "; if (I->hasName() || !Prototype) ArgName = getValueName(I); else ArgName = ""; - printType(I->getType(), ArgName); + printType(FunctionInards, I->getType(), ArgName); } } } else { @@ -728,8 +729,8 @@ for (FunctionType::ParamTypes::const_iterator I = FT->getParamTypes().begin(), E = FT->getParamTypes().end(); I != E; ++I) { - if (I != FT->getParamTypes().begin()) Out << ", "; - printType(*I); + if (I != FT->getParamTypes().begin()) FunctionInards << ", "; + printType(FunctionInards, *I); } } @@ -737,10 +738,13 @@ // unless there are no known types, in which case, we just emit (). // if (FT->isVarArg() && !FT->getParamTypes().empty()) { - if (FT->getParamTypes().size()) Out << ", "; - Out << "..."; // Output varargs portion of signature! + if (FT->getParamTypes().size()) FunctionInards << ", "; + FunctionInards << "..."; // Output varargs portion of signature! } - Out << ")"; + FunctionInards << ")"; + // Print out the return type and the entire signature for that matter + printType(Out, F->getReturnType(), FunctionInards.str()); + } @@ -756,7 +760,7 @@ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) if ((*I)->getType() != Type::VoidTy && !isInlinableInst(**I)) { Out << " "; - printType((*I)->getType(), getValueName(*I)); + printType(Out, (*I)->getType(), getValueName(*I)); Out << ";\n"; } @@ -914,7 +918,7 @@ // binary instructions, shift instructions, setCond instructions. if (isa(I.getType())) { Out << "("; - printType(I.getType()); + printType(Out, I.getType()); Out << ")"; } @@ -947,7 +951,7 @@ void CWriter::visitCastInst(CastInst &I) { Out << "("; - printType(I.getType(), string(""),/*ignoreName*/false, /*namedContext*/false); + printType(Out, I.getType(), string(""),/*ignoreName*/false, /*namedContext*/false); Out << ")"; writeOperand(I.getOperand(0)); } @@ -973,9 +977,9 @@ void CWriter::visitMallocInst(MallocInst &I) { Out << "("; - printType(I.getType()); + printType(Out, I.getType()); Out << ")malloc(sizeof("; - printType(I.getType()->getElementType()); + printType(Out, I.getType()->getElementType()); Out << ")"; if (I.isArrayAllocation()) { @@ -987,9 +991,9 @@ void CWriter::visitAllocaInst(AllocaInst &I) { Out << "("; - printType(I.getType()); + printType(Out, I.getType()); Out << ") alloca(sizeof("; - printType(I.getType()->getElementType()); + printType(Out, I.getType()->getElementType()); Out << ")"; if (I.isArrayAllocation()) { Out << " * " ; From lattner at cs.uiuc.edu Mon Nov 18 15:43:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 15:43:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraphTraits.h Message-ID: <200211182142.PAA30821@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraphTraits.h updated: 1.10 -> 1.11 --- Log message: Templatize graph traits and iterator to work with const and non-const clients --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraphTraits.h diff -u llvm/include/llvm/Analysis/DSGraphTraits.h:1.10 llvm/include/llvm/Analysis/DSGraphTraits.h:1.11 --- llvm/include/llvm/Analysis/DSGraphTraits.h:1.10 Wed Nov 6 00:20:27 2002 +++ llvm/include/llvm/Analysis/DSGraphTraits.h Mon Nov 18 15:42:19 2002 @@ -14,15 +14,16 @@ #include "Support/iterator" #include "Support/STLExtras.h" +template class DSNodeIterator : public forward_iterator { friend class DSNode; - const DSNode * const Node; + NodeTy * const Node; unsigned Offset; - typedef DSNodeIterator _Self; + typedef DSNodeIterator _Self; - DSNodeIterator(const DSNode *N) : Node(N), Offset(0) {} // begin iterator - DSNodeIterator(const DSNode *N, bool) // Create end iterator + DSNodeIterator(NodeTy *N) : Node(N), Offset(0) {} // begin iterator + DSNodeIterator(NodeTy *N, bool) // Create end iterator : Node(N) { Offset = (N->getSize()+((1 << DS::PointerShift)-1)) & ~((1 << DS::PointerShift)-1); @@ -60,8 +61,18 @@ }; // Provide iterators for DSNode... -inline DSNode::iterator DSNode::begin() const { return DSNodeIterator(this); } -inline DSNode::iterator DSNode::end() const { return DSNodeIterator(this, false); } +inline DSNode::iterator DSNode::begin() { + return DSNode::iterator(this); +} +inline DSNode::iterator DSNode::end() { + return DSNode::iterator(this, false); +} +inline DSNode::const_iterator DSNode::begin() const { + return DSNode::const_iterator(this); +} +inline DSNode::const_iterator DSNode::end() const { + return DSNode::const_iterator(this, false); +} template <> struct GraphTraits { typedef DSNode NodeType; @@ -72,6 +83,15 @@ static ChildIteratorType child_end(NodeType *N) { return N->end(); } }; +template <> struct GraphTraits { + typedef const DSNode NodeType; + typedef DSNode::const_iterator ChildIteratorType; + + static NodeType *getEntryNode(NodeType *N) { return N; } + static ChildIteratorType child_begin(NodeType *N) { return N->begin(); } + static ChildIteratorType child_end(NodeType *N) { return N->end(); } +}; + static DSNode &dereference ( DSNode *N) { return *N; } static const DSNode &dereferenceC(const DSNode *N) { return *N; } @@ -97,7 +117,7 @@ template <> struct GraphTraits { typedef const DSNode NodeType; - typedef DSNode::iterator ChildIteratorType; + typedef DSNode::const_iterator ChildIteratorType; typedef std::pointer_to_unary_function DerefFun; From lattner at cs.uiuc.edu Mon Nov 18 15:43:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 15:43:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Printer.cpp Message-ID: <200211182142.PAA30835@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Printer.cpp updated: 1.41 -> 1.42 --- Log message: Add stats --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Printer.cpp diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.41 llvm/lib/Analysis/DataStructure/Printer.cpp:1.42 --- llvm/lib/Analysis/DataStructure/Printer.cpp:1.41 Sun Nov 10 18:01:02 2002 +++ llvm/lib/Analysis/DataStructure/Printer.cpp Mon Nov 18 15:42:45 2002 @@ -11,6 +11,7 @@ #include "llvm/Assembly/Writer.h" #include "Support/CommandLine.h" #include "Support/GraphWriter.h" +#include "Support/Statistic.h" #include #include using std::string; @@ -18,7 +19,11 @@ // OnlyPrintMain - The DataStructure printer exposes this option to allow // printing of only the graph for "main". // -static cl::opt OnlyPrintMain("only-print-main-ds", cl::ReallyHidden); +namespace { + cl::opt OnlyPrintMain("only-print-main-ds", cl::ReallyHidden); + Statistic<> MaxGraphSize ("dsnode", "Maximum graph size"); + Statistic<> NumFoldedNodes ("dsnode", "Number of folded nodes (in final graph)"); +} void DSNode::dump() const { print(std::cerr, 0); } @@ -30,8 +35,8 @@ if (N->isNodeCompletelyFolded()) OS << "FOLDED"; else { - WriteTypeSymbolic(OS, N->getType().Ty, M); - if (N->getType().isArray) + WriteTypeSymbolic(OS, N->getType(), M); + if (N->isArray()) OS << " array"; } if (N->NodeType) { @@ -89,7 +94,7 @@ if (!isa(I->first)) { std::stringstream OS; WriteAsOperand(OS, I->first, false, true, G->getFunction().getParent()); - GW.emitSimpleNode(I->first, "plaintext=circle", OS.str()); + GW.emitSimpleNode(I->first, "", OS.str()); // Add edge from return node to real destination int EdgeDest = I->second.getOffset() >> DS::PointerShift; @@ -186,6 +191,12 @@ O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... [" << Gr.getGraphSize() << "+" << NumCalls << "]\n"; } + + if (MaxGraphSize < Gr.getNodes().size()) + MaxGraphSize = Gr.getNodes().size(); + for (unsigned i = 0, e = Gr.getNodes().size(); i != e; ++i) + if (Gr.getNodes()[i]->isNodeCompletelyFolded()) + ++NumFoldedNodes; } DSGraph &GG = C.getGlobalsGraph(); From lattner at cs.uiuc.edu Mon Nov 18 15:45:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 15:45:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200211182144.PAA30852@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.38 -> 1.39 --- Log message: Add peak memory usage support --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.38 llvm/lib/Analysis/DataStructure/Local.cpp:1.39 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.38 Sun Nov 10 00:53:38 2002 +++ llvm/lib/Analysis/DataStructure/Local.cpp Mon Nov 18 15:44:19 2002 @@ -18,6 +18,7 @@ #include "llvm/Support/InstVisitor.h" #include "llvm/Target/TargetData.h" #include "Support/Statistic.h" +#include "Support/Timer.h" // FIXME: This should eventually be a FunctionPass that is automatically // aggregated into a Pass. @@ -132,6 +133,9 @@ PrintAuxCalls = false; // Use the graph builder to construct the local version of the graph GraphBuilder B(*this, Nodes, RetNode, ScalarMap, FunctionCalls); +#ifndef NDEBUG + Timer::addPeakMemoryMeasurement(); +#endif markIncompleteNodes(); // Remove any nodes made dead due to merging... @@ -142,7 +146,6 @@ //===----------------------------------------------------------------------===// // Helper method implementations... // - /// getValueDest - Return the DSNode that the actual value points to. /// From lattner at cs.uiuc.edu Mon Nov 18 15:45:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 15:45:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200211182144.PAA30868@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.67 -> 1.68 --- Log message: Add peak memory usage measurement stuff Add structure padding optimizations --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.67 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.68 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.67 Tue Nov 12 01:20:45 2002 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Nov 18 15:44:46 2002 @@ -11,6 +11,7 @@ #include "llvm/Target/TargetData.h" #include "Support/STLExtras.h" #include "Support/Statistic.h" +#include "Support/Timer.h" #include #include @@ -77,7 +78,8 @@ ++NumFolds; // We are no longer typed at all... - Ty = DSTypeRec(Type::VoidTy, true); + Ty = Type::VoidTy; + NodeType |= Array; Size = 1; // Loop over all of our referrers, making them point to our zero bytes of @@ -97,7 +99,7 @@ /// all of the field sensitivity that may be present in the node. /// bool DSNode::isNodeCompletelyFolded() const { - return getSize() == 1 && Ty.Ty == Type::VoidTy && Ty.isArray; + return getSize() == 1 && Ty == Type::VoidTy && isArray(); } @@ -117,15 +119,15 @@ // Size = 1, Ty = Void, Array = 1: The node is collapsed // Otherwise, sizeof(Ty) = Size // - assert(((Size == 0 && Ty.Ty == Type::VoidTy && !Ty.isArray) || - (Size == 0 && !Ty.Ty->isSized() && !Ty.isArray) || - (Size == 1 && Ty.Ty == Type::VoidTy && Ty.isArray) || - (Size == 0 && !Ty.Ty->isSized() && !Ty.isArray) || - (TD.getTypeSize(Ty.Ty) == Size)) && + assert(((Size == 0 && Ty == Type::VoidTy && !isArray()) || + (Size == 0 && !Ty->isSized() && !isArray()) || + (Size == 1 && Ty == Type::VoidTy && isArray()) || + (Size == 0 && !Ty->isSized() && !isArray()) || + (TD.getTypeSize(Ty) == Size)) && "Size member of DSNode doesn't match the type structure!"); assert(NewTy != Type::VoidTy && "Cannot merge void type into DSNode!"); - if (Offset == 0 && NewTy == Ty.Ty) + if (Offset == 0 && NewTy == Ty) return false; // This should be a common case, handle it efficiently // Return true immediately if the node is completely folded. @@ -150,13 +152,14 @@ // we can't, we fold the node completely, if we can, we potentially update our // internal state. // - if (Ty.Ty == Type::VoidTy) { + if (Ty == Type::VoidTy) { // If this is the first type that this node has seen, just accept it without // question.... assert(Offset == 0 && "Cannot have an offset into a void node!"); - assert(!Ty.isArray && "This shouldn't happen!"); - Ty.Ty = NewTy; - Ty.isArray = WillBeArray; + assert(!isArray() && "This shouldn't happen!"); + Ty = NewTy; + NodeType &= ~Array; + if (WillBeArray) NodeType |= Array; Size = NewTySize; // Calculate the number of outgoing links from this node. @@ -168,7 +171,7 @@ if (Offset+NewTySize > Size) { // It is illegal to grow this node if we have treated it as an array of // objects... - if (Ty.isArray) { + if (isArray()) { foldNodeCompletely(); return true; } @@ -186,9 +189,10 @@ // hit the other code path here. If the other code path decides it's not // ok, it will collapse the node as appropriate. // - const Type *OldTy = Ty.Ty; - Ty.Ty = NewTy; - Ty.isArray = WillBeArray; + const Type *OldTy = Ty; + Ty = NewTy; + NodeType &= ~Array; + if (WillBeArray) NodeType |= Array; Size = NewTySize; // Must grow links to be the appropriate size... @@ -202,11 +206,11 @@ assert(Offset <= Size && "Cannot merge something into a part of our type that doesn't exist!"); - // Find the section of Ty.Ty that NewTy overlaps with... first we find the + // Find the section of Ty that NewTy overlaps with... first we find the // type that starts at offset Offset. // unsigned O = 0; - const Type *SubType = Ty.Ty; + const Type *SubType = Ty; while (O < Offset) { assert(Offset-O < TD.getTypeSize(SubType) && "Offset out of range!"); @@ -247,17 +251,27 @@ // composite type... // unsigned SubTypeSize = SubType->isSized() ? TD.getTypeSize(SubType) : 0; + unsigned PadSize = SubTypeSize; // Size, including pad memory which is ignored while (SubType != NewTy) { const Type *NextSubType = 0; unsigned NextSubTypeSize = 0; + unsigned NextPadSize = 0; switch (SubType->getPrimitiveID()) { - case Type::StructTyID: - NextSubType = cast(SubType)->getElementTypes()[0]; - NextSubTypeSize = TD.getTypeSize(SubType); + case Type::StructTyID: { + const StructType *STy = cast(SubType); + const StructLayout &SL = *TD.getStructLayout(STy); + if (SL.MemberOffsets.size() > 1) + NextPadSize = SL.MemberOffsets[1]; + else + NextPadSize = SubTypeSize; + NextSubType = STy->getElementTypes()[0]; + NextSubTypeSize = TD.getTypeSize(NextSubType); break; + } case Type::ArrayTyID: NextSubType = cast(SubType)->getElementType(); - NextSubTypeSize = TD.getTypeSize(SubType); + NextSubTypeSize = TD.getTypeSize(NextSubType); + NextPadSize = NextSubTypeSize; break; default: ; // fall out @@ -266,10 +280,11 @@ if (NextSubType == 0) break; // In the default case, break out of the loop - if (NextSubTypeSize < NewTySize) + if (NextPadSize < NewTySize) break; // Don't allow shrinking to a smaller type than NewTySize SubType = NextSubType; SubTypeSize = NextSubTypeSize; + PadSize = NextPadSize; } // If we found the type exactly, return it... @@ -288,11 +303,14 @@ if (SubType->isInteger() && isa(NewTy) || NewTy->isInteger() && isa(SubType)) return false; - + } else if (NewTySize > SubTypeSize && NewTySize <= PadSize) { + // We are accessing the field, plus some structure padding. Ignore the + // structure padding. + return false; } - DEBUG(std::cerr << "MergeTypeInfo Folding OrigTy: " << Ty.Ty + DEBUG(std::cerr << "MergeTypeInfo Folding OrigTy: " << Ty << "\n due to:" << NewTy << " @ " << Offset << "!\n" << "SubType: " << SubType << "\n\n"); @@ -322,8 +340,8 @@ // duplicates are not allowed and both are sorted. This assumes that 'T's are // efficiently copyable and have sane comparison semantics. // -template -void MergeSortedVectors(vector &Dest, const vector &Src) { +static void MergeSortedVectors(vector &Dest, + const vector &Src) { // By far, the most common cases will be the simple ones. In these cases, // avoid having to allocate a temporary vector... // @@ -332,22 +350,22 @@ } else if (Dest.empty()) { // Just copy the result in... Dest = Src; } else if (Src.size() == 1) { // Insert a single element... - const T &V = Src[0]; - typename vector::iterator I = + const GlobalValue *V = Src[0]; + vector::iterator I = std::lower_bound(Dest.begin(), Dest.end(), V); if (I == Dest.end() || *I != Src[0]) // If not already contained... Dest.insert(I, Src[0]); } else if (Dest.size() == 1) { - T Tmp = Dest[0]; // Save value in temporary... + GlobalValue *Tmp = Dest[0]; // Save value in temporary... Dest = Src; // Copy over list... - typename vector::iterator I = + vector::iterator I = std::lower_bound(Dest.begin(), Dest.end(), Tmp); if (I == Dest.end() || *I != Tmp) // If not already contained... Dest.insert(I, Tmp); } else { // Make a copy to the side of Dest... - vector Old(Dest); + vector Old(Dest); // Make space for all of the type entries now... Dest.resize(Dest.size()+Src.size()); @@ -407,8 +425,8 @@ unsigned NSize = N->getSize(); // Merge the type entries of the two nodes together... - if (N->Ty.Ty != Type::VoidTy) { - mergeTypeInfo(N->Ty.Ty, NOffset); + if (N->Ty != Type::VoidTy) { + mergeTypeInfo(N->Ty, NOffset); // mergeTypeInfo can cause collapsing, which can cause this node to become // dead. @@ -423,14 +441,14 @@ if (!N->isNodeCompletelyFolded()) { N->foldNodeCompletely(); if (hasNoReferrers()) return; - NSize = N->getSize(); + NSize = N->getSize(); } } else if (N->isNodeCompletelyFolded()) { foldNodeCompletely(); if (hasNoReferrers()) return; Offset = 0; NOffset = NH.getOffset(); - NSize = N->getSize(); + NSize = N->getSize(); } N = NH.getNode(); if (this == N || N == 0) return; @@ -464,15 +482,17 @@ // merging just occured, causing THIS node to get merged into oblivion. // If that happens, we must not try to merge any more edges into it! // - if (Size == 0) return; + if (Size == 0) + return; // Node is now dead + if (Size == 1) + break; // Node got collapsed } } // Now that there are no outgoing edges, all of the Links are dead. N->Links.clear(); N->Size = 0; - N->Ty.Ty = Type::VoidTy; - N->Ty.isArray = false; + N->Ty = Type::VoidTy; // Merge the node types NodeType |= N->NodeType; @@ -569,6 +589,10 @@ OldNodeMap[Old] = New; } +#ifndef NDEBUG + Timer::addPeakMemoryMeasurement(); +#endif + // Rewrite the links in the new nodes to point into the current graph now. for (unsigned i = FN, e = Nodes.size(); i != e; ++i) Nodes[i]->remapLinks(OldNodeMap); @@ -786,7 +810,7 @@ if (DSNode *N = Edge.getNode()) // Is there an edge? if (N->getReferrers().size() == 1) // Does it point to a lonely node? if ((N->NodeType & ~DSNode::Incomplete) == 0 && // No interesting info? - N->getType().Ty == Type::VoidTy && !N->isNodeCompletelyFolded()) + N->getType() == Type::VoidTy && !N->isNodeCompletelyFolded()) Edge.setNode(0); // Kill the edge! } From lattner at cs.uiuc.edu Mon Nov 18 15:46:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 15:46:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSSupport.h Message-ID: <200211182145.PAA30880@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSSupport.h updated: 1.7 -> 1.8 --- Log message: Inline DSTypeRec into DSNode --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSSupport.h diff -u llvm/include/llvm/Analysis/DSSupport.h:1.7 llvm/include/llvm/Analysis/DSSupport.h:1.8 --- llvm/include/llvm/Analysis/DSSupport.h:1.7 Sun Nov 10 17:46:51 2002 +++ llvm/include/llvm/Analysis/DSSupport.h Mon Nov 18 15:45:07 2002 @@ -20,7 +20,6 @@ class DSNode; // Each node in the graph class DSGraph; // A graph for a function -class DSNodeIterator; // Data structure graph traversal iterator namespace DS { // FIXME: After the paper, this should get cleaned up enum { PointerShift = 3, // 64bit ptrs = 3, 32 bit ptrs = 2 @@ -98,20 +97,6 @@ }; inline void swap(DSNodeHandle &NH1, DSNodeHandle &NH2) { NH1.swap(NH2); } - -//===----------------------------------------------------------------------===// -/// DSTypeRec - This structure is used to represent a single type that is held -/// in a DSNode. -/// -struct DSTypeRec { - const Type *Ty; // The type itself... - bool isArray; // Have we accessed an array of elements? - - DSTypeRec(const Type *T = 0, bool A = false) - : Ty(T), isArray(A) {} -}; - - //===----------------------------------------------------------------------===// /// DSCallSite - Representation of a call site via its call instruction, From lattner at cs.uiuc.edu Mon Nov 18 15:46:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 15:46:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSNode.h Message-ID: <200211182145.PAA30894@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSNode.h updated: 1.14 -> 1.15 --- Log message: Inline DSTypeRec stuff into DSNode --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSNode.h diff -u llvm/include/llvm/Analysis/DSNode.h:1.14 llvm/include/llvm/Analysis/DSNode.h:1.15 --- llvm/include/llvm/Analysis/DSNode.h:1.14 Sun Nov 10 00:48:24 2002 +++ llvm/include/llvm/Analysis/DSNode.h Mon Nov 18 15:45:30 2002 @@ -8,6 +8,8 @@ #define LLVM_ANALYSIS_DSNODE_H #include "llvm/Analysis/DSSupport.h" +template +class DSNodeIterator; // Data structure graph traversal iterator //===----------------------------------------------------------------------===// /// DSNode - Data structure node class @@ -34,11 +36,11 @@ /// std::vector Globals; - /// Type - Keep track of the current outer most type of this object, in - /// addition to whether or not it has been indexed like an array or not. If - /// the isArray bit is set, the node cannot grow. + /// Ty - Keep track of the current outer most type of this object, in addition + /// to whether or not it has been indexed like an array or not. If the + /// isArray bit is set, the node cannot grow. /// - DSTypeRec Ty; + const Type *Ty; // The type itself... /// Size - The current size of the node. This should be equal to the size of /// the current type record. @@ -56,8 +58,9 @@ Incomplete = 1 << 4, // This node may not be complete Modified = 1 << 5, // This node is modified in this context Read = 1 << 6, // This node is read in this context + Array = 1 << 7, // This node is treated like an array #if 1 - DEAD = 1 << 7, // This node is dead and should not be pointed to + DEAD = 1 << 8, // This node is dead and should not be pointed to #endif }; @@ -66,7 +69,7 @@ /// with a value of 0 for their NodeType. Scalar and Alloca markers go away /// when function graphs are inlined. /// - unsigned char NodeType; + unsigned short NodeType; DSNode(enum NodeTy NT, const Type *T); DSNode(const DSNode &); @@ -76,11 +79,13 @@ assert(Referrers.empty() && "Referrers to dead node exist!"); } - // Iterator for graph interface... - typedef DSNodeIterator iterator; - typedef DSNodeIterator const_iterator; - inline iterator begin() const; // Defined in DSGraphTraits.h - inline iterator end() const; + // Iterator for graph interface... Defined in DSGraphTraits.h + typedef DSNodeIterator iterator; + typedef DSNodeIterator const_iterator; + inline iterator begin(); + inline iterator end(); + inline const_iterator begin() const; + inline const_iterator end() const; //===-------------------------------------------------- // Accessors @@ -90,7 +95,8 @@ unsigned getSize() const { return Size; } // getType - Return the node type of this object... - const DSTypeRec &getType() const { return Ty; } + const Type *getType() const { return Ty; } + bool isArray() const { return NodeType & Array; } /// getReferrers - Return a list of the pointers to this node... /// From lattner at cs.uiuc.edu Mon Nov 18 15:47:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 15:47:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/Timer.h Message-ID: <200211182146.PAA30905@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: Timer.h updated: 1.3 -> 1.4 --- Log message: Add facility to compute peak memory usage --- Diffs of the changes: Index: llvm/include/Support/Timer.h diff -u llvm/include/Support/Timer.h:1.3 llvm/include/Support/Timer.h:1.4 --- llvm/include/Support/Timer.h:1.3 Mon Nov 4 13:20:09 2002 +++ llvm/include/Support/Timer.h Mon Nov 18 15:45:55 2002 @@ -35,6 +35,8 @@ double UserTime; // User time elapsed double SystemTime; // System time elapsed long MemUsed; // Memory allocated (in bytes) + long PeakMem; // Peak memory used + long PeakMemBase; // Temporary for peak calculation... std::string Name; // The name of this time variable bool Started; // Has this time variable ever been started? TimerGroup *TG; // The TimerGroup this Timer is in. @@ -47,6 +49,7 @@ double getProcessTime() const { return UserTime+SystemTime; } double getWallTime() const { return Elapsed; } long getMemUsed() const { return MemUsed; } + long getPeakMem() const { return PeakMem; } std::string getName() const { return Name; } const Timer &operator=(const Timer &T) { @@ -54,6 +57,8 @@ UserTime = T.UserTime; SystemTime = T.SystemTime; MemUsed = T.MemUsed; + PeakMem = T.PeakMem; + PeakMemBase = T.PeakMemBase; Name = T.Name; Started = T.Started; assert (TG == T.TG && "Can only assign timers in the same TimerGroup!"); @@ -76,6 +81,12 @@ /// stopTimer - Stop the timer. /// void stopTimer(); + + /// addPeakMemoryMeasurement - This method should be called whenever memory + /// usage needs to be checked. It adds a peak memory measurement to the + /// currently active timers, which will be printed when the timer group prints + /// + static void addPeakMemoryMeasurement(); /// print - Print the current timer to standard error, and reset the "Started" /// flag. From lattner at cs.uiuc.edu Mon Nov 18 15:48:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Nov 18 15:48:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Support/Timer.cpp Message-ID: <200211182147.PAA30925@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: Timer.cpp updated: 1.9 -> 1.10 --- Log message: Add peak memory usage measurement capability Add (currently disabled) faciility to try to filter out pool allocation overhead from memory usage stats --- Diffs of the changes: Index: llvm/lib/Support/Timer.cpp diff -u llvm/lib/Support/Timer.cpp:1.9 llvm/lib/Support/Timer.cpp:1.10 --- llvm/lib/Support/Timer.cpp:1.9 Mon Nov 4 15:06:54 2002 +++ llvm/lib/Support/Timer.cpp Mon Nov 18 15:47:09 2002 @@ -15,6 +15,12 @@ #include #include +// getNumBytesToNotCount - This function is supposed to return the number of +// bytes that are to be considered not allocated, even though malloc thinks they +// are allocated. +// +static unsigned getNumBytesToNotCount(); + static TimerGroup *DefaultTimerGroup = 0; static TimerGroup *getDefaultTimerGroup() { if (DefaultTimerGroup) return DefaultTimerGroup; @@ -22,13 +28,13 @@ } Timer::Timer(const std::string &N) - : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), Name(N), + : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), PeakMem(0), Name(N), Started(false), TG(getDefaultTimerGroup()) { TG->addTimer(); } Timer::Timer(const std::string &N, TimerGroup &tg) - : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), Name(N), + : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), PeakMem(0), Name(N), Started(false), TG(&tg) { TG->addTimer(); } @@ -58,42 +64,70 @@ } } +static long getMemUsage() { + struct mallinfo MI = mallinfo(); + return MI.uordblks/*+MI.hblkhd-getNumBytesToNotCount()*/; +} + struct TimeRecord { double Elapsed, UserTime, SystemTime; long MemUsed; }; -static TimeRecord getTimeRecord() { +static TimeRecord getTimeRecord(bool Start) { struct rusage RU; struct timeval T; + long MemUsed; + if (Start) { + MemUsed = getMemUsage(); + if (getrusage(RUSAGE_SELF, &RU)) + perror("getrusage call failed: -time-passes info incorrect!"); + } gettimeofday(&T, 0); - if (getrusage(RUSAGE_SELF, &RU)) { - perror("getrusage call failed: -time-passes info incorrect!"); + + if (!Start) { + MemUsed = getMemUsage(); + if (getrusage(RUSAGE_SELF, &RU)) + perror("getrusage call failed: -time-passes info incorrect!"); } TimeRecord Result; Result.Elapsed = T.tv_sec + T.tv_usec/1000000.0; Result.UserTime = RU.ru_utime.tv_sec + RU.ru_utime.tv_usec/1000000.0; Result.SystemTime = RU.ru_stime.tv_sec + RU.ru_stime.tv_usec/1000000.0; - Result.MemUsed = mallinfo().uordblks; + Result.MemUsed = MemUsed; + return Result; } +static std::vector ActiveTimers; + void Timer::startTimer() { Started = true; - TimeRecord TR = getTimeRecord(); + TimeRecord TR = getTimeRecord(true); Elapsed -= TR.Elapsed; UserTime -= TR.UserTime; SystemTime -= TR.SystemTime; MemUsed -= TR.MemUsed; + PeakMemBase = TR.MemUsed; + ActiveTimers.push_back(this); } void Timer::stopTimer() { - TimeRecord TR = getTimeRecord(); + TimeRecord TR = getTimeRecord(false); Elapsed += TR.Elapsed; UserTime += TR.UserTime; SystemTime += TR.SystemTime; MemUsed += TR.MemUsed; + + if (ActiveTimers.back() == this) { + ActiveTimers.pop_back(); + } else { + std::vector::iterator I = + std::find(ActiveTimers.begin(), ActiveTimers.end(), this); + assert(I != ActiveTimers.end() && "stop but no startTimer?"); + ActiveTimers.erase(I); + } } void Timer::sum(const Timer &T) { @@ -101,8 +135,22 @@ UserTime += T.UserTime; SystemTime += T.SystemTime; MemUsed += T.MemUsed; + PeakMem += T.PeakMem; +} + +/// addPeakMemoryMeasurement - This method should be called whenever memory +/// usage needs to be checked. It adds a peak memory measurement to the +/// currently active timers, which will be printed when the timer group prints +/// +void Timer::addPeakMemoryMeasurement() { + long MemUsed = getMemUsage(); + + for (std::vector::iterator I = ActiveTimers.begin(), + E = ActiveTimers.end(); I != E; ++I) + (*I)->PeakMem = std::max((*I)->PeakMem, MemUsed-(*I)->PeakMemBase); } + //===----------------------------------------------------------------------===// // TimerGroup Implementation //===----------------------------------------------------------------------===// @@ -127,6 +175,12 @@ if (Total.MemUsed) fprintf(stderr, " %8ld ", MemUsed); + if (Total.PeakMem) { + if (PeakMem) + fprintf(stderr, " %8ld ", PeakMem); + else + fprintf(stderr, " "); + } std::cerr << Name << "\n"; Started = false; // Once printed, don't print again @@ -168,6 +222,8 @@ std::cerr << " ---Wall Time---"; if (Total.getMemUsed()) std::cerr << " ---Mem---"; + if (Total.getPeakMem()) + std::cerr << " -PeakMem-"; std::cerr << " --- Name ---\n"; // Loop through all of the timing data, printing it out... @@ -187,4 +243,61 @@ delete DefaultTimerGroup; DefaultTimerGroup = 0; } +} + + + +#if (__GNUC__ == 3) && (__GNUC_MINOR__ == 2) && (__GNUC_PATCHLEVEL__ == 0) +// If we have GCC 3.2.0, we can calculate pool allocation bookkeeping info +#define HAVE_POOL +extern "C" { + // Taken from GCC 3.2's stl_alloc.h file: + enum {_ALIGN = 8, _MAX_BYTES = 128, NFREE = _MAX_BYTES / _ALIGN}; + struct FreeList { FreeList *Next; }; + + FreeList *_ZNSt24__default_alloc_templateILb1ELi0EE12_S_free_listE[NFREE]; + char *_ZNSt24__default_alloc_templateILb1ELi0EE13_S_start_freeE; + char *_ZNSt24__default_alloc_templateILb1ELi0EE11_S_end_freeE; + size_t _ZNSt24__default_alloc_templateILb1ELi0EE12_S_heap_sizeE; + + // Make the symbols possible to use... + FreeList* (&TheFreeList)[NFREE] = _ZNSt24__default_alloc_templateILb1ELi0EE12_S_free_listE; + char * &StartFree = _ZNSt24__default_alloc_templateILb1ELi0EE13_S_start_freeE; + char * &EndFree = _ZNSt24__default_alloc_templateILb1ELi0EE11_S_end_freeE; + size_t &HeapSize = _ZNSt24__default_alloc_templateILb1ELi0EE12_S_heap_sizeE; +} +#endif + +// getNumBytesToNotCount - This function is supposed to return the number of +// bytes that are to be considered not allocated, even though malloc thinks they +// are allocated. +// +static unsigned getNumBytesToNotCount() { +#ifdef HAVE_POOL + // If we have GCC 3.2.0, we can subtract off pool allocation bookkeeping info + + // Size of the free slab section... + unsigned FreePoolMem = (unsigned)(EndFree-StartFree); + + // Walk all of the free lists, adding memory to the free counter whenever we + // have a free bucket. + for (unsigned i = 0; i != NFREE; ++i) { + unsigned NumEntries = 0; + for (FreeList *FL = TheFreeList[i]; FL; ++NumEntries, FL = FL->Next) + /*empty*/ ; + +#if 0 + if (NumEntries) + std::cerr << " For Size[" << (i+1)*_ALIGN << "]: " << NumEntries + << " Free entries\n"; +#endif + FreePoolMem += NumEntries*(i+1)*_ALIGN; + } + return FreePoolMem; + +#else +#warning "Don't know how to avoid pool allocation accounting overhead for this" +#warning " compiler: Space usage numbers (with -time-passes) may be off!" + return 0; +#endif } From hldnbrnd at cs.uiuc.edu Mon Nov 18 16:23:01 2002 From: hldnbrnd at cs.uiuc.edu (Nicholas Hildenbrandt) Date: Mon Nov 18 16:23:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200211182222.QAA06160@niobe.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.74 -> 1.75 --- Log message: (null) --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.74 llvm/lib/CWriter/Writer.cpp:1.75 --- llvm/lib/CWriter/Writer.cpp:1.74 Mon Nov 18 14:55:50 2002 +++ llvm/lib/CWriter/Writer.cpp Mon Nov 18 16:21:52 2002 @@ -156,8 +156,8 @@ string CWriter::getValueName(const Value *V) { if (V->hasName()) { // Print out the label if it exists... if (isa(V) && // Do not mangle globals... - cast(V)->hasExternalLinkage() && // Unless it's internal or - !MangledGlobals.count(V)) // Unless the name would collide if we don't + cast(V)->hasExternalLinkage())// && // Unless it's internal or + //!MangledGlobals.count(V)) // Unless the name would collide if we don't return makeNameProper(V->getName()); return "l" + utostr(V->getType()->getUniqueID()) + "_" + @@ -567,8 +567,12 @@ Out << "\n/* Function Declarations */\n"; needsMalloc = true; for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { - printFunctionSignature(I, true); - Out << ";\n"; + // If the function is external and the name collides don't print it. + // Sometimes the bytecode likes to have multiple "declerations" for external functions + if (I->hasInternalLinkage() || !MangledGlobals.count(I)){ + printFunctionSignature(I, true); + Out << ";\n"; + } } } From brukman at neo.cs.uiuc.edu Mon Nov 18 16:36:01 2002 From: brukman at neo.cs.uiuc.edu (Misha Brukman) Date: Mon Nov 18 16:36:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Reoptimizer/BinInterface/analyze.cpp fvector.h sparc9.h Message-ID: <200211182239.gAIMdMJ20841@neo.cs.uiuc.edu> Changes in directory llvm/lib/Reoptimizer/BinInterface: analyze.cpp updated: 1.2 -> 1.3 fvector.h updated: 1.1 -> 1.2 sparc9.h updated: 1.4 -> 1.5 --- Log message: * analyze.cpp - added some comments * fvector.h - added newline at end of file (gcc sometimes complains) * sparc9.h - now triple-checked (pre-processed using binproc and checked entries, they are correct), returned binary formatting to original (no spaces between each group of 4 digits) --- Diffs of the changes: Index: llvm/lib/Reoptimizer/BinInterface/analyze.cpp diff -u llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.2 llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.3 --- llvm/lib/Reoptimizer/BinInterface/analyze.cpp:1.2 Tue Nov 12 20:44:48 2002 +++ llvm/lib/Reoptimizer/BinInterface/analyze.cpp Mon Nov 18 16:39:11 2002 @@ -171,6 +171,7 @@ return 0; } +// returns which register is written to unsigned sparc_getwrites(unsigned mask, unsigned instr) { if (mask & IF_RD) @@ -179,6 +180,7 @@ return 0; } +// returns which registers are read unsigned sparc_getreads (unsigned mask, unsigned instr) { unsigned m = 0; Index: llvm/lib/Reoptimizer/BinInterface/fvector.h diff -u llvm/lib/Reoptimizer/BinInterface/fvector.h:1.1 llvm/lib/Reoptimizer/BinInterface/fvector.h:1.2 --- llvm/lib/Reoptimizer/BinInterface/fvector.h:1.1 Fri Nov 8 04:38:13 2002 +++ llvm/lib/Reoptimizer/BinInterface/fvector.h Mon Nov 18 16:39:11 2002 @@ -83,4 +83,4 @@ }; -#endif \ No newline at end of file +#endif Index: llvm/lib/Reoptimizer/BinInterface/sparc9.h diff -u llvm/lib/Reoptimizer/BinInterface/sparc9.h:1.4 llvm/lib/Reoptimizer/BinInterface/sparc9.h:1.5 --- llvm/lib/Reoptimizer/BinInterface/sparc9.h:1.4 Tue Nov 12 20:40:00 2002 +++ llvm/lib/Reoptimizer/BinInterface/sparc9.h Mon Nov 18 16:39:11 2002 @@ -177,48 +177,48 @@ // SIMM13 //********************************** -#define OP3_ADD 0x0 // 0b00 0000 -#define OP3_ADDC 0x8 // 0b00 1000 -#define OP3_AND 0x1 // 0b00 0001 -#define OP3_OR 0x2 // 0b00 0010 -#define OP3_XOR 0x3 // 0b00 0011 -#define OP3_SUB 0x4 // 0b00 0100 -#define OP3_ANDN 0x5 // 0b00 0101 -#define OP3_ORN 0x6 // 0b00 0110 -#define OP3_XNOR 0x7 // 0b00 0111 -#define OP3_SUBC 0xc // 0b00 1100 -#define OP3_ADDcc 0x10 // 0b01 0000 -#define OP3_ADDCcc 0x18 // 0b01 1000 -#define OP3_ANDcc 0x11 // 0b01 0001 -#define OP3_ORcc 0x12 // 0b01 0010 -#define OP3_XORcc 0x13 // 0b01 0011 -#define OP3_SUBcc 0x14 // 0b01 0100 -#define OP3_ANDNcc 0x15 // 0b01 0101 -#define OP3_ORNcc 0x16 // 0b01 0110 -#define OP3_XNORcc 0x17 // 0b01 0111 -#define OP3_SUBCcc 0x1c // 0b01 1100 -#define OP3_MULX 0x9 // 0b00 1001 -#define OP3_SDIVX 0x2d // 0b10 1101 -#define OP3_UDIVX 0xd // 0b00 1101 +#define OP3_ADD 0x0 // 0b000000 +#define OP3_ADDC 0x8 // 0b001000 +#define OP3_AND 0x1 // 0b000001 +#define OP3_OR 0x2 // 0b000010 +#define OP3_XOR 0x3 // 0b000011 +#define OP3_SUB 0x4 // 0b000100 +#define OP3_ANDN 0x5 // 0b000101 +#define OP3_ORN 0x6 // 0b000110 +#define OP3_XNOR 0x7 // 0b000111 +#define OP3_SUBC 0xc // 0b001100 +#define OP3_ADDcc 0x10 // 0b010000 +#define OP3_ADDCcc 0x18 // 0b011000 +#define OP3_ANDcc 0x11 // 0b010001 +#define OP3_ORcc 0x12 // 0b010010 +#define OP3_XORcc 0x13 // 0b010011 +#define OP3_SUBcc 0x14 // 0b010100 +#define OP3_ANDNcc 0x15 // 0b010101 +#define OP3_ORNcc 0x16 // 0b010110 +#define OP3_XNORcc 0x17 // 0b010111 +#define OP3_SUBCcc 0x1c // 0b011100 +#define OP3_MULX 0x9 // 0b001001 +#define OP3_SDIVX 0x2d // 0b101101 +#define OP3_UDIVX 0xd // 0b001101 //Op3 members -#define OP3_CASA 0x3c // 0b11 1100 -#define OP3_CASXA 0x3e // 0b11 1110 +#define OP3_CASA 0x3c // 0b111100 +#define OP3_CASXA 0x3e // 0b111110 //Instructions below generated with: //OP=OP_2: RD, OP_3 RS1: {I=0 -> X & RS2 ,I=1 -> {X=0 -> SHCNT32 X=1->SHCNT64 }} -#define OP3_SLL 0x25 // 0b10 0101 -#define OP3_SRL 0x26 // 0b10 0110 -#define OP3_SRA 0x27 // 0b10 0111 +#define OP3_SLL 0x25 // 0b100101 +#define OP3_SRL 0x26 // 0b100110 +#define OP3_SRA 0x27 // 0b100111 // class OP_3 -#define OP3_STFA 0x34 // 0b11 0100 -#define OP3_STDFA 0x37 // 0b11 0111 -#define OP3_STQFA 0x36 // 0b11 0110 +#define OP3_STFA 0x34 // 0b110100 +#define OP3_STDFA 0x37 // 0b110111 +#define OP3_STQFA 0x36 // 0b110110 //Instructions below generated with: //OP=OP_2: FCN -#define OP3_DONERETRY 0x3e // 0b11 1110 +#define OP3_DONERETRY 0x3e // 0b111110 #define FCN_DONE 0 #define FCN_RETRY 1 @@ -235,82 +235,82 @@ //Instructions below generated with //OP=OP_2: CC1_H, CC0_H, RS1, OPF, RS2 -#define OP3_FCMP 0x35 // 0b 11 0101 -#define OPF_FCMPn 0x50 // 0b0 0101 0000 -#define OPF_FCMPEn 0x54 // 0b0 0101 0100 +#define OP3_FCMP 0x35 // 0b110101 +#define OPF_FCMPn 0x50 // 0b001010000 +#define OPF_FCMPEn 0x54 // 0b001010100 //Instructions below generated with //OP=OP_2: RD, OP3 RS1, OPF, RS2 -#define OP3_FPU 0x34 // 0b 11 0100 -#define OPF_FADDn 0x40 // 0b0 0100 0000 -#define OPF_FSUBn 0x44 // 0b0 0100 0100 -#define OPF_FMOVn 0x0 // 0b0 0000 0000 -#define OPF_FNEGn 0x4 // 0b0 0000 0100 -#define OPF_FABSn 0x8 // 0b0 0000 1000 -#define OPF_FMULn 0x48 // 0b0 0100 1000 -#define OPF_FDIVn 0x4c // 0b0 0100 1100 -#define OPF_FSQRTn 0x28 // 0b0 0010 1000 -#define OPF_FsTOx 0x81 // 0b0 1000 0001 -#define OPF_FsTOi 0xd1 // 0b0 1101 0001 -#define OPF_FsTOd 0xc9 // 0b0 1100 1001 -#define OPF_FsTOq 0xcd // 0b0 1100 1101 -#define OPF_FdTOx 0x82 // 0b0 1000 0010 -#define OPF_FdTOi 0xd2 // 0b0 1101 0010 -#define OPF_FdTOs 0xc6 // 0b0 1100 0110 -#define OPF_FdTOq 0xce // 0b0 1100 1110 -#define OPF_FqTOx 0x83 // 0b0 1000 0011 -#define OPF_FqTOi 0xd3 // 0b0 1101 0011 -#define OPF_FqTOs 0xc7 // 0b0 1100 0111 -#define OPF_FqTOd 0xcb // 0b0 1100 1011 -#define OPF_FxTOt 0x80 // 0b0 1000 0000 -#define OPF_FiTOt 0xc0 // 0b0 1100 0000 -#define OPF_FsMULd 0x69 // 0b0 0110 1001 -#define OPF_FdMULq 0x6e // 0b0 0110 1110 - - -#define OP3_FLUSH 0x3b // 0b11 1011 //OP=OP_2 RS1 {I=0 -> rs2, I=1->simm13} -#define OP3_FLUSHW 0x2b // 0b10 1011 //OP=OP_2 I = 0 -#define OP3_JMPL 0x38 // 0b11 1000 //OP=OP_2 RD, RS1 {I=0-> RS2, I=1->SIMM13} +#define OP3_FPU 0x34 // 0b110100 +#define OPF_FADDn 0x40 // 0b001000000 +#define OPF_FSUBn 0x44 // 0b001000100 +#define OPF_FMOVn 0x0 // 0b000000000 +#define OPF_FNEGn 0x4 // 0b000000100 +#define OPF_FABSn 0x8 // 0b000001000 +#define OPF_FMULn 0x48 // 0b001001000 +#define OPF_FDIVn 0x4c // 0b001001100 +#define OPF_FSQRTn 0x28 // 0b000101000 +#define OPF_FsTOx 0x81 // 0b010000001 +#define OPF_FsTOi 0xd1 // 0b011010001 +#define OPF_FsTOd 0xc9 // 0b011001001 +#define OPF_FsTOq 0xcd // 0b011001101 +#define OPF_FdTOx 0x82 // 0b010000010 +#define OPF_FdTOi 0xd2 // 0b011010010 +#define OPF_FdTOs 0xc6 // 0b011000110 +#define OPF_FdTOq 0xce // 0b011001110 +#define OPF_FqTOx 0x83 // 0b010000011 +#define OPF_FqTOi 0xd3 // 0b011010011 +#define OPF_FqTOs 0xc7 // 0b011000111 +#define OPF_FqTOd 0xcb // 0b011001011 +#define OPF_FxTOt 0x80 // 0b010000000 +#define OPF_FiTOt 0xc0 // 0b011000000 +#define OPF_FsMULd 0x69 // 0b001101001 +#define OPF_FdMULq 0x6e // 0b001101110 + + +#define OP3_FLUSH 0x3b // 0b111011 //OP=OP_2 RS1 {I=0 -> rs2, I=1->simm13} +#define OP3_FLUSHW 0x2b // 0b101011 //OP=OP_2 I = 0 +#define OP3_JMPL 0x38 // 0b111000 //OP=OP_2 RD, RS1 {I=0-> RS2, I=1->SIMM13} //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} -#define OP3_LDFA 0x30 // 0b11 0000 +#define OP3_LDFA 0x30 // 0b110000 //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} -#define OP3_LDDFA 0x33 // 0b11 0011 +#define OP3_LDDFA 0x33 // 0b110011 //OP=OP_3 RD, Rs1, {I=0->IMM_ASI, RS2 I=1->SIMM13} -#define OP3_LDQFA 0x32 // 0b11 0010 +#define OP3_LDQFA 0x32 // 0b110010 -#define OP3_LDSTUB 0xd // 0b00 1101 //OP=OP_3 RD, Rs1 {I=0->RS2, I=1->SIMM13} -#define OP3_STB 0x5 // 0b00 0101 -#define OP3_STH 0x6 // 0b00 0110 -#define OP3_STW 0x4 // 0b00 0100 -#define OP3_STX 0x7 // 0b00 0111 -#define OP3_LDSB 0x9 // 0b00 1001 -#define OP3_LDSH 0xa // 0b00 1010 -#define OP3_LDSW 0x8 // 0b00 1000 -#define OP3_LDUB 0x1 // 0b00 0001 -#define OP3_LDUH 0x2 // 0b00 0010 -#define OP3_LDUW 0x0 // 0b00 0000 -#define OP3_LDX 0xb // 0b00 1011 +#define OP3_LDSTUB 0xd // 0b001101 //OP=OP_3 RD, Rs1 {I=0->RS2, I=1->SIMM13} +#define OP3_STB 0x5 // 0b000101 +#define OP3_STH 0x6 // 0b000110 +#define OP3_STW 0x4 // 0b000100 +#define OP3_STX 0x7 // 0b000111 +#define OP3_LDSB 0x9 // 0b001001 +#define OP3_LDSH 0xa // 0b001010 +#define OP3_LDSW 0x8 // 0b001000 +#define OP3_LDUB 0x1 // 0b000001 +#define OP3_LDUH 0x2 // 0b000010 +#define OP3_LDUW 0x0 // 0b000000 +#define OP3_LDX 0xb // 0b001011 //OP=OP_3 RD, RS1 {I=0->RS2, IMM_ASI, I=1->SIMM13} -#define OP3_LDSTUBA 0x1d // 0b01 1101 +#define OP3_LDSTUBA 0x1d // 0b011101 //OP=OP_2 CMASK, MMASK //WTF?!?! some bits get set -#define OP3_MEMBAR 0x28 // 0b10 1000 +#define OP3_MEMBAR 0x28 // 0b101000 //These two instructions are FUNKY as hell -#define OP3_FMOVcc 0x35 // 0b11 0101 //OP=OP_2 RD, COND, OPF_CC, OPF_LOW, RS2 -#define OP3_MOVcc 0x2c // 0b10 1100 // +#define OP3_FMOVcc 0x35 // 0b110101 //OP=OP_2 RD, COND, OPF_CC, OPF_LOW, RS2 +#define OP3_MOVcc 0x2c // 0b101100 // -#define OP3_POPC 0x2e // 0b10 1110 -#define OP3_PREFETCH 0x2d // 0b10 1101 -#define OP3_PREFETCHA 0x3d // 0b11 1101 -#define OP3_RETURN 0x39 // 0b11 1001 -#define OP3_SAVE 0x3c // 0b11 1100 -#define OP3_RESTORE 0x3d // 0b11 1101 +#define OP3_POPC 0x2e // 0b101110 +#define OP3_PREFETCH 0x2d // 0b101101 +#define OP3_PREFETCHA 0x3d // 0b111101 +#define OP3_RETURN 0x39 // 0b111001 +#define OP3_SAVE 0x3c // 0b111100 +#define OP3_RESTORE 0x3d // 0b111101 -#define OP3_SAVDRESTD 0x31 // 0b11 0001 +#define OP3_SAVDRESTD 0x31 // 0b110001 #define FCN_SAVED 0 #define FCN_RESTORED 1 -#define OP3_TRAP 0x3a // 0b11 1010 //integer trap +#define OP3_TRAP 0x3a // 0b111010 //integer trap From lattner at cs.uiuc.edu Tue Nov 19 03:10:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 03:10:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp X86InstrInfo.def Message-ID: <200211190909.DAA04298@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.28 -> 1.29 X86InstrInfo.def updated: 1.20 -> 1.21 --- Log message: Brian Gaeke says: lib/Target/X86/InstSelectSimple.cpp: Add a little something to visitBranchInst which supports conditional branches. lib/Target/X86/X86InstrInfo.def: Add defs of JNE, JE, CMPri8 --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.28 llvm/lib/Target/X86/InstSelectSimple.cpp:1.29 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.28 Sun Nov 17 16:33:26 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Nov 19 03:08:47 2002 @@ -386,17 +386,31 @@ BuildMI(BB, X86::RET, 0); } - /// visitBranchInst - Handle conditional and unconditional branches here. Note /// that since code layout is frozen at this point, that if we are trying to /// jump to a block that is the immediate successor of the current block, we can /// just make a fall-through. (but we don't currently). /// -void ISel::visitBranchInst(BranchInst &BI) { - if (BI.isConditional()) // Only handles unconditional branches so far... - visitInstruction(BI); +void +ISel::visitBranchInst (BranchInst & BI) +{ + if (BI.isConditional ()) + { + BasicBlock *ifTrue = BI.getSuccessor (0); + BasicBlock *ifFalse = BI.getSuccessor (1); // this is really unobvious - BuildMI(BB, X86::JMP, 1).addPCDisp(BI.getSuccessor(0)); + // simplest thing I can think of: compare condition with zero, + // followed by jump-if-equal to ifFalse, and jump-if-nonequal to + // ifTrue + unsigned int condReg = getReg (BI.getCondition ()); + BuildMI (BB, X86::CMPri8, 2, X86::EFLAGS).addReg (condReg).addZImm (0); + BuildMI (BB, X86::JNE, 1).addPCDisp (BI.getSuccessor (0)); + BuildMI (BB, X86::JE, 1).addPCDisp (BI.getSuccessor (1)); + } + else // unconditional branch + { + BuildMI (BB, X86::JMP, 1).addPCDisp (BI.getSuccessor (0)); + } } Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.20 llvm/lib/Target/X86/X86InstrInfo.def:1.21 --- llvm/lib/Target/X86/X86InstrInfo.def:1.20 Sun Nov 17 23:37:11 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Tue Nov 19 03:08:47 2002 @@ -37,6 +37,8 @@ // Flow control instructions I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void) // ret I(JMP , "jmp", 0x00, M_BRANCH_FLAG, X86II::Void) // jmp foo EB|E9 cb|w +I(JNE , "jne", 0x00, M_BRANCH_FLAG, X86II::Void) // 75 cb, or 0f 85 cw|cd +I(JE , "je", 0x00, M_BRANCH_FLAG, X86II::Void) // 74 cb, or 0f 84 cw|cd // Misc instructions I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm) // leave @@ -134,6 +136,7 @@ I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg) // compare R8,R8 38/r I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg) // compare R16,R16 39/r I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg) // compare R32,R32 39/r +I(CMPri8 , "cmp", 0x80, 0, 0) // compare R8, imm8 80 /7 ib // Sign extenders (first 3 are good for DIV/IDIV; the others are more general) I(CBW , "cbw", 0x98, 0, X86II::RawFrm) // AX = signext(AL) From lattner at cs.uiuc.edu Tue Nov 19 11:00:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 11:00:01 2002 Subject: [llvm-commits] CVS: llvm/tools/opt/Makefile Message-ID: <200211191659.KAA05590@apoc.cs.uiuc.edu> Changes in directory llvm/tools/opt: Makefile updated: 1.35 -> 1.36 --- Log message: Remove extra target.a entry --- Diffs of the changes: Index: llvm/tools/opt/Makefile diff -u llvm/tools/opt/Makefile:1.35 llvm/tools/opt/Makefile:1.36 --- llvm/tools/opt/Makefile:1.35 Mon Nov 4 14:50:57 2002 +++ llvm/tools/opt/Makefile Tue Nov 19 10:59:41 2002 @@ -2,7 +2,7 @@ TOOLNAME = opt USEDLIBS = bcreader bcwriter instrument profpaths \ - sparc target.a mapping regalloc.a sched select codegen preopts \ + sparc mapping regalloc.a sched select codegen preopts \ postopts.a \ livevar scalaropts \ ipo ipa.a datastructure transforms target.a analysis \ From lattner at cs.uiuc.edu Tue Nov 19 11:11:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 11:11:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/PassNameParser.h Message-ID: <200211191710.LAA05777@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: PassNameParser.h updated: 1.2 -> 1.3 --- Log message: Ignore options that are "" --- Diffs of the changes: Index: llvm/include/llvm/Support/PassNameParser.h diff -u llvm/include/llvm/Support/PassNameParser.h:1.2 llvm/include/llvm/Support/PassNameParser.h:1.3 --- llvm/include/llvm/Support/PassNameParser.h:1.2 Mon Sep 16 11:01:41 2002 +++ llvm/include/llvm/Support/PassNameParser.h Tue Nov 19 11:10:14 2002 @@ -46,7 +46,7 @@ inline bool ignorablePass(const PassInfo *P) const { // Ignore non-selectable and non-constructible passes! Ignore // non-optimizations. - return P->getPassArgument() == 0 || + return P->getPassArgument() == 0 || *P->getPassArgument() == 0 || (P->getNormalCtor() == 0 && P->getDataCtor() == 0 && P->getTargetCtor() == 0) || ignorablePassImpl(P); From lattner at cs.uiuc.edu Tue Nov 19 12:42:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 12:42:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Module.h Message-ID: <200211191841.MAA13022@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Module.h updated: 1.28 -> 1.29 --- Log message: Add a new Module::getNamedFunction method --- Diffs of the changes: Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.28 llvm/include/llvm/Module.h:1.29 --- llvm/include/llvm/Module.h:1.28 Fri Nov 8 14:34:00 2002 +++ llvm/include/llvm/Module.h Tue Nov 19 12:41:43 2002 @@ -86,6 +86,12 @@ /// Function *getMainFunction(); + /// getNamedFunction - Return the first function in the module with the + /// specified name, of arbitrary type. This method returns null if a function + /// with the specified name is not found. + /// + Function *getNamedFunction(const std::string &Name); + /// addTypeName - Insert an entry in the symbol table mapping Str to Type. If /// there is already an entry for this name, true is returned and the symbol /// table is not modified. From lattner at cs.uiuc.edu Tue Nov 19 12:42:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 12:42:03 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Module.cpp Message-ID: <200211191841.MAA13029@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Module.cpp updated: 1.31 -> 1.32 --- Log message: Add a new Module::getNamedFunction method --- Diffs of the changes: Index: llvm/lib/VMCore/Module.cpp diff -u llvm/lib/VMCore/Module.cpp:1.31 llvm/lib/VMCore/Module.cpp:1.32 --- llvm/lib/VMCore/Module.cpp:1.31 Fri Nov 8 14:34:02 2002 +++ llvm/lib/VMCore/Module.cpp Tue Nov 19 12:41:44 2002 @@ -182,11 +182,20 @@ return F; } - // Loop over all of the methods, trying to find main the hard way... + // Ok, try to find main the hard way... + return getNamedFunction("main"); +} + +/// getNamedFunction - Return the first function in the module with the +/// specified name, of arbitrary type. This method returns null if a function +/// with the specified name is not found. +/// +Function *Module::getNamedFunction(const std::string &Name) { + // Loop over all of the functions, looking for the function desired for (iterator I = begin(), E = end(); I != E; ++I) - if (I->getName() == "main") + if (I->getName() == Name) return I; - return 0; // Main not found... + return 0; // function not found... } From lattner at cs.uiuc.edu Tue Nov 19 12:44:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 12:44:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/ExtractFunction.cpp Message-ID: <200211191843.MAA13249@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: ExtractFunction.cpp added (r1.1) --- Log message: Move the function extractor pass from tools/extract into lib/Xform/IPO --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Nov 19 12:44:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 12:44:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/IPO.h Message-ID: <200211191843.MAA13256@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.13 -> 1.14 --- Log message: Move the function extractor pass from tools/extract into lib/Xform/IPO --- Diffs of the changes: Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.13 llvm/include/llvm/Transforms/IPO.h:1.14 --- llvm/include/llvm/Transforms/IPO.h:1.13 Wed Sep 25 19:17:18 2002 +++ llvm/include/llvm/Transforms/IPO.h Tue Nov 19 12:42:58 2002 @@ -9,6 +9,7 @@ #define LLVM_TRANSFORMS_IPO_H class Pass; +class Function; //===----------------------------------------------------------------------===// // createConstantMergePass - This function returns a new pass that merges @@ -32,6 +33,13 @@ // internal globals (functions or global variables) // Pass *createGlobalDCEPass(); + + +//===----------------------------------------------------------------------===// +// createFunctionExtractionPass - This pass deletes as much of the module as +// possible, except for the function specified. +// +Pass *createFunctionExtractionPass(Function *F); //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Tue Nov 19 12:44:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 12:44:03 2002 Subject: [llvm-commits] CVS: llvm/tools/extract/extract.cpp Message-ID: <200211191843.MAA13263@apoc.cs.uiuc.edu> Changes in directory llvm/tools/extract: extract.cpp updated: 1.12 -> 1.13 --- Log message: Move the function extractor pass from tools/extract into lib/Xform/IPO --- Diffs of the changes: Index: llvm/tools/extract/extract.cpp diff -u llvm/tools/extract/extract.cpp:1.12 llvm/tools/extract/extract.cpp:1.13 --- llvm/tools/extract/extract.cpp:1.12 Sat Oct 12 15:50:16 2002 +++ llvm/tools/extract/extract.cpp Tue Nov 19 12:42:59 2002 @@ -25,95 +25,6 @@ ExtractFunc("func", cl::desc("Specify function to extract"), cl::init("main"), cl::value_desc("function")); - -struct FunctionExtractorPass : public Pass { - bool run(Module &M) { - // Mark all global variables to be internal - for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - if (!I->isExternal()) { - I->setInitializer(0); // Make all variables external - I->setInternalLinkage(false); // Make sure it's not internal - } - - Function *Named = 0; - - // Loop over all of the functions in the module, dropping all references in - // functions that are not the named function. - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - // Check to see if this is the named function! - if (I->getName() == ExtractFunc && !I->isExternal()) { - if (Named) { // Two functions, same name? - std::cerr << "extract ERROR: Two functions named: '" << ExtractFunc - << "' found!\n"; - exit(1); - } - - // Yes, it is. Keep track of it... - Named = I; - - // Make sure it's globally accessable... - Named->setInternalLinkage(false); - } - - if (Named == 0) { - std::cerr << "Warning: Function '" << ExtractFunc << "' not found!\n"; - return false; - } - - // All of the functions may be used by global variables or the named - // function. Loop through them and create a new, external functions that - // can be "used", instead of ones with bodies. - // - std::vector NewFunctions; - - Function *Last = &M.back(); // Figure out where the last real fn is... - - for (Module::iterator I = M.begin(); ; ++I) { - if (I->getName() != ExtractFunc) { - Function *New = new Function(I->getFunctionType(), false, I->getName()); - I->setName(""); // Remove Old name - - // If it's not the named function, delete the body of the function - I->dropAllReferences(); - - M.getFunctionList().push_back(New); - NewFunctions.push_back(New); - } - - if (&*I == Last) break; // Stop after processing the last function - } - - // Now that we have replacements all set up, loop through the module, - // deleting the old functions, replacing them with the newly created - // functions. - if (!NewFunctions.empty()) { - unsigned FuncNum = 0; - Module::iterator I = M.begin(); - do { - if (I->getName() != ExtractFunc) { - // Make everything that uses the old function use the new dummy fn - I->replaceAllUsesWith(NewFunctions[FuncNum++]); - - Function *Old = I; - ++I; // Move the iterator to the new function - - // Delete the old function! - M.getFunctionList().erase(Old); - - } else { - ++I; // Skip the function we are extracting - } - } while (&*I != NewFunctions[0]); - } - - return true; - } -}; - - -static RegisterPass X("extract", "Function Extractor"); - - int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n"); @@ -123,14 +34,21 @@ return 1; } + // Figure out which function we should extract + Function *F = M.get()->getNamedFunction(ExtractFunc); + if (F == 0) { + std::cerr << argv[0] << ": program doesn't contain function named '" + << ExtractFunc << "'!\n"; + return 1; + } + // In addition to just parsing the input from GCC, we also want to spiff it up // a little bit. Do this now. // PassManager Passes; - Passes.add(new FunctionExtractorPass()); + Passes.add(createFunctionExtractionPass(F)); // Extract the function Passes.add(createGlobalDCEPass()); // Delete unreachable globals Passes.add(createFunctionResolvingPass()); // Delete prototypes - Passes.add(createConstantMergePass()); // Merge dup global constants Passes.add(createDeadTypeEliminationPass()); // Remove dead types... Passes.add(new WriteBytecodePass(&std::cout)); // Write bytecode to file... From lattner at cs.uiuc.edu Tue Nov 19 14:09:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 14:09:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PoolAllocate.cpp Message-ID: <200211192008.OAA15355@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PoolAllocate.cpp updated: 1.43 -> 1.44 --- Log message: Rename CloneFunction.h to Cloning.h --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PoolAllocate.cpp diff -u llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.43 llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.44 --- llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.43 Wed Oct 16 23:57:09 2002 +++ llvm/lib/Transforms/IPO/PoolAllocate.cpp Tue Nov 19 14:08:24 2002 @@ -10,7 +10,7 @@ #include "llvm/Pass.h" #else #include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/Utils/CloneFunction.h" +#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Analysis/DataStructure.h" #include "llvm/Module.h" #include "llvm/iMemory.h" From lattner at cs.uiuc.edu Tue Nov 19 14:44:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 14:44:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/FunctionInlining.h IPO.h Message-ID: <200211192043.OAA15506@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: FunctionInlining.h updated: 1.9 -> 1.10 IPO.h updated: 1.14 -> 1.15 --- Log message: Move inlining pass to IPO.h --- Diffs of the changes: Index: llvm/include/llvm/Transforms/FunctionInlining.h diff -u llvm/include/llvm/Transforms/FunctionInlining.h:1.9 llvm/include/llvm/Transforms/FunctionInlining.h:1.10 --- llvm/include/llvm/Transforms/FunctionInlining.h:1.9 Tue Jun 25 11:11:17 2002 +++ llvm/include/llvm/Transforms/FunctionInlining.h Tue Nov 19 14:43:24 2002 @@ -8,10 +8,6 @@ #define LLVM_TRANSFORMS_FUNCTION_INLINING_H class CallInst; -class Pass; - -Pass *createFunctionInliningPass(); - // InlineFunction - This function forcibly inlines the called function into the // basic block of the caller. This returns true if it is not possible to inline // this call. The program is still in a well defined state if this occurs Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.14 llvm/include/llvm/Transforms/IPO.h:1.15 --- llvm/include/llvm/Transforms/IPO.h:1.14 Tue Nov 19 12:42:58 2002 +++ llvm/include/llvm/Transforms/IPO.h Tue Nov 19 14:43:24 2002 @@ -55,6 +55,11 @@ // Pass *createFunctionResolvingPass(); +//===----------------------------------------------------------------------===// +// createFunctionInliningPass - Return a new pass object that uses a heuristic +// to inline direct function calls to small functions. +// +Pass *createFunctionInliningPass(); //===----------------------------------------------------------------------===// // createInternalizePass - This pass loops over all of the functions in the From lattner at cs.uiuc.edu Tue Nov 19 14:50:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 14:50:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/MutateStructTypes.cpp SimpleStructMutation.cpp Message-ID: <200211192049.OAA16258@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: MutateStructTypes.cpp updated: 1.32 -> 1.33 SimpleStructMutation.cpp updated: 1.19 -> 1.20 --- Log message: Move MutatStructTypes.h out of IPO --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/MutateStructTypes.cpp diff -u llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.32 llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.33 --- llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.32 Sun Oct 13 15:53:11 2002 +++ llvm/lib/Transforms/IPO/MutateStructTypes.cpp Tue Nov 19 14:49:40 2002 @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/IPO/MutateStructTypes.h" +#include "llvm/Transforms/MutateStructTypes.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" Index: llvm/lib/Transforms/IPO/SimpleStructMutation.cpp diff -u llvm/lib/Transforms/IPO/SimpleStructMutation.cpp:1.19 llvm/lib/Transforms/IPO/SimpleStructMutation.cpp:1.20 --- llvm/lib/Transforms/IPO/SimpleStructMutation.cpp:1.19 Wed Sep 25 19:17:21 2002 +++ llvm/lib/Transforms/IPO/SimpleStructMutation.cpp Tue Nov 19 14:49:40 2002 @@ -6,7 +6,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/IPO/MutateStructTypes.h" +#include "llvm/Transforms/MutateStructTypes.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/FindUnsafePointerTypes.h" #include "llvm/Target/TargetData.h" From lattner at cs.uiuc.edu Tue Nov 19 14:59:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 14:59:03 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Cloning.h Message-ID: <200211192058.OAA16732@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Cloning.h added (r1.1) --- Log message: Merge cloning and inlining utilities --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Nov 19 15:00:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 15:00:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200211192059.OAA16814@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneFunction.cpp updated: 1.6 -> 1.7 --- Log message: Start using the new function cloning header --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.6 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.7 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.6 Sun Jun 30 11:22:25 2002 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Tue Nov 19 14:59:39 2002 @@ -1,10 +1,10 @@ + + // FIXME: document -#include "llvm/Transforms/Utils/CloneFunction.h" +#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Function.h" -#include "llvm/BasicBlock.h" -#include "llvm/Instruction.h" #include // FIXME: This should be merged with FunctionInlining From lattner at cs.uiuc.edu Tue Nov 19 15:00:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 15:00:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionInlining.cpp Message-ID: <200211192059.OAA16821@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionInlining.cpp updated: 1.37 -> 1.38 --- Log message: Start using the new function cloning header --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/FunctionInlining.cpp diff -u llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.37 llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.38 --- llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.37 Tue Oct 1 17:38:34 2002 +++ llvm/lib/Transforms/IPO/FunctionInlining.cpp Tue Nov 19 14:59:41 2002 @@ -18,7 +18,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/FunctionInlining.h" +#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/iTerminators.h" From lattner at cs.uiuc.edu Tue Nov 19 15:01:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 15:01:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/FunctionInlining.h Message-ID: <200211192100.PAA16840@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: FunctionInlining.h (r1.10) removed --- Log message: This file is supersumed by Utils/Cloning.h --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Nov 19 15:01:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 15:01:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/CloneFunction.h Message-ID: <200211192100.PAA16845@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: CloneFunction.h (r1.1) removed --- Log message: This file is supersumed by Utils/Cloning.h --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Nov 19 15:55:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 15:55:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionInlining.cpp Message-ID: <200211192154.PAA18552@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionInlining.cpp updated: 1.38 -> 1.39 --- Log message: Rework inline pass to use cloning infrastructure to do the dirty work --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/FunctionInlining.cpp diff -u llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.38 llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.39 --- llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.38 Tue Nov 19 14:59:41 2002 +++ llvm/lib/Transforms/IPO/FunctionInlining.cpp Tue Nov 19 15:54:05 2002 @@ -32,27 +32,6 @@ static Statistic<> NumInlined("inline", "Number of functions inlined"); using std::cerr; -// RemapInstruction - Convert the instruction operands from referencing the -// current values into those specified by ValueMap. -// -static inline void RemapInstruction(Instruction *I, - std::map &ValueMap) { - - for (unsigned op = 0, E = I->getNumOperands(); op != E; ++op) { - const Value *Op = I->getOperand(op); - Value *V = ValueMap[Op]; - if (!V && (isa(Op) || isa(Op))) - continue; // Globals and constants don't get relocated - - if (!V) { - cerr << "Val = \n" << Op << "Addr = " << (void*)Op; - cerr << "\nInst = " << I; - } - assert(V && "Referenced value not in value map!"); - I->setOperand(op, V); - } -} - // InlineFunction - This function forcibly inlines the called function into the // basic block of the caller. This returns false if it is not possible to // inline this call. The program is still in a well defined state if this @@ -92,7 +71,7 @@ // function. // PHINode *PHI = 0; - if (CalledFunc->getReturnType() != Type::VoidTy) { + if (!CI->use_empty()) { // The PHI node should go at the front of the new basic block to merge all // possible incoming values. // @@ -105,102 +84,52 @@ CI->replaceAllUsesWith(PHI); } - // Keep a mapping between the original function's values and the new - // duplicated code's values. This includes all of: Function arguments, - // instruction values, constant pool entries, and basic blocks. + // Get a pointer to the last basic block in the function, which will have the + // new function inlined after it. // - std::map ValueMap; + Function::iterator LastBlock = &OrigBB->getParent()->back(); - // Add the function arguments to the mapping: (start counting at 1 to skip the - // function reference itself) - // - Function::const_aiterator PTI = CalledFunc->abegin(); - for (unsigned a = 1, E = CI->getNumOperands(); a != E; ++a, ++PTI) - ValueMap[PTI] = CI->getOperand(a); - - ValueMap[NewBB] = NewBB; // Returns get converted to reference NewBB + // Calculate the vector of arguments to pass into the function cloner... + std::vector ArgVector; + for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) + ArgVector.push_back(CI->getOperand(i)); - // Loop over all of the basic blocks in the function, inlining them as - // appropriate. Keep track of the first basic block of the function... - // - for (Function::const_iterator BB = CalledFunc->begin(); - BB != CalledFunc->end(); ++BB) { - assert(BB->getTerminator() && "BasicBlock doesn't have terminator!?!?"); - - // Create a new basic block to copy instructions into! - BasicBlock *IBB = new BasicBlock("", NewBB->getParent()); - if (BB->hasName()) IBB->setName(BB->getName()+".i"); // .i = inlined once - - ValueMap[BB] = IBB; // Add basic block mapping. - - // Make sure to capture the mapping that a return will use... - // TODO: This assumes that the RET is returning a value computed in the same - // basic block as the return was issued from! - // - const TerminatorInst *TI = BB->getTerminator(); - - // Loop over all instructions copying them over... - Instruction *NewInst; - for (BasicBlock::const_iterator II = BB->begin(); - II != --BB->end(); ++II) { - IBB->getInstList().push_back((NewInst = II->clone())); - ValueMap[II] = NewInst; // Add instruction map to value. - if (II->hasName()) - NewInst->setName(II->getName()+".i"); // .i = inlined once - } + // Since we are now done with the CallInst, we can delete it. + delete CI; - // Copy over the terminator now... - switch (TI->getOpcode()) { - case Instruction::Ret: { - const ReturnInst *RI = cast(TI); - - if (PHI) { // The PHI node should include this value! - assert(RI->getReturnValue() && "Ret should have value!"); - assert(RI->getReturnValue()->getType() == PHI->getType() && - "Ret value not consistent in function!"); - PHI->addIncoming((Value*)RI->getReturnValue(), - (BasicBlock*)cast(&*BB)); - } - - // Add a branch to the code that was after the original Call. - IBB->getInstList().push_back(new BranchInst(NewBB)); - break; - } - case Instruction::Br: - IBB->getInstList().push_back(TI->clone()); - break; - - default: - cerr << "FunctionInlining: Don't know how to handle terminator: " << TI; - abort(); - } - } + // Make a vector to capture the return instructions in the cloned function... + std::vector Returns; + // Do all of the hard part of cloning the callee into the caller... + CloneFunctionInto(OrigBB->getParent(), CalledFunc, ArgVector, Returns, ".i"); - // Loop over all of the instructions in the function, fixing up operand - // references as we go. This uses ValueMap to do all the hard work. - // - for (Function::const_iterator BB = CalledFunc->begin(); - BB != CalledFunc->end(); ++BB) { - BasicBlock *NBB = (BasicBlock*)ValueMap[BB]; + // Loop over all of the return instructions, turning them into unconditional + // branches to the merge point now... + for (unsigned i = 0, e = Returns.size(); i != e; ++i) { + ReturnInst *RI = Returns[i]; + BasicBlock *BB = RI->getParent(); + + // Add a branch to the merge point where the PHI node would live... + new BranchInst(NewBB, RI); + + if (PHI) { // The PHI node should include this value! + assert(RI->getReturnValue() && "Ret should have value!"); + assert(RI->getReturnValue()->getType() == PHI->getType() && + "Ret value not consistent in function!"); + PHI->addIncoming(RI->getReturnValue(), BB); + } - // Loop over all instructions, fixing each one as we find it... - // - for (BasicBlock::iterator II = NBB->begin(); II != NBB->end(); ++II) - RemapInstruction(II, ValueMap); + // Delete the return instruction now + BB->getInstList().erase(RI); } - if (PHI) { - RemapInstruction(PHI, ValueMap); // Fix the PHI node also... - - // Check to see if the PHI node only has one argument. This is a common - // case resulting from there only being a single return instruction in the - // function call. Because this is so common, eliminate the PHI node. - // - if (PHI->getNumIncomingValues() == 1) { - PHI->replaceAllUsesWith(PHI->getIncomingValue(0)); - PHI->getParent()->getInstList().erase(PHI); - } + // Check to see if the PHI node only has one argument. This is a common + // case resulting from there only being a single return instruction in the + // function call. Because this is so common, eliminate the PHI node. + // + if (PHI && PHI->getNumIncomingValues() == 1) { + PHI->replaceAllUsesWith(PHI->getIncomingValue(0)); + PHI->getParent()->getInstList().erase(PHI); } // Change the branch that used to go to NewBB to branch to the first basic @@ -209,10 +138,7 @@ TerminatorInst *Br = OrigBB->getTerminator(); assert(Br && Br->getOpcode() == Instruction::Br && "splitBasicBlock broken!"); - Br->setOperand(0, ValueMap[&CalledFunc->front()]); - - // Since we are now done with the CallInst, we can finally delete it. - delete CI; + Br->setOperand(0, ++LastBlock); return true; } From lattner at cs.uiuc.edu Tue Nov 19 15:55:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 15:55:04 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200211192154.PAA18559@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneFunction.cpp updated: 1.7 -> 1.8 --- Log message: Rework inline pass to use cloning infrastructure to do the dirty work --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.7 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.8 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.7 Tue Nov 19 14:59:39 2002 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Tue Nov 19 15:54:07 2002 @@ -4,6 +4,7 @@ // FIXME: document #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/iTerminators.h" #include "llvm/Function.h" #include @@ -35,9 +36,10 @@ // ArgMap values. // void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, - const std::vector &ArgMap) { - assert(OldFunc->aempty() || !NewFunc->aempty() && - "Synthesization of arguments is not implemented yet!"); + const std::vector &ArgMap, + std::vector &Returns, + const char *NameSuffix) { + assert(NameSuffix && "NameSuffix cannot be null!"); assert(OldFunc->asize() == ArgMap.size() && "Improper number of argument values to map specified!"); @@ -55,25 +57,30 @@ // Loop over all of the basic blocks in the function, cloning them as - // appropriate. + // appropriate. Note that we save BE this way in order to handle cloning of + // recursive functions into themselves. // for (Function::const_iterator BI = OldFunc->begin(), BE = OldFunc->end(); BI != BE; ++BI) { const BasicBlock &BB = *BI; - assert(BB.getTerminator() && "BasicBlock doesn't have terminator!?!?"); // Create a new basic block to copy instructions into! - BasicBlock *CBB = new BasicBlock(BB.getName(), NewFunc); + BasicBlock *CBB = new BasicBlock("", NewFunc); + if (BB.hasName()) CBB->setName(BB.getName()+NameSuffix); ValueMap[&BB] = CBB; // Add basic block mapping. // Loop over all instructions copying them over... for (BasicBlock::const_iterator II = BB.begin(), IE = BB.end(); II != IE; ++II) { Instruction *NewInst = II->clone(); - NewInst->setName(II->getName()); // Name is not cloned... + if (II->hasName()) + NewInst->setName(II->getName()+NameSuffix); // Name is not cloned... CBB->getInstList().push_back(NewInst); ValueMap[II] = NewInst; // Add instruction map to value. } + + if (ReturnInst *RI = dyn_cast(CBB->getTerminator())) + Returns.push_back(RI); } // Loop over all of the instructions in the function, fixing up operand From lattner at cs.uiuc.edu Tue Nov 19 15:55:06 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 15:55:06 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Cloning.h Message-ID: <200211192154.PAA18581@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Cloning.h updated: 1.1 -> 1.2 --- Log message: Extend function cloning interface to support inlining --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Utils/Cloning.h diff -u llvm/include/llvm/Transforms/Utils/Cloning.h:1.1 llvm/include/llvm/Transforms/Utils/Cloning.h:1.2 --- llvm/include/llvm/Transforms/Utils/Cloning.h:1.1 Tue Nov 19 14:58:38 2002 +++ llvm/include/llvm/Transforms/Utils/Cloning.h Tue Nov 19 15:54:38 2002 @@ -17,13 +17,18 @@ class BasicBlock; class Value; class CallInst; +class ReturnInst; // Clone OldFunc into NewFunc, transforming the old arguments into references to // ArgMap values. Note that if NewFunc already has basic blocks, the ones -// cloned into it will be added to the end of the function. +// cloned into it will be added to the end of the function. This function fills +// in a list of return instructions, and can optionally append the specified +// suffix to all values cloned. // void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, - const std::vector &ArgMap); + const std::vector &ArgMap, + std::vector &Returns, + const char *NameSuffix = ""); // InlineFunction - This function forcibly inlines the called function into the From lattner at cs.uiuc.edu Tue Nov 19 15:58:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 15:58:01 2002 Subject: [llvm-commits] CVS: llvm/test/Makefile.tests Message-ID: <200211192157.PAA18683@apoc.cs.uiuc.edu> Changes in directory llvm/test: Makefile.tests updated: 1.49 -> 1.50 --- Log message: Add support for bugpoint --- Diffs of the changes: Index: llvm/test/Makefile.tests diff -u llvm/test/Makefile.tests:1.49 llvm/test/Makefile.tests:1.50 --- llvm/test/Makefile.tests:1.49 Fri Nov 8 18:50:02 2002 +++ llvm/test/Makefile.tests Tue Nov 19 15:57:18 2002 @@ -44,6 +44,7 @@ LLINK = $(TOOLS)/link LANALYZE = $(TOOLS)/analyze LJELLO = $(TOOLS)/jello +LBUGPOINT= $(TOOLS)/bugpoint LCCFLAGS += -O2 -Wall LLCFLAGS = From lattner at cs.uiuc.edu Tue Nov 19 16:05:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 16:05:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200211192204.QAA18742@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneFunction.cpp updated: 1.8 -> 1.9 --- Log message: Fix two fixmes: integrate with inlining, and document --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.8 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.9 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.8 Tue Nov 19 15:54:07 2002 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Tue Nov 19 16:04:49 2002 @@ -1,14 +1,15 @@ - - - -// FIXME: document +//===- CloneFunction.cpp - Clone a function into another function ---------===// +// +// This file implements the CloneFunctionInto interface, which is used as the +// low-level function cloner. This is used by the CloneFunction and function +// inliner to do the dirty work of copying the body of a function around. +// +//===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/iTerminators.h" #include "llvm/Function.h" #include - -// FIXME: This should be merged with FunctionInlining // RemapInstruction - Convert the instruction operands from referencing the // current values into those specified by ValueMap. From lattner at cs.uiuc.edu Tue Nov 19 16:55:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 16:55:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Cloning.h Message-ID: <200211192254.QAA21336@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Cloning.h updated: 1.2 -> 1.3 --- Log message: Minor changes to cloning interface --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Utils/Cloning.h diff -u llvm/include/llvm/Transforms/Utils/Cloning.h:1.2 llvm/include/llvm/Transforms/Utils/Cloning.h:1.3 --- llvm/include/llvm/Transforms/Utils/Cloning.h:1.2 Tue Nov 19 15:54:38 2002 +++ llvm/include/llvm/Transforms/Utils/Cloning.h Tue Nov 19 16:53:58 2002 @@ -12,6 +12,7 @@ #define LLVM_TRANSFORMS_UTIlS_CLONING_H #include +#include class Module; class Function; class BasicBlock; @@ -19,6 +20,28 @@ class CallInst; class ReturnInst; +/// CloneModule - Return an exact copy of the specified module +/// +Module *CloneModule(Module *M); + +/// CloneFunction - Return a copy of the specified function, but without +/// embedding the function into another module. Also, any references specified +/// in the ValueMap are changed to refer to their mapped value instead of the +/// original one. If any of the arguments to the function are in the ValueMap, +/// the arguments are deleted from the resultant function. The ValueMap is +/// updated to include mappings from all of the instructions and basicblocks in +/// the function from their old to new values. +/// +Function *CloneFunction(const Function *F, + std::map &ValueMap); + +/// CloneFunction - Version of the function that doesn't need the ValueMap. +/// +inline Function *CloneFunction(const Function *F) { + std::map ValueMap; + return CloneFunction(F, ValueMap); +} + // Clone OldFunc into NewFunc, transforming the old arguments into references to // ArgMap values. Note that if NewFunc already has basic blocks, the ones // cloned into it will be added to the end of the function. This function fills @@ -26,7 +49,7 @@ // suffix to all values cloned. // void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, - const std::vector &ArgMap, + std::map &ValueMap, std::vector &Returns, const char *NameSuffix = ""); From lattner at cs.uiuc.edu Tue Nov 19 16:55:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 16:55:04 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/FunctionInlining.cpp Message-ID: <200211192254.QAA21343@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: FunctionInlining.cpp updated: 1.39 -> 1.40 --- Log message: Minor changes to cloning interface --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/FunctionInlining.cpp diff -u llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.39 llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.40 --- llvm/lib/Transforms/IPO/FunctionInlining.cpp:1.39 Tue Nov 19 15:54:05 2002 +++ llvm/lib/Transforms/IPO/FunctionInlining.cpp Tue Nov 19 16:53:59 2002 @@ -90,9 +90,14 @@ Function::iterator LastBlock = &OrigBB->getParent()->back(); // Calculate the vector of arguments to pass into the function cloner... - std::vector ArgVector; - for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) - ArgVector.push_back(CI->getOperand(i)); + std::map ValueMap; + assert((unsigned)std::distance(CalledFunc->abegin(), CalledFunc->aend()) == + CI->getNumOperands()-1 && "No varargs calls can be inlined yet!"); + + unsigned i = 1; + for (Function::const_aiterator I = CalledFunc->abegin(), E=CalledFunc->aend(); + I != E; ++I, ++i) + ValueMap[I] = CI->getOperand(i); // Since we are now done with the CallInst, we can delete it. delete CI; @@ -101,7 +106,7 @@ std::vector Returns; // Do all of the hard part of cloning the callee into the caller... - CloneFunctionInto(OrigBB->getParent(), CalledFunc, ArgVector, Returns, ".i"); + CloneFunctionInto(OrigBB->getParent(), CalledFunc, ValueMap, Returns, ".i"); // Loop over all of the return instructions, turning them into unconditional // branches to the merge point now... From lattner at cs.uiuc.edu Tue Nov 19 16:55:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 16:55:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200211192254.QAA21350@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneFunction.cpp updated: 1.9 -> 1.10 --- Log message: Minor changes to cloning interface --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.9 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.10 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.9 Tue Nov 19 16:04:49 2002 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Tue Nov 19 16:54:01 2002 @@ -37,25 +37,16 @@ // ArgMap values. // void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, - const std::vector &ArgMap, + std::map &ValueMap, std::vector &Returns, const char *NameSuffix) { assert(NameSuffix && "NameSuffix cannot be null!"); - assert(OldFunc->asize() == ArgMap.size() && - "Improper number of argument values to map specified!"); - // Keep a mapping between the original function's values and the new - // duplicated code's values. This includes all of: Function arguments, - // instruction values, constant pool entries, and basic blocks. - // - std::map ValueMap; - - // Add all of the function arguments to the mapping... - unsigned i = 0; +#ifndef NDEBUG for (Function::const_aiterator I = OldFunc->abegin(), E = OldFunc->aend(); - I != E; ++I, ++i) - ValueMap[I] = ArgMap[i]; - + I != E; ++I) + assert(ValueMap.count(I) && "No mapping from source argument specified!"); +#endif // Loop over all of the basic blocks in the function, cloning them as // appropriate. Note that we save BE this way in order to handle cloning of From lattner at cs.uiuc.edu Tue Nov 19 17:13:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 17:13:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200211192312.RAA21944@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneFunction.cpp updated: 1.10 -> 1.11 --- Log message: Implement the CloneFunction function --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.10 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.11 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.10 Tue Nov 19 16:54:01 2002 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Tue Nov 19 17:12:22 2002 @@ -8,6 +8,7 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/iTerminators.h" +#include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include @@ -86,4 +87,43 @@ for (BasicBlock::iterator II = NBB->begin(); II != NBB->end(); ++II) RemapInstruction(II, ValueMap); } +} + +/// CloneFunction - Return a copy of the specified function, but without +/// embedding the function into another module. Also, any references specified +/// in the ValueMap are changed to refer to their mapped value instead of the +/// original one. If any of the arguments to the function are in the ValueMap, +/// the arguments are deleted from the resultant function. The ValueMap is +/// updated to include mappings from all of the instructions and basicblocks in +/// the function from their old to new values. +/// +Function *CloneFunction(const Function *F, + std::map &ValueMap) { + std::vector ArgTypes; + + // The user might be deleting arguments to the function by specifying them in + // the ValueMap. If so, we need to not add the arguments to the arg ty vector + // + for (Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I) + if (ValueMap.count(I) == 0) // Haven't mapped the argument to anything yet? + ArgTypes.push_back(I->getType()); + + // Create a new function type... + FunctionType *FTy = FunctionType::get(F->getFunctionType()->getReturnType(), + ArgTypes, F->getFunctionType()->isVarArg()); + + // Create the new function... + Function *NewF = new Function(FTy, F->hasInternalLinkage(), F->getName()); + + // Loop over the arguments, copying the names of the mapped arguments over... + Function::aiterator DestI = NewF->abegin(); + for (Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I) + if (ValueMap.count(I)) { // Is this argument preserved? + DestI->setName(I->getName()); // Copy the name over... + ValueMap[I] = DestI; // Add mapping to ValueMap + } + + std::vector Returns; // Ignore returns cloned... + CloneFunctionInto(NewF, F, ValueMap, Returns); + return NewF; } From lattner at cs.uiuc.edu Tue Nov 19 17:14:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Nov 19 17:14:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200211192313.RAA21969@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneFunction.cpp updated: 1.11 -> 1.12 --- Log message: Remove unneccesary #include --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.11 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.12 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.11 Tue Nov 19 17:12:22 2002 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Tue Nov 19 17:12:53 2002 @@ -10,7 +10,6 @@ #include "llvm/iTerminators.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" -#include // RemapInstruction - Convert the instruction operands from referencing the // current values into those specified by ValueMap. From brukman at cs.uiuc.edu Tue Nov 19 18:48:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Nov 19 18:48:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.def Message-ID: <200211200047.SAA24389@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.def updated: 1.5 -> 1.6 --- Log message: Thanks to the R8, R16, and R32 macros, I can now deal with registers that belong to different register classes easier. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.def diff -u llvm/lib/Target/X86/X86RegisterInfo.def:1.5 llvm/lib/Target/X86/X86RegisterInfo.def:1.6 --- llvm/lib/Target/X86/X86RegisterInfo.def:1.5 Sun Nov 17 17:05:21 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.def Tue Nov 19 18:47:40 2002 @@ -8,11 +8,22 @@ //===----------------------------------------------------------------------===// // NOTE: No include guards desired - #ifndef R #errror "Must define R macro before including X86/X86RegisterInfo.def!" #endif +#ifndef R8 +#define R8(ENUM, NAME, FLAGS, TSFLAGS) R(ENUM, NAME, FLAGS, TSFLAGS) +#endif + +#ifndef R16 +#define R16(ENUM, NAME, FLAGS, TSFLAGS) R(ENUM, NAME, FLAGS, TSFLAGS) +#endif + +#ifndef R32 +#define R32(ENUM, NAME, FLAGS, TSFLAGS) R(ENUM, NAME, FLAGS, TSFLAGS) +#endif + // Arguments passed into the R macro // #1: Enum Name - This ends up being a symbol in the X86 namespace // #2: Register name - The name of the register as used by the gnu assembler @@ -33,36 +44,35 @@ // R(NoReg, "none", 0, 0) - // 32 bit registers, ordered as the processor does... -R(EAX, "EAX", MRF::INT32, 0) -R(ECX, "ECX", MRF::INT32, 0) -R(EDX, "EDX", MRF::INT32, 0) -R(EBX, "EBX", MRF::INT32, 0) -R(ESP, "ESP", MRF::INT32, 0) -R(EBP, "EBP", MRF::INT32, 0) -R(ESI, "ESI", MRF::INT32, 0) -R(EDI, "EDI", MRF::INT32, 0) +R32(EAX, "EAX", MRF::INT32, 0) +R32(ECX, "ECX", MRF::INT32, 0) +R32(EDX, "EDX", MRF::INT32, 0) +R32(EBX, "EBX", MRF::INT32, 0) +R32(ESP, "ESP", MRF::INT32, 0) +R32(EBP, "EBP", MRF::INT32, 0) +R32(ESI, "ESI", MRF::INT32, 0) +R32(EDI, "EDI", MRF::INT32, 0) // 16 bit registers, aliased with the corresponding 32 bit registers above -R(AX, "AX", MRF::INT16, 0) -R(CX, "CX", MRF::INT16, 0) -R(DX, "DX", MRF::INT16, 0) -R(BX, "BX", MRF::INT16, 0) -R(SP, "SP", MRF::INT16, 0) -R(BP, "BP", MRF::INT16, 0) -R(SI, "SI", MRF::INT16, 0) -R(DI, "DI", MRF::INT16, 0) +R16(AX, "AX", MRF::INT16, 0) +R16(CX, "CX", MRF::INT16, 0) +R16(DX, "DX", MRF::INT16, 0) +R16(BX, "BX", MRF::INT16, 0) +R16(SP, "SP", MRF::INT16, 0) +R16(BP, "BP", MRF::INT16, 0) +R16(SI, "SI", MRF::INT16, 0) +R16(DI, "DI", MRF::INT16, 0) // 8 bit registers aliased with registers above as well -R(AL, "AL", MRF::INT8, 0) -R(CL, "CL", MRF::INT8, 0) -R(DL, "DL", MRF::INT8, 0) -R(BL, "BL", MRF::INT8, 0) -R(AH, "AH", MRF::INT8, 0) -R(CH, "CH", MRF::INT8, 0) -R(DH, "DH", MRF::INT8, 0) -R(BH, "BH", MRF::INT8, 0) +R8(AL, "AL", MRF::INT8, 0) +R8(CL, "CL", MRF::INT8, 0) +R8(DL, "DL", MRF::INT8, 0) +R8(BL, "BL", MRF::INT8, 0) +R8(AH, "AH", MRF::INT8, 0) +R8(CH, "CH", MRF::INT8, 0) +R8(DH, "DH", MRF::INT8, 0) +R8(BH, "BH", MRF::INT8, 0) // Flags, Segment registers, etc... @@ -71,5 +81,8 @@ // could clobber. R(EFLAGS, "EFLAGS", MRF::INT16, 0) -// We are now done with the R macro +// We are now done with the R* macros #undef R +#undef R8 +#undef R16 +#undef R32 From brukman at cs.uiuc.edu Tue Nov 19 18:54:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Nov 19 18:54:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SSARegMap.h MachineFunction.h Message-ID: <200211200053.SAA24427@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SSARegMap.h added (r1.1) MachineFunction.h updated: 1.19 -> 1.20 --- Log message: SSARegMap -- the mapping between SSARegisters and their RegisterClasses, which imply types of SSA Registers. This is on a per-function basis, so the MachineFunction contains the SSARegMap, and has accessor functions to it. --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineFunction.h diff -u llvm/include/llvm/CodeGen/MachineFunction.h:1.19 llvm/include/llvm/CodeGen/MachineFunction.h:1.20 --- llvm/include/llvm/CodeGen/MachineFunction.h:1.19 Tue Oct 29 18:46:31 2002 +++ llvm/include/llvm/CodeGen/MachineFunction.h Tue Nov 19 18:53:10 2002 @@ -10,6 +10,7 @@ #define LLVM_CODEGEN_MACHINEFUNCTION_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/SSARegMap.h" #include "llvm/Annotation.h" #include "Support/HashExtras.h" #include "Support/hash_set" @@ -46,6 +47,9 @@ bool compiledAsLeaf; bool spillsAreaFrozen; bool automaticVarsAreaFrozen; + + // Keeping track of mapping from SSA values to registers + SSARegMap *SSARegMapping; public: MachineFunction(const Function *Fn, const TargetMachine& target); @@ -85,6 +89,15 @@ const TargetMachine &target); static void destruct(const Function *F); static MachineFunction& get(const Function *F); + + // Getting and storing SSARegMap information + const TargetRegisterClass* getRegClass(unsigned Reg) { + return SSARegMapping->getRegClass(Reg); + } + void addRegMap(unsigned Reg, const TargetRegisterClass *RegClass) { + SSARegMapping->addRegMap(Reg, RegClass); + } + void clearSSARegMap() { delete SSARegMapping; } // Provide accessors for the MachineBasicBlock list... typedef iplist BasicBlockListType; From brukman at cs.uiuc.edu Tue Nov 19 18:57:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Nov 19 18:57:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200211200056.SAA24459@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.3 -> 1.4 --- Log message: Sigh. Fixed some speling. --- Diffs of the changes: Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.3 llvm/lib/Target/X86/README.txt:1.4 --- llvm/lib/Target/X86/README.txt:1.3 Sun Nov 17 14:33:26 2002 +++ llvm/lib/Target/X86/README.txt Tue Nov 19 18:56:42 2002 @@ -104,7 +104,7 @@ lib/CodeGen ----------- -This directory will contain all of the target independant transformations (for +This directory will contain all of the target independent transformations (for example, register allocation) that we write. These transformations should only use information exposed through the Target interface, they should not include any target specific header files. @@ -112,7 +112,7 @@ lib/Target/X86 -------------- This directory contains the machine description for X86 that is required to the -rest of the compiler working. It contains any code that is truely specific to +rest of the compiler working. It contains any code that is truly specific to the X86 backend, for example the instruction selector and machine code emitter. tools/jello @@ -159,7 +159,7 @@ There are a large number of things remaining to do. Here is a partial list: -Critial path: +Critical path: ------------- 0. Finish providing SSA form. This involves keeping track of some information From brukman at cs.uiuc.edu Tue Nov 19 18:59:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Nov 19 18:59:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211200058.SAA24471@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.29 -> 1.30 --- Log message: Add mapping in MachineFunction from SSA regs to Register Classes. Also, uncovered a bug where registers were not being put in a map if they were not found... --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.29 llvm/lib/Target/X86/InstSelectSimple.cpp:1.30 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.29 Tue Nov 19 03:08:47 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Nov 19 18:58:23 2002 @@ -17,7 +17,11 @@ #include "llvm/Constants.h" #include "llvm/Pass.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Support/InstVisitor.h" +#include "llvm/Target/MRegisterInfo.h" +#include using namespace MOTy; // Get Use, Def, UseAndDef @@ -105,8 +109,14 @@ unsigned getReg(Value &V) { return getReg(&V); } // Allow references unsigned getReg(Value *V) { unsigned &Reg = RegMap[V]; - if (Reg == 0) + if (Reg == 0) { Reg = CurReg++; + RegMap[V] = Reg; + + // Add the mapping of regnumber => reg class to MachineFunction + F->addRegMap(Reg, + TM.getRegisterInfo()->getRegClassForType(V->getType())); + } // If this operand is a constant, emit the code to copy the constant into // the register here... From lattner at cs.uiuc.edu Wed Nov 20 12:08:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:08:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Function.h Message-ID: <200211201807.MAA03229@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Function.h updated: 1.38 -> 1.39 --- Log message: Eliminate the concept of a deferred symbol table. The optimization really isn't, and it causes obscure bugs to show up in passes. --- Diffs of the changes: Index: llvm/include/llvm/Function.h diff -u llvm/include/llvm/Function.h:1.38 llvm/include/llvm/Function.h:1.39 --- llvm/include/llvm/Function.h:1.38 Tue Oct 15 16:26:24 2002 +++ llvm/include/llvm/Function.h Wed Nov 20 12:07:46 2002 @@ -111,22 +111,12 @@ //===--------------------------------------------------------------------===// // Symbol Table Accessing functions... - /// hasSymbolTable() - Returns true if there is a symbol table allocated to - /// this object AND if there is at least one name in it! - /// - bool hasSymbolTable() const; - - /// getSymbolTable() - CAUTION: The current symbol table may be null if there - /// are no names (ie, the symbol table is empty) + /// getSymbolTable() - Return the symbol table... /// inline SymbolTable *getSymbolTable() { return SymTab; } inline const SymbolTable *getSymbolTable() const { return SymTab; } - - /// getSymbolTableSure is guaranteed to not return a null pointer, because if - /// the function does not already have a symtab, one is created. Use this if - /// you intend to put something into the symbol table for the function. - /// - SymbolTable *getSymbolTableSure(); // Implemented in Value.cpp + SymbolTable *getSymbolTableSure() { return SymTab; } + bool hasSymbolTable() const { return true; } //===--------------------------------------------------------------------===// From lattner at cs.uiuc.edu Wed Nov 20 12:08:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:08:05 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Message-ID: <200211201807.MAA03236@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.34 -> 1.35 --- Log message: Eliminate the concept of a deferred symbol table. The optimization really isn't, and it causes obscure bugs to show up in passes. --- Diffs of the changes: Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.34 llvm/lib/VMCore/Function.cpp:1.35 --- llvm/lib/VMCore/Function.cpp:1.34 Tue Oct 15 16:26:29 2002 +++ llvm/lib/VMCore/Function.cpp Wed Nov 20 12:07:48 2002 @@ -84,7 +84,7 @@ BasicBlocks.setParent(this); ArgumentList.setItemParent(this); ArgumentList.setParent(this); - SymTab = 0; + SymTab = new SymbolTable(); // Create the arguments vector, all arguments start out unnamed. for (unsigned i = 0, e = Ty->getNumParams(); i != e; ++i) { @@ -136,27 +136,6 @@ const Type *Function::getReturnType() const { return getFunctionType()->getReturnType(); } - -SymbolTable *Function::getSymbolTableSure() { - if (!SymTab) SymTab = new SymbolTable(); - return SymTab; -} - -// hasSymbolTable() - Returns true if there is a symbol table allocated to -// this object AND if there is at least one name in it! -// -bool Function::hasSymbolTable() const { - if (!SymTab) return false; - - for (SymbolTable::const_iterator I = SymTab->begin(); - I != SymTab->end(); ++I) { - if (I->second.begin() != I->second.end()) - return true; // Found nonempty type plane! - } - - return false; -} - // dropAllReferences() - This function causes all the subinstructions to "let // go" of all references that they are maintaining. This allows one to From lattner at cs.uiuc.edu Wed Nov 20 12:32:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:32:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Function.h Module.h Message-ID: <200211201831.MAA05641@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Function.h updated: 1.39 -> 1.40 Module.h updated: 1.29 -> 1.30 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/include/llvm/Function.h diff -u llvm/include/llvm/Function.h:1.39 llvm/include/llvm/Function.h:1.40 --- llvm/include/llvm/Function.h:1.39 Wed Nov 20 12:07:46 2002 +++ llvm/include/llvm/Function.h Wed Nov 20 12:31:31 2002 @@ -113,10 +113,8 @@ /// getSymbolTable() - Return the symbol table... /// - inline SymbolTable *getSymbolTable() { return SymTab; } - inline const SymbolTable *getSymbolTable() const { return SymTab; } - SymbolTable *getSymbolTableSure() { return SymTab; } - bool hasSymbolTable() const { return true; } + inline SymbolTable &getSymbolTable() { return *SymTab; } + inline const SymbolTable &getSymbolTable() const { return *SymTab; } //===--------------------------------------------------------------------===// Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.29 llvm/include/llvm/Module.h:1.30 --- llvm/include/llvm/Module.h:1.29 Tue Nov 19 12:41:43 2002 +++ llvm/include/llvm/Module.h Wed Nov 20 12:31:31 2002 @@ -113,22 +113,11 @@ //===--------------------------------------------------------------------===// // Symbol table support functions... - /// hasSymbolTable() - Returns true if there is a symbol table allocated to - /// this object AND if there is at least one name in it! + /// getSymbolTable() - Get access to the symbol table for the module, where + /// global variables and functions are identified. /// - bool hasSymbolTable() const; - - /// getSymbolTable() - CAUTION: The current symbol table may be null if there - /// are no names (ie, the symbol table is empty) - /// - inline SymbolTable *getSymbolTable() { return SymTab; } - inline const SymbolTable *getSymbolTable() const { return SymTab; } - - /// getSymbolTableSure is guaranteed to not return a null pointer, because if - /// the method does not already have a symtab, one is created. Use this if - /// you intend to put something into the symbol table for the method. - /// - SymbolTable *getSymbolTableSure(); + inline SymbolTable &getSymbolTable() { return *SymTab; } + inline const SymbolTable &getSymbolTable() const { return *SymTab; } //===--------------------------------------------------------------------===// From lattner at cs.uiuc.edu Wed Nov 20 12:33:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:33:01 2002 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y Message-ID: <200211201832.MAA05681@apoc.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: llvmAsmParser.y updated: 1.98 -> 1.99 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.98 llvm/lib/AsmParser/llvmAsmParser.y:1.99 --- llvm/lib/AsmParser/llvmAsmParser.y:1.98 Tue Oct 15 16:41:14 2002 +++ llvm/lib/AsmParser/llvmAsmParser.y Wed Nov 20 12:31:57 2002 @@ -211,16 +211,18 @@ case ValID::NameVal: { // Is it a named definition? string Name(D.Name); SymbolTable *SymTab = 0; - if (inFunctionScope()) SymTab = CurMeth.CurrentFunction->getSymbolTable(); - Value *N = SymTab ? SymTab->lookup(Type::TypeTy, Name) : 0; + Value *N = 0; + if (inFunctionScope()) { + SymTab = &CurMeth.CurrentFunction->getSymbolTable(); + N = SymTab->lookup(Type::TypeTy, Name); + } if (N == 0) { // Symbol table doesn't automatically chain yet... because the function // hasn't been added to the module... // - SymTab = CurModule.CurrentModule->getSymbolTable(); - if (SymTab) - N = SymTab->lookup(Type::TypeTy, Name); + SymTab = &CurModule.CurrentModule->getSymbolTable(); + N = SymTab->lookup(Type::TypeTy, Name); if (N == 0) break; } @@ -251,10 +253,10 @@ } static Value *lookupInSymbolTable(const Type *Ty, const string &Name) { - SymbolTable *SymTab = + SymbolTable &SymTab = inFunctionScope() ? CurMeth.CurrentFunction->getSymbolTable() : CurModule.CurrentModule->getSymbolTable(); - return SymTab ? SymTab->lookup(Ty, Name) : 0; + return SymTab.lookup(Ty, Name); } // getValNonImprovising - Look up the value specified by the provided type and @@ -481,11 +483,11 @@ ThrowException("Can't assign name '" + Name + "' to a null valued instruction!"); - SymbolTable *ST = inFunctionScope() ? - CurMeth.CurrentFunction->getSymbolTableSure() : - CurModule.CurrentModule->getSymbolTableSure(); + SymbolTable &ST = inFunctionScope() ? + CurMeth.CurrentFunction->getSymbolTable() : + CurModule.CurrentModule->getSymbolTable(); - Value *Existing = ST->lookup(V->getType(), Name); + Value *Existing = ST.lookup(V->getType(), Name); if (Existing) { // Inserting a name that is already defined??? // There is only one case where this is allowed: when we are refining an // opaque type. In this case, Existing will be an opaque type. @@ -528,7 +530,7 @@ V->getType()->getDescription() + "' type plane!"); } - V->setName(Name, ST); + V->setName(Name, &ST); return false; } From lattner at cs.uiuc.edu Wed Nov 20 12:33:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:33:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp Message-ID: <200211201832.MAA05688@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.40 -> 1.41 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.40 llvm/lib/Bytecode/Reader/Reader.cpp:1.41 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.40 Tue Oct 22 19:51:54 2002 +++ llvm/lib/Bytecode/Reader/Reader.cpp Wed Nov 20 12:31:59 2002 @@ -338,7 +338,7 @@ case BytecodeFormat::SymbolTable: BCR_TRACE(2, "BLOCK BytecodeFormat::SymbolTable: {\n"); - if (ParseSymbolTable(Buf, Buf+Size, M->getSymbolTableSure())) { + if (ParseSymbolTable(Buf, Buf+Size, &M->getSymbolTable())) { delete M; return true; } break; @@ -543,7 +543,7 @@ case BytecodeFormat::SymbolTable: BCR_TRACE(1, "BLOCK BytecodeFormat::SymbolTable: {\n"); - if (ParseSymbolTable(Buf, Buf+Size, Mod->getSymbolTableSure())) { + if (ParseSymbolTable(Buf, Buf+Size, &Mod->getSymbolTable())) { delete Mod; return true; } break; From lattner at cs.uiuc.edu Wed Nov 20 12:33:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:33:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Writer/Writer.cpp Message-ID: <200211201832.MAA05695@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Writer: Writer.cpp updated: 1.29 -> 1.30 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/Bytecode/Writer/Writer.cpp diff -u llvm/lib/Bytecode/Writer/Writer.cpp:1.29 llvm/lib/Bytecode/Writer/Writer.cpp:1.30 --- llvm/lib/Bytecode/Writer/Writer.cpp:1.29 Sun Oct 13 22:34:17 2002 +++ llvm/lib/Bytecode/Writer/Writer.cpp Wed Nov 20 12:32:01 2002 @@ -58,8 +58,7 @@ processMethod(I); // If needed, output the symbol table for the module... - if (M->hasSymbolTable()) - outputSymbolTable(*M->getSymbolTable()); + outputSymbolTable(M->getSymbolTable()); } // Helper function for outputConstants(). @@ -187,8 +186,7 @@ processBasicBlock(*I); // If needed, output the symbol table for the function... - if (F->hasSymbolTable()) - outputSymbolTable(*F->getSymbolTable()); + outputSymbolTable(F->getSymbolTable()); Table.purgeFunction(); } From lattner at cs.uiuc.edu Wed Nov 20 12:33:07 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:33:07 2002 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200211201832.MAA05702@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.75 -> 1.76 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.75 llvm/lib/CWriter/Writer.cpp:1.76 --- llvm/lib/CWriter/Writer.cpp:1.75 Mon Nov 18 16:21:52 2002 +++ llvm/lib/CWriter/Writer.cpp Wed Nov 20 12:32:03 2002 @@ -485,10 +485,10 @@ // Loop over the module symbol table, removing types from UT that are already // named. // - SymbolTable *MST = M.getSymbolTableSure(); - if (MST->find(Type::TypeTy) != MST->end()) - for (SymbolTable::type_iterator I = MST->type_begin(Type::TypeTy), - E = MST->type_end(Type::TypeTy); I != E; ++I) + SymbolTable &MST = M.getSymbolTable(); + if (MST.find(Type::TypeTy) != MST.end()) + for (SymbolTable::type_iterator I = MST.type_begin(Type::TypeTy), + E = MST.type_end(Type::TypeTy); I != E; ++I) UT.erase(cast(I->second)); // UT now contains types that are not named. Loop over it, naming structure @@ -498,7 +498,7 @@ for (std::set::const_iterator I = UT.begin(), E = UT.end(); I != E; ++I) if (const StructType *ST = dyn_cast(*I)) { - ((Value*)ST)->setName("unnamed", MST); + ((Value*)ST)->setName("unnamed", &MST); Changed = true; } return Changed; @@ -547,8 +547,7 @@ // // Loop over the symbol table, emitting all named constants... - if (M->hasSymbolTable()) - printSymbolTable(*M->getSymbolTable()); + printSymbolTable(M->getSymbolTable()); // Global variable declarations... if (!M->gempty()) { From lattner at cs.uiuc.edu Wed Nov 20 12:33:09 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:33:09 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneFunction.cpp Message-ID: <200211201832.MAA05733@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneFunction.cpp updated: 1.12 -> 1.13 --- Log message: Fix minor bugs --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.12 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.13 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.12 Tue Nov 19 17:12:53 2002 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Wed Nov 20 12:32:31 2002 @@ -117,9 +117,9 @@ // Loop over the arguments, copying the names of the mapped arguments over... Function::aiterator DestI = NewF->abegin(); for (Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I) - if (ValueMap.count(I)) { // Is this argument preserved? + if (ValueMap.count(I) == 0) { // Is this argument preserved? DestI->setName(I->getName()); // Copy the name over... - ValueMap[I] = DestI; // Add mapping to ValueMap + ValueMap[I] = DestI++; // Add mapping to ValueMap } std::vector Returns; // Ignore returns cloned... From lattner at cs.uiuc.edu Wed Nov 20 12:35:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:35:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/LevelRaise.cpp Message-ID: <200211201834.MAA06040@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: LevelRaise.cpp updated: 1.75 -> 1.76 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/Transforms/LevelRaise.cpp diff -u llvm/lib/Transforms/LevelRaise.cpp:1.75 llvm/lib/Transforms/LevelRaise.cpp:1.76 --- llvm/lib/Transforms/LevelRaise.cpp:1.75 Tue Oct 22 18:34:11 2002 +++ llvm/lib/Transforms/LevelRaise.cpp Wed Nov 20 12:34:35 2002 @@ -209,7 +209,7 @@ if (!Src->hasName() && CI->hasName()) { std::string Name = CI->getName(); CI->setName(""); - Src->setName(Name, BB->getParent()->getSymbolTable()); + Src->setName(Name, &BB->getParent()->getSymbolTable()); } // DCE the instruction now, to avoid having the iterative version of DCE From lattner at cs.uiuc.edu Wed Nov 20 12:35:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:35:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/DeadTypeElimination.cpp FunctionResolution.cpp Message-ID: <200211201834.MAA06049@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: DeadTypeElimination.cpp updated: 1.41 -> 1.42 FunctionResolution.cpp updated: 1.16 -> 1.17 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/DeadTypeElimination.cpp diff -u llvm/lib/Transforms/IPO/DeadTypeElimination.cpp:1.41 llvm/lib/Transforms/IPO/DeadTypeElimination.cpp:1.42 --- llvm/lib/Transforms/IPO/DeadTypeElimination.cpp:1.41 Tue Oct 1 17:38:36 2002 +++ llvm/lib/Transforms/IPO/DeadTypeElimination.cpp Wed Nov 20 12:34:36 2002 @@ -63,35 +63,34 @@ bool DTE::run(Module &M) { bool Changed = false; - if (SymbolTable *ST = M.getSymbolTable()) { - const std::set &UsedTypes = - getAnalysis().getTypes(); + SymbolTable &ST = M.getSymbolTable(); + const std::set &UsedTypes = + getAnalysis().getTypes(); - // Check the symbol table for superfluous type entries... - // - // Grab the 'type' plane of the module symbol... - SymbolTable::iterator STI = ST->find(Type::TypeTy); - if (STI != ST->end()) { - // Loop over all entries in the type plane... - SymbolTable::VarMap &Plane = STI->second; - for (SymbolTable::VarMap::iterator PI = Plane.begin(); PI != Plane.end();) - // If this entry should be unconditionally removed, or if we detect that - // the type is not used, remove it. - // - if (ShouldNukeSymtabEntry(*PI) || - !UsedTypes.count(cast(PI->second))) { + // Check the symbol table for superfluous type entries... + // + // Grab the 'type' plane of the module symbol... + SymbolTable::iterator STI = ST.find(Type::TypeTy); + if (STI != ST.end()) { + // Loop over all entries in the type plane... + SymbolTable::VarMap &Plane = STI->second; + for (SymbolTable::VarMap::iterator PI = Plane.begin(); PI != Plane.end();) + // If this entry should be unconditionally removed, or if we detect that + // the type is not used, remove it. + // + if (ShouldNukeSymtabEntry(*PI) || + !UsedTypes.count(cast(PI->second))) { #if MAP_IS_NOT_BRAINDEAD - PI = Plane.erase(PI); // STD C++ Map should support this! + PI = Plane.erase(PI); // STD C++ Map should support this! #else - Plane.erase(PI); // Alas, GCC 2.95.3 doesn't *SIGH* - PI = Plane.begin(); + Plane.erase(PI); // Alas, GCC 2.95.3 doesn't *SIGH* + PI = Plane.begin(); #endif - ++NumKilled; - Changed = true; - } else { - ++PI; - } - } + ++NumKilled; + Changed = true; + } else { + ++PI; + } } return Changed; Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.16 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.17 --- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.16 Sat Nov 9 21:36:55 2002 +++ llvm/lib/Transforms/IPO/FunctionResolution.cpp Wed Nov 20 12:34:36 2002 @@ -304,8 +304,7 @@ } bool FunctionResolvingPass::run(Module &M) { - SymbolTable *ST = M.getSymbolTable(); - if (!ST) return false; + SymbolTable &ST = M.getSymbolTable(); std::map > Globals; @@ -313,7 +312,7 @@ // then add it to the Functions map. We do a two pass algorithm here to avoid // problems with iterators getting invalidated if we did a one pass scheme. // - for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I) + for (SymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I) if (const PointerType *PT = dyn_cast(I->first)) { SymbolTable::VarMap &Plane = I->second; for (SymbolTable::type_iterator PI = Plane.begin(), PE = Plane.end(); From lattner at cs.uiuc.edu Wed Nov 20 12:35:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:35:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SymbolStripping.cpp Message-ID: <200211201834.MAA06056@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SymbolStripping.cpp updated: 1.20 -> 1.21 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/SymbolStripping.cpp diff -u llvm/lib/Transforms/Scalar/SymbolStripping.cpp:1.20 llvm/lib/Transforms/Scalar/SymbolStripping.cpp:1.21 --- llvm/lib/Transforms/Scalar/SymbolStripping.cpp:1.20 Fri Sep 13 22:04:02 2002 +++ llvm/lib/Transforms/Scalar/SymbolStripping.cpp Wed Nov 20 12:34:38 2002 @@ -19,20 +19,19 @@ #include "llvm/SymbolTable.h" #include "llvm/Pass.h" -static bool StripSymbolTable(SymbolTable *SymTab) { - if (SymTab == 0) return false; // No symbol table? No problem. +static bool StripSymbolTable(SymbolTable &SymTab) { bool RemovedSymbol = false; - for (SymbolTable::iterator I = SymTab->begin(); I != SymTab->end(); ++I) { + for (SymbolTable::iterator I = SymTab.begin(); I != SymTab.end(); ++I) { std::map &Plane = I->second; SymbolTable::type_iterator B; while ((B = Plane.begin()) != Plane.end()) { // Found nonempty type plane! Value *V = B->second; if (isa(V) || isa(V)) - SymTab->type_remove(B); + SymTab.type_remove(B); else - V->setName("", SymTab); // Set name to "", removing from symbol table! + V->setName("", &SymTab); // Set name to "", removing from symbol table! RemovedSymbol = true; assert(Plane.begin() != B && "Symbol not removed from table!"); } From lattner at cs.uiuc.edu Wed Nov 20 12:35:07 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:35:07 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/BasicBlockUtils.cpp Linker.cpp Message-ID: <200211201834.MAA06065@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: BasicBlockUtils.cpp updated: 1.4 -> 1.5 Linker.cpp updated: 1.33 -> 1.34 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/BasicBlockUtils.cpp diff -u llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:1.4 llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:1.5 --- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp:1.4 Tue Oct 29 17:04:01 2002 +++ llvm/lib/Transforms/Utils/BasicBlockUtils.cpp Wed Nov 20 12:34:39 2002 @@ -28,7 +28,7 @@ // Make sure to propagate a name if there is one already... if (OldName.size() && !V->hasName()) - V->setName(OldName, BIL.getParent()->getSymbolTable()); + V->setName(OldName, &BIL.getParent()->getSymbolTable()); } Index: llvm/lib/Transforms/Utils/Linker.cpp diff -u llvm/lib/Transforms/Utils/Linker.cpp:1.33 llvm/lib/Transforms/Utils/Linker.cpp:1.34 --- llvm/lib/Transforms/Utils/Linker.cpp:1.33 Sun Oct 13 15:53:12 2002 +++ llvm/lib/Transforms/Utils/Linker.cpp Wed Nov 20 12:34:39 2002 @@ -32,11 +32,8 @@ // Make sure there are no type name conflicts. // static bool LinkTypes(Module *Dest, const Module *Src, string *Err = 0) { - // No symbol table? Can't have named types. - if (!Src->hasSymbolTable()) return false; - - SymbolTable *DestST = Dest->getSymbolTableSure(); - const SymbolTable *SrcST = Src->getSymbolTable(); + SymbolTable *DestST = &Dest->getSymbolTable(); + const SymbolTable *SrcST = &Src->getSymbolTable(); // Look for a type plane for Type's... SymbolTable::const_iterator PI = SrcST->find(Type::TypeTy); @@ -176,7 +173,7 @@ map &ValueMap, string *Err = 0) { // We will need a module level symbol table if the src module has a module // level symbol table... - SymbolTable *ST = Src->getSymbolTable() ? Dest->getSymbolTableSure() : 0; + SymbolTable *ST = (SymbolTable*)&Src->getSymbolTable(); // Loop over all of the globals in the src module, mapping them over as we go // @@ -266,7 +263,7 @@ string *Err = 0) { // We will need a module level symbol table if the src module has a module // level symbol table... - SymbolTable *ST = Src->getSymbolTable() ? Dest->getSymbolTableSure() : 0; + SymbolTable *ST = (SymbolTable*)&Src->getSymbolTable(); // Loop over all of the functions in the src module, mapping them over as we // go From lattner at cs.uiuc.edu Wed Nov 20 12:35:09 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:35:09 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp BasicBlock.cpp Function.cpp Instruction.cpp Module.cpp SlotCalculator.cpp SymbolTableListTraitsImpl.h Verifier.cpp Message-ID: <200211201834.MAA06084@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.79 -> 1.80 BasicBlock.cpp updated: 1.28 -> 1.29 Function.cpp updated: 1.35 -> 1.36 Instruction.cpp updated: 1.20 -> 1.21 Module.cpp updated: 1.32 -> 1.33 SlotCalculator.cpp updated: 1.24 -> 1.25 SymbolTableListTraitsImpl.h updated: 1.2 -> 1.3 Verifier.cpp updated: 1.41 -> 1.42 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.79 llvm/lib/VMCore/AsmWriter.cpp:1.80 --- llvm/lib/VMCore/AsmWriter.cpp:1.79 Sun Oct 13 15:57:00 2002 +++ llvm/lib/VMCore/AsmWriter.cpp Wed Nov 20 12:33:41 2002 @@ -74,20 +74,19 @@ // static void fillTypeNameTable(const Module *M, map &TypeNames) { - if (M && M->hasSymbolTable()) { - const SymbolTable *ST = M->getSymbolTable(); - SymbolTable::const_iterator PI = ST->find(Type::TypeTy); - if (PI != ST->end()) { - SymbolTable::type_const_iterator I = PI->second.begin(); - for (; I != PI->second.end(); ++I) { - // As a heuristic, don't insert pointer to primitive types, because - // they are used too often to have a single useful name. - // - const Type *Ty = cast(I->second); - if (!isa(Ty) || - !cast(Ty)->getElementType()->isPrimitiveType()) - TypeNames.insert(std::make_pair(Ty, "%"+I->first)); - } + if (!M) return; + const SymbolTable &ST = M->getSymbolTable(); + SymbolTable::const_iterator PI = ST.find(Type::TypeTy); + if (PI != ST.end()) { + SymbolTable::type_const_iterator I = PI->second.begin(); + for (; I != PI->second.end(); ++I) { + // As a heuristic, don't insert pointer to primitive types, because + // they are used too often to have a single useful name. + // + const Type *Ty = cast(I->second); + if (!isa(Ty) || + !cast(Ty)->getElementType()->isPrimitiveType()) + TypeNames.insert(std::make_pair(Ty, "%"+I->first)); } } } @@ -200,7 +199,7 @@ // If they want us to print out a type, attempt to make it symbolic if there // is a symbol table in the module... - if (M && M->hasSymbolTable()) { + if (M) { map TypeNames; fillTypeNameTable(M, TypeNames); @@ -406,7 +405,7 @@ map TypeNames; if (Context == 0) Context = getModuleFromVal(V); - if (Context && Context->hasSymbolTable()) + if (Context) fillTypeNameTable(Context, TypeNames); if (PrintType) @@ -524,8 +523,7 @@ void AssemblyWriter::printModule(const Module *M) { // Loop over the symbol table, emitting all named constants... - if (M->hasSymbolTable()) - printSymbolTable(*M->getSymbolTable()); + printSymbolTable(M->getSymbolTable()); for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I) printGlobal(I); Index: llvm/lib/VMCore/BasicBlock.cpp diff -u llvm/lib/VMCore/BasicBlock.cpp:1.28 llvm/lib/VMCore/BasicBlock.cpp:1.29 --- llvm/lib/VMCore/BasicBlock.cpp:1.28 Sun Oct 13 14:39:16 2002 +++ llvm/lib/VMCore/BasicBlock.cpp Wed Nov 20 12:33:41 2002 @@ -105,11 +105,11 @@ // Specialize setName to take care of symbol table majik void BasicBlock::setName(const std::string &name, SymbolTable *ST) { Function *P; - assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) && + assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) && "Invalid symtab argument!"); - if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this); + if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this); Value::setName(name); - if (P && hasName()) P->getSymbolTable()->insert(this); + if (P && hasName()) P->getSymbolTable().insert(this); } TerminatorInst *BasicBlock::getTerminator() { Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.35 llvm/lib/VMCore/Function.cpp:1.36 --- llvm/lib/VMCore/Function.cpp:1.35 Wed Nov 20 12:07:48 2002 +++ llvm/lib/VMCore/Function.cpp Wed Nov 20 12:33:41 2002 @@ -57,11 +57,11 @@ // Specialize setName to take care of symbol table majik void Argument::setName(const std::string &name, SymbolTable *ST) { Function *P; - assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) && + assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) && "Invalid symtab argument!"); - if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this); + if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this); Value::setName(name); - if (P && hasName()) P->getSymbolTableSure()->insert(this); + if (P && hasName()) P->getSymbolTable().insert(this); } void Argument::setParent(Function *parent) { @@ -114,11 +114,11 @@ // Specialize setName to take care of symbol table majik void Function::setName(const std::string &name, SymbolTable *ST) { Module *P; - assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) && + assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) && "Invalid symtab argument!"); - if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this); + if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this); Value::setName(name); - if (P && getName() != "") P->getSymbolTableSure()->insert(this); + if (P && getName() != "") P->getSymbolTable().insert(this); } void Function::setParent(Module *parent) { @@ -178,9 +178,9 @@ // Specialize setName to take care of symbol table majik void GlobalVariable::setName(const std::string &name, SymbolTable *ST) { Module *P; - assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) && + assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) && "Invalid symtab argument!"); - if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this); + if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this); Value::setName(name); - if (P && getName() != "") P->getSymbolTableSure()->insert(this); + if (P && getName() != "") P->getSymbolTable().insert(this); } Index: llvm/lib/VMCore/Instruction.cpp diff -u llvm/lib/VMCore/Instruction.cpp:1.20 llvm/lib/VMCore/Instruction.cpp:1.21 --- llvm/lib/VMCore/Instruction.cpp:1.20 Wed Oct 30 22:14:01 2002 +++ llvm/lib/VMCore/Instruction.cpp Wed Nov 20 12:33:41 2002 @@ -40,12 +40,12 @@ void Instruction::setName(const std::string &name, SymbolTable *ST) { BasicBlock *P = 0; Function *PP = 0; assert((ST == 0 || !getParent() || !getParent()->getParent() || - ST == getParent()->getParent()->getSymbolTable()) && + ST == &getParent()->getParent()->getSymbolTable()) && "Invalid symtab argument!"); if ((P = getParent()) && (PP = P->getParent()) && hasName()) - PP->getSymbolTable()->remove(this); + PP->getSymbolTable().remove(this); Value::setName(name); - if (PP && hasName()) PP->getSymbolTableSure()->insert(this); + if (PP && hasName()) PP->getSymbolTable().insert(this); } Index: llvm/lib/VMCore/Module.cpp diff -u llvm/lib/VMCore/Module.cpp:1.32 llvm/lib/VMCore/Module.cpp:1.33 --- llvm/lib/VMCore/Module.cpp:1.32 Tue Nov 19 12:41:44 2002 +++ llvm/lib/VMCore/Module.cpp Wed Nov 20 12:33:41 2002 @@ -57,7 +57,7 @@ GlobalList.setItemParent(this); GlobalList.setParent(this); GVRefMap = 0; - SymTab = 0; + SymTab = new SymbolTable(); } Module::~Module() { @@ -74,26 +74,6 @@ print(std::cerr); } -SymbolTable *Module::getSymbolTableSure() { - if (!SymTab) SymTab = new SymbolTable(); - return SymTab; -} - -// hasSymbolTable() - Returns true if there is a symbol table allocated to -// this object AND if there is at least one name in it! -// -bool Module::hasSymbolTable() const { - if (!SymTab) return false; - - for (SymbolTable::const_iterator I = SymTab->begin(), E = SymTab->end(); - I != E; ++I) - if (I->second.begin() != I->second.end()) - return true; // Found nonempty type plane! - - return false; -} - - // getOrInsertFunction - Look up the specified function in the module symbol // table. If it does not exist, add a prototype for the function and return // it. This is nice because it allows most passes to get away with not handling @@ -101,10 +81,10 @@ // Function *Module::getOrInsertFunction(const std::string &Name, const FunctionType *Ty) { - SymbolTable *SymTab = getSymbolTableSure(); + SymbolTable &SymTab = getSymbolTable(); // See if we have a definitions for the specified function already... - if (Value *V = SymTab->lookup(PointerType::get(Ty), Name)) { + if (Value *V = SymTab.lookup(PointerType::get(Ty), Name)) { return cast(V); // Yup, got it } else { // Nope, add one Function *New = new Function(Ty, false, Name); @@ -117,10 +97,8 @@ // If it does not exist, return null. // Function *Module::getFunction(const std::string &Name, const FunctionType *Ty) { - SymbolTable *SymTab = getSymbolTable(); - if (SymTab == 0) return 0; // No symtab, no symbols... - - return cast_or_null(SymTab->lookup(PointerType::get(Ty), Name)); + SymbolTable &SymTab = getSymbolTable(); + return cast_or_null(SymTab.lookup(PointerType::get(Ty), Name)); } // addTypeName - Insert an entry in the symbol table mapping Str to Type. If @@ -128,13 +106,13 @@ // table is not modified. // bool Module::addTypeName(const std::string &Name, const Type *Ty) { - SymbolTable *ST = getSymbolTableSure(); + SymbolTable &ST = getSymbolTable(); - if (ST->lookup(Type::TypeTy, Name)) return true; // Already in symtab... + if (ST.lookup(Type::TypeTy, Name)) return true; // Already in symtab... // Not in symbol table? Set the name with the Symtab as an argument so the // type knows what to update... - ((Value*)Ty)->setName(Name, ST); + ((Value*)Ty)->setName(Name, &ST); return false; } @@ -204,13 +182,12 @@ // specified type, return it. // std::string Module::getTypeName(const Type *Ty) { - const SymbolTable *ST = getSymbolTable(); - if (ST == 0) return ""; // No symbol table, must not have an entry... - if (ST->find(Type::TypeTy) == ST->end()) + const SymbolTable &ST = getSymbolTable(); + if (ST.find(Type::TypeTy) == ST.end()) return ""; // No names for types... - SymbolTable::type_const_iterator TI = ST->type_begin(Type::TypeTy); - SymbolTable::type_const_iterator TE = ST->type_end(Type::TypeTy); + SymbolTable::type_const_iterator TI = ST.type_begin(Type::TypeTy); + SymbolTable::type_const_iterator TE = ST.type_end(Type::TypeTy); while (TI != TE && TI->second != (const Value*)Ty) ++TI; Index: llvm/lib/VMCore/SlotCalculator.cpp diff -u llvm/lib/VMCore/SlotCalculator.cpp:1.24 llvm/lib/VMCore/SlotCalculator.cpp:1.25 --- llvm/lib/VMCore/SlotCalculator.cpp:1.24 Sun Oct 13 19:48:57 2002 +++ llvm/lib/VMCore/SlotCalculator.cpp Wed Nov 20 12:33:41 2002 @@ -90,9 +90,9 @@ // Insert constants that are named at module level into the slot pool so that // the module symbol table can refer to them... // - if (TheModule->hasSymbolTable() && !IgnoreNamedNodes) { + if (!IgnoreNamedNodes) { SC_DEBUG("Inserting SymbolTable values:\n"); - processSymbolTable(TheModule->getSymbolTable()); + processSymbolTable(&TheModule->getSymbolTable()); } SC_DEBUG("end processModule!\n"); @@ -156,8 +156,7 @@ // symboltable references to constants not in the output. Scan for these // constants now. // - if (M->hasSymbolTable()) - processSymbolTableConstants(M->getSymbolTable()); + processSymbolTableConstants(&M->getSymbolTable()); } SC_DEBUG("Inserting Labels:\n"); @@ -174,9 +173,9 @@ for_each(inst_begin(M), inst_end(M), bind_obj(this, &SlotCalculator::insertValue)); - if (M->hasSymbolTable() && !IgnoreNamedNodes) { + if (!IgnoreNamedNodes) { SC_DEBUG("Inserting SymbolTable values:\n"); - processSymbolTable(M->getSymbolTable()); + processSymbolTable(&M->getSymbolTable()); } SC_DEBUG("end processFunction!\n"); Index: llvm/lib/VMCore/SymbolTableListTraitsImpl.h diff -u llvm/lib/VMCore/SymbolTableListTraitsImpl.h:1.2 llvm/lib/VMCore/SymbolTableListTraitsImpl.h:1.3 --- llvm/lib/VMCore/SymbolTableListTraitsImpl.h:1.2 Wed Jul 24 17:08:50 2002 +++ llvm/lib/VMCore/SymbolTableListTraitsImpl.h Wed Nov 20 12:33:41 2002 @@ -20,20 +20,20 @@ // Remove all of the items from the old symtab.. if (SymTabObject && !List.empty()) { - SymbolTable *SymTab = SymTabObject->getSymbolTable(); + SymbolTable &SymTab = SymTabObject->getSymbolTable(); for (typename iplist::iterator I = List.begin(); I != List.end(); ++I) - if (I->hasName()) SymTab->remove(I); + if (I->hasName()) SymTab.remove(I); } SymTabObject = STO; // Add all of the items to the new symtab... if (SymTabObject && !List.empty()) { - SymbolTable *SymTab = SymTabObject->getSymbolTableSure(); + SymbolTable &SymTab = SymTabObject->getSymbolTable(); for (typename iplist::iterator I = List.begin(); I != List.end(); ++I) - if (I->hasName()) SymTab->insert(I); + if (I->hasName()) SymTab.insert(I); } } @@ -44,7 +44,7 @@ assert(V->getParent() == 0 && "Value already in a container!!"); V->setParent(ItemParent); if (V->hasName() && SymTabObject) - SymTabObject->getSymbolTableSure()->insert(V); + SymTabObject->getSymbolTable().insert(V); } templatesetParent(0); if (V->hasName() && SymTabObject) - SymTabObject->getSymbolTable()->remove(V); + SymTabObject->getSymbolTable().remove(V); } templategetSymbolTable()->remove(&V); + OldSTO->getSymbolTable().remove(&V); V.setParent(NewIP); if (NewSTO && HasName) - NewSTO->getSymbolTableSure()->insert(&V); + NewSTO->getSymbolTable().insert(&V); } } else { // Just transfering between blocks in the same function, simply update the Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.41 llvm/lib/VMCore/Verifier.cpp:1.42 --- llvm/lib/VMCore/Verifier.cpp:1.41 Sun Oct 13 15:53:14 2002 +++ llvm/lib/VMCore/Verifier.cpp Wed Nov 20 12:33:41 2002 @@ -124,7 +124,7 @@ } // Verification methods... - void verifySymbolTable(SymbolTable *ST); + void verifySymbolTable(SymbolTable &ST); void visitFunction(Function &F); void visitBasicBlock(BasicBlock &BB); void visitPHINode(PHINode &PN); @@ -172,11 +172,9 @@ // verifySymbolTable - Verify that a function or module symbol table is ok // -void Verifier::verifySymbolTable(SymbolTable *ST) { - if (ST == 0) return; // No symbol table to process - +void Verifier::verifySymbolTable(SymbolTable &ST) { // Loop over all of the types in the symbol table... - for (SymbolTable::iterator TI = ST->begin(), TE = ST->end(); TI != TE; ++TI) + for (SymbolTable::iterator TI = ST.begin(), TE = ST.end(); TI != TE; ++TI) for (SymbolTable::type_iterator I = TI->second.begin(), E = TI->second.end(); I != E; ++I) { Value *V = I->second; From lattner at cs.uiuc.edu Wed Nov 20 12:36:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:36:01 2002 Subject: [llvm-commits] CVS: llvm/tools/lli/ExternalFunctions.cpp Support.cpp Message-ID: <200211201835.MAA06386@apoc.cs.uiuc.edu> Changes in directory llvm/tools/lli: ExternalFunctions.cpp updated: 1.38 -> 1.39 Support.cpp updated: 1.4 -> 1.5 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/tools/lli/ExternalFunctions.cpp diff -u llvm/tools/lli/ExternalFunctions.cpp:1.38 llvm/tools/lli/ExternalFunctions.cpp:1.39 --- llvm/tools/lli/ExternalFunctions.cpp:1.38 Fri Nov 8 13:10:26 2002 +++ llvm/tools/lli/ExternalFunctions.cpp Wed Nov 20 12:35:26 2002 @@ -437,16 +437,15 @@ // Check to see if the currently loaded module contains an __iob symbol... GlobalVariable *IOB = 0; - if (SymbolTable *ST = M->getSymbolTable()) { - for (SymbolTable::iterator I = ST->begin(), E = ST->end(); I != E; ++I) { - SymbolTable::VarMap &M = I->second; - for (SymbolTable::VarMap::iterator J = M.begin(), E = M.end(); - J != E; ++J) - if (J->first == "__iob") - if ((IOB = dyn_cast(J->second))) - break; - if (IOB) break; - } + SymbolTable &ST = M->getSymbolTable(); + for (SymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I) { + SymbolTable::VarMap &M = I->second; + for (SymbolTable::VarMap::iterator J = M.begin(), E = M.end(); + J != E; ++J) + if (J->first == "__iob") + if ((IOB = dyn_cast(J->second))) + break; + if (IOB) break; } // If we found an __iob symbol now, find out what the actual address it's Index: llvm/tools/lli/Support.cpp diff -u llvm/tools/lli/Support.cpp:1.4 llvm/tools/lli/Support.cpp:1.5 --- llvm/tools/lli/Support.cpp:1.4 Sat Apr 27 23:55:14 2002 +++ llvm/tools/lli/Support.cpp Wed Nov 20 12:35:26 2002 @@ -15,13 +15,10 @@ // LookupMatchingNames helper - Search a symbol table for values matching Name. // static inline void LookupMatchingNames(const std::string &Name, - SymbolTable *SymTab, + SymbolTable &SymTab, std::vector &Results) { - if (SymTab == 0) return; // No symbolic values :( - // Loop over all of the type planes in the symbol table... - for (SymbolTable::iterator I = SymTab->begin(), E = SymTab->end(); - I != E; ++I) { + for (SymbolTable::iterator I = SymTab.begin(), E = SymTab.end(); I != E; ++I){ SymbolTable::VarMap &Plane = I->second; // Search the symbol table plane for this name... From lattner at cs.uiuc.edu Wed Nov 20 12:37:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:37:01 2002 Subject: [llvm-commits] CVS: llvm/www/docs/ProgrammersManual.html Message-ID: <200211201836.MAA05514@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: ProgrammersManual.html updated: 1.36 -> 1.37 --- Log message: - Eliminated the deferred symbol table stuff in Module & Function, it really wasn't an optimization and it was causing lots of bugs. --- Diffs of the changes: Index: llvm/www/docs/ProgrammersManual.html diff -u llvm/www/docs/ProgrammersManual.html:1.36 llvm/www/docs/ProgrammersManual.html:1.37 --- llvm/www/docs/ProgrammersManual.html:1.36 Fri Nov 8 00:50:02 2002 +++ llvm/www/docs/ProgrammersManual.html Wed Nov 20 12:36:02 2002 @@ -1441,26 +1441,10 @@ and returns the return type of the function, or the FunctionType of the actual function.

- -

  • bool hasSymbolTable() const

    - -Return true if the Function has a symbol table allocated to it and if -there is at least one entry in it.

    -

  • SymbolTable *getSymbolTable()

    Return a pointer to the SymbolTable for this -Function or a null pointer if one has not been allocated (because there -are no named values in the function).

    - -

  • SymbolTable *getSymbolTableSure()

    - -Return a pointer to the SymbolTable for this -Function or allocate a new SymbolTable if one is not already around. This -should only be used when adding elements to the SymbolTable, so that empty symbol tables are -not left laying around.

    +Function.

    @@ -1580,25 +1564,10 @@


    -
  • bool hasSymbolTable() const

    - -Return true if the Module has a symbol table allocated to it and if -there is at least one entry in it.

    -

  • SymbolTable *getSymbolTable()

    -Return a pointer to the SymbolTable for this -Module or a null pointer if one has not been allocated (because there -are no named values in the function).

    - -

  • SymbolTable *getSymbolTableSure()

    - -Return a pointer to the SymbolTable for this -Module or allocate a new SymbolTable if one is not already around. This -should only be used when adding elements to the SymbolTable, so that empty symbol tables are -not left laying around.

    +Return a reference to the SymbolTable for +this Module.

    @@ -1776,6 +1745,6 @@ Chris Lattner -Last modified: Fri Nov 8 00:48:37 CST 2002 +Last modified: Wed Nov 20 12:21:34 CST 2002 From lattner at cs.uiuc.edu Wed Nov 20 12:38:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 12:38:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Makefile Message-ID: <200211201837.MAA06541@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Makefile updated: 1.6 -> 1.7 --- Log message: Don't build X86 target yet --- Diffs of the changes: Index: llvm/lib/Target/Makefile diff -u llvm/lib/Target/Makefile:1.6 llvm/lib/Target/Makefile:1.7 --- llvm/lib/Target/Makefile:1.6 Tue Oct 29 14:29:34 2002 +++ llvm/lib/Target/Makefile Wed Nov 20 12:37:37 2002 @@ -1,5 +1,5 @@ LEVEL = ../.. -DIRS = Sparc X86 +DIRS = Sparc #X86 LIBRARYNAME = target BUILD_ARCHIVE = 1 From brukman at cs.uiuc.edu Wed Nov 20 12:56:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Nov 20 12:56:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h TargetMachine.h Message-ID: <200211201855.MAA07582@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.1 -> 1.2 TargetMachine.h updated: 1.19 -> 1.20 --- Log message: MRegisterInfo.h - Added prototypes for functions we need to map a register to an appropriate TargetRegisterClass, also adds TargetRegisterClass definition. TargetMachine.h - speling. --- Diffs of the changes: Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.1 llvm/include/llvm/Target/MRegisterInfo.h:1.2 --- llvm/include/llvm/Target/MRegisterInfo.h:1.1 Fri Oct 25 18:00:40 2002 +++ llvm/include/llvm/Target/MRegisterInfo.h Wed Nov 20 12:54:53 2002 @@ -6,11 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MREGISTERINFO_H -#define LLVM_CODEGEN_MREGISTERINFO_H +#ifndef LLVM_TARGET_MREGISTERINFO_H +#define LLVM_TARGET_MREGISTERINFO_H +#include "llvm/CodeGen/MachineBasicBlock.h" #include +class Type; + /// MRegisterDesc - This record contains all of the information known about a /// particular register. /// @@ -38,6 +41,30 @@ }; }; +class TargetRegisterClass { +protected: + TargetRegisterClass() {} + +public: + + typedef unsigned* iterator; + typedef unsigned* const_iterator; + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + virtual unsigned getNumRegs() const { return 0; } + virtual unsigned getRegister(unsigned idx) const { return 0; } + + virtual unsigned getDataSize() const { return 0; } + + //const std::vector &getRegsInClass(void) { return Regs; } + //void getAliases(void); +}; + + /// MRegisterInfo base class - We assume that the target defines a static array /// of MRegisterDesc objects that represent all of the machine registers that /// the target has. As such, we simply have to track a pointer to this array so @@ -79,8 +106,25 @@ /// const MRegisterDesc &get(unsigned RegNo) const { return operator[](RegNo); } - // This will eventually get some virtual methods... - + + virtual void copyReg2PCRel(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned SrcReg, unsigned ImmOffset, + unsigned dataSize) const = 0; + + virtual void copyPCRel2Reg(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned ImmOffset, unsigned DestReg, + unsigned dataSize) const = 0; + + /// Register class iterators + typedef const TargetRegisterClass* const_iterator; + + virtual const_iterator const_regclass_begin() const = 0; + virtual const_iterator const_regclass_end() const = 0; + + virtual unsigned getNumRegClasses() const = 0; + virtual const TargetRegisterClass* getRegClassForType(const Type* Ty) const=0; }; #endif Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.19 llvm/include/llvm/Target/TargetMachine.h:1.20 --- llvm/include/llvm/Target/TargetMachine.h:1.19 Tue Oct 29 18:53:02 2002 +++ llvm/include/llvm/Target/TargetMachine.h Wed Nov 20 12:54:53 2002 @@ -1,4 +1,4 @@ -//===-- llvm/Target/Machine.h - General Target Information -------*- C++ -*-==// +//===-- llvm/Target/TargetMachine.h - General Target Information -*- C++ -*-==// // // This file describes the general parts of a Target machine. // @@ -68,7 +68,7 @@ virtual const MachineOptInfo& getOptInfo() const = 0; /// getRegisterInfo - If register information is available, return it. If - /// not, return null. This is kept seperate from RegInfo until RegInfo gets + /// not, return null. This is kept separate from RegInfo until RegInfo gets /// straightened out. /// virtual const MRegisterInfo* getRegisterInfo() const { return 0; } From brukman at cs.uiuc.edu Wed Nov 20 12:56:05 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Nov 20 12:56:05 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineFunction.cpp Message-ID: <200211201855.MAA07595@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineFunction.cpp updated: 1.29 -> 1.30 --- Log message: Initialize the SSARegMap. --- Diffs of the changes: Index: llvm/lib/CodeGen/MachineFunction.cpp diff -u llvm/lib/CodeGen/MachineFunction.cpp:1.29 llvm/lib/CodeGen/MachineFunction.cpp:1.30 --- llvm/lib/CodeGen/MachineFunction.cpp:1.29 Tue Oct 29 18:48:05 2002 +++ llvm/lib/CodeGen/MachineFunction.cpp Wed Nov 20 12:55:27 2002 @@ -102,6 +102,7 @@ currentTmpValuesSize(0), maxTmpValuesSize(0), compiledAsLeaf(false), spillsAreaFrozen(false), automaticVarsAreaFrozen(false) { + SSARegMapping = new SSARegMap(); } void MachineFunction::dump() const { print(std::cerr); } From brukman at cs.uiuc.edu Wed Nov 20 12:57:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Nov 20 12:57:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211201856.MAA07618@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.7 -> 1.8 --- Log message: Check not only for MO_VirtualRegister, but MO_MachineRegister as well when printing out assembly. After all, we want the real thing too. --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.7 llvm/lib/Target/X86/Printer.cpp:1.8 --- llvm/lib/Target/X86/Printer.cpp:1.7 Mon Nov 18 00:56:51 2002 +++ llvm/lib/Target/X86/Printer.cpp Wed Nov 20 12:56:41 2002 @@ -71,6 +71,7 @@ const MRegisterInfo &RI) { switch (MO.getType()) { case MachineOperand::MO_VirtualRegister: + case MachineOperand::MO_MachineRegister: if (MO.getReg() < MRegisterInfo::FirstVirtualRegister) O << RI.get(MO.getReg()).Name; else @@ -137,14 +138,20 @@ // 2 Operands: this is for things like mov that do not read a second input // assert(((MI->getNumOperands() == 3 && - (MI->getOperand(0).getType()==MachineOperand::MO_VirtualRegister&& - MI->getOperand(1).getType()==MachineOperand::MO_VirtualRegister))|| + (MI->getOperand(0).getType()==MachineOperand::MO_VirtualRegister|| + MI->getOperand(0).getType()==MachineOperand::MO_MachineRegister) + && + (MI->getOperand(1).getType()==MachineOperand::MO_VirtualRegister|| + MI->getOperand(1).getType()==MachineOperand::MO_MachineRegister)) + || (MI->getNumOperands() == 2 && - (MI->getOperand(0).getType()==MachineOperand::MO_VirtualRegister))) - && MI->getOperand(MI->getNumOperands()-1).getType() == - MachineOperand::MO_VirtualRegister && - "Bad format for MRMDestReg!"); - + (MI->getOperand(0).getType()==MachineOperand::MO_VirtualRegister|| + MI->getOperand(0).getType()==MachineOperand::MO_MachineRegister) + && (MI->getOperand(MI->getNumOperands()-1).getType() == + MachineOperand::MO_VirtualRegister|| + MI->getOperand(MI->getNumOperands()-1).getType() == + MachineOperand::MO_MachineRegister))) + && "Bad format for MRMDestReg!"); if (MI->getNumOperands() == 3 && MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) O << "**"; From brukman at cs.uiuc.edu Wed Nov 20 13:00:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Nov 20 13:00:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterClasses.cpp X86RegisterInfo.h X86RegisterInfo.cpp Message-ID: <200211201859.MAA07643@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterClasses.cpp added (r1.1) X86RegisterInfo.h updated: 1.1 -> 1.2 X86RegisterInfo.cpp updated: 1.1 -> 1.2 --- Log message: Add definitions for function headers from MRegisterInfo.h: Some functions are in X86RegisterInfo.cpp, others, because of the data they need, are in X86RegisterClasses.cpp, which also defines some register classes: byte, short, and int. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.1 llvm/lib/Target/X86/X86RegisterInfo.h:1.2 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.1 Fri Oct 25 17:55:53 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.h Wed Nov 20 12:59:43 2002 @@ -9,8 +9,32 @@ #include "llvm/Target/MRegisterInfo.h" +class Type; + struct X86RegisterInfo : public MRegisterInfo { X86RegisterInfo(); + + MRegisterInfo::const_iterator const_regclass_begin() const; + MRegisterInfo::const_iterator const_regclass_end() const; + + void copyReg2PCRel(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned SrcReg, unsigned ImmOffset, + unsigned dataSize) const; + + void copyPCRel2Reg(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned ImmOffset, unsigned DestReg, + unsigned dataSize) const; + + /// Returns register class appropriate for input SSA register + /// + const TargetRegisterClass *getClassForReg(unsigned Reg) const; + + const TargetRegisterClass* getRegClassForType(const Type* Ty) const; + + unsigned getNumRegClasses() const; + }; Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.1 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.2 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.1 Fri Oct 25 17:55:53 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Nov 20 12:59:43 2002 @@ -4,7 +4,11 @@ // //===----------------------------------------------------------------------===// +#include "X86.h" #include "X86RegisterInfo.h" +#include "llvm/Constants.h" +#include "llvm/Type.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" // X86Regs - Turn the X86RegisterInfo.def file into a bunch of register // descriptors @@ -17,3 +21,25 @@ X86RegisterInfo::X86RegisterInfo() : MRegisterInfo(X86Regs, sizeof(X86Regs)/sizeof(X86Regs[0])) { } + + +void X86RegisterInfo::copyReg2PCRel(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned SrcReg, unsigned ImmOffset, + unsigned dataSize) const +{ + MachineInstrBuilder MI = BuildMI(X86::MOVmr32, 2) + .addPCDisp(ConstantUInt::get(Type::UIntTy, ImmOffset)).addReg(SrcReg); + MBB->insert(MBBI, &*MI); +} + +void X86RegisterInfo::copyPCRel2Reg(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned ImmOffset, unsigned DestReg, + unsigned dataSize) const +{ + MachineInstrBuilder MI = BuildMI(X86::MOVrm32, 2) + .addReg(DestReg).addPCDisp(ConstantUInt::get(Type::UIntTy, ImmOffset)); + MBB->insert(MBBI, &*MI); +} + From lattner at cs.uiuc.edu Wed Nov 20 13:33:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 13:33:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/MutateStructTypes.cpp Message-ID: <200211201932.NAA09153@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: MutateStructTypes.cpp updated: 1.33 -> 1.34 --- Log message: Fix symbol table problem --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/MutateStructTypes.cpp diff -u llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.33 llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.34 --- llvm/lib/Transforms/IPO/MutateStructTypes.cpp:1.33 Tue Nov 19 14:49:40 2002 +++ llvm/lib/Transforms/IPO/MutateStructTypes.cpp Wed Nov 20 13:32:43 2002 @@ -266,17 +266,16 @@ // Remap the symbol table to refer to the types in a nice way // - if (SymbolTable *ST = M.getSymbolTable()) { - SymbolTable::iterator I = ST->find(Type::TypeTy); - if (I != ST->end()) { // Get the type plane for Type's - SymbolTable::VarMap &Plane = I->second; - for (SymbolTable::type_iterator TI = Plane.begin(), TE = Plane.end(); - TI != TE; ++TI) { - // FIXME: This is gross, I'm reaching right into a symbol table and - // mucking around with it's internals... but oh well. - // - TI->second = (Value*)cast(ConvertType(cast(TI->second))); - } + SymbolTable &ST = M.getSymbolTable(); + SymbolTable::iterator I = ST.find(Type::TypeTy); + if (I != ST.end()) { // Get the type plane for Type's + SymbolTable::VarMap &Plane = I->second; + for (SymbolTable::type_iterator TI = Plane.begin(), TE = Plane.end(); + TI != TE; ++TI) { + // FIXME: This is gross, I'm reaching right into a symbol table and + // mucking around with it's internals... but oh well. + // + TI->second = (Value*)cast(ConvertType(cast(TI->second))); } } } From lattner at cs.uiuc.edu Wed Nov 20 14:18:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 14:18:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Makefile Message-ID: <200211202017.OAA10800@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target: Makefile updated: 1.7 -> 1.8 --- Log message: X86 target builds fine now --- Diffs of the changes: Index: llvm/lib/Target/Makefile diff -u llvm/lib/Target/Makefile:1.7 llvm/lib/Target/Makefile:1.8 --- llvm/lib/Target/Makefile:1.7 Wed Nov 20 12:37:37 2002 +++ llvm/lib/Target/Makefile Wed Nov 20 14:17:03 2002 @@ -1,5 +1,5 @@ LEVEL = ../.. -DIRS = Sparc #X86 +DIRS = Sparc X86 LIBRARYNAME = target BUILD_ARCHIVE = 1 From lattner at cs.uiuc.edu Wed Nov 20 14:24:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 14:24:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Cloning.h Message-ID: <200211202023.OAA11165@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Cloning.h updated: 1.3 -> 1.4 --- Log message: Cloning stuff doesn't modify the source module --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Utils/Cloning.h diff -u llvm/include/llvm/Transforms/Utils/Cloning.h:1.3 llvm/include/llvm/Transforms/Utils/Cloning.h:1.4 --- llvm/include/llvm/Transforms/Utils/Cloning.h:1.3 Tue Nov 19 16:53:58 2002 +++ llvm/include/llvm/Transforms/Utils/Cloning.h Wed Nov 20 14:22:58 2002 @@ -22,7 +22,7 @@ /// CloneModule - Return an exact copy of the specified module /// -Module *CloneModule(Module *M); +Module *CloneModule(const Module *M); /// CloneFunction - Return a copy of the specified function, but without /// embedding the function into another module. Also, any references specified From lattner at cs.uiuc.edu Wed Nov 20 14:48:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 14:48:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/CloneModule.cpp ValueMapper.cpp ValueMapper.h CloneFunction.cpp Message-ID: <200211202047.OAA13656@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: CloneModule.cpp added (r1.1) ValueMapper.cpp added (r1.1) ValueMapper.h added (r1.1) CloneFunction.cpp updated: 1.13 -> 1.14 --- Log message: Initial checkin of Module cloning support stuff --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/CloneFunction.cpp diff -u llvm/lib/Transforms/Utils/CloneFunction.cpp:1.13 llvm/lib/Transforms/Utils/CloneFunction.cpp:1.14 --- llvm/lib/Transforms/Utils/CloneFunction.cpp:1.13 Wed Nov 20 12:32:31 2002 +++ llvm/lib/Transforms/Utils/CloneFunction.cpp Wed Nov 20 14:47:41 2002 @@ -10,6 +10,7 @@ #include "llvm/iTerminators.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" +#include "ValueMapper.h" // RemapInstruction - Convert the instruction operands from referencing the // current values into those specified by ValueMap. @@ -18,10 +19,7 @@ std::map &ValueMap) { for (unsigned op = 0, E = I->getNumOperands(); op != E; ++op) { const Value *Op = I->getOperand(op); - Value *V = ValueMap[Op]; - if (!V && (isa(Op) || isa(Op))) - continue; // Globals and constants don't get relocated - + Value *V = MapValue(Op, ValueMap); #ifndef NDEBUG if (!V) { std::cerr << "Val = \n" << Op << "Addr = " << (void*)Op; From lattner at cs.uiuc.edu Wed Nov 20 16:28:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 16:28:01 2002 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/ Message-ID: <200211202227.QAA16042@apoc.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/tools/bugpoint added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Nov 20 16:29:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 16:29:01 2002 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.cpp BugDriver.h CrashDebugger.cpp ExtractFunction.cpp Makefile OptimizerDriver.cpp TestPasses.cpp bugpoint.cpp Message-ID: <200211202228.QAA16061@apoc.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: BugDriver.cpp added (r1.1) BugDriver.h added (r1.1) CrashDebugger.cpp added (r1.1) ExtractFunction.cpp added (r1.1) Makefile added (r1.1) OptimizerDriver.cpp added (r1.1) TestPasses.cpp added (r1.1) bugpoint.cpp added (r1.1) --- Log message: Initial checkin of bugpoint --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Nov 20 16:29:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 16:29:04 2002 Subject: [llvm-commits] CVS: llvm/tools/Makefile Message-ID: <200211202228.QAA16091@apoc.cs.uiuc.edu> Changes in directory llvm/tools: Makefile updated: 1.15 -> 1.16 --- Log message: Build bugpoint --- Diffs of the changes: Index: llvm/tools/Makefile diff -u llvm/tools/Makefile:1.15 llvm/tools/Makefile:1.16 --- llvm/tools/Makefile:1.15 Tue Oct 29 17:41:11 2002 +++ llvm/tools/Makefile Wed Nov 20 16:28:18 2002 @@ -1,5 +1,5 @@ LEVEL = .. -PARALLEL_DIRS = as dis opt gccas llc link lli gccld analyze extract jello +PARALLEL_DIRS = as dis opt gccas llc link lli gccld analyze extract jello bugpoint include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Wed Nov 20 16:30:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 16:30:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/BugPoint/ Message-ID: <200211202229.QAA16111@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/BugPoint: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Regression/BugPoint added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Nov 20 16:31:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 16:31:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/BugPoint/Makefile crash-basictest.ll crash-narrowfunctiontest.ll Message-ID: <200211202230.QAA16124@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/BugPoint: Makefile added (r1.1) crash-basictest.ll added (r1.1) crash-narrowfunctiontest.ll added (r1.1) --- Log message: Checkin testcases for bugpoint --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Nov 20 16:32:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 16:32:00 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Makefile Message-ID: <200211202231.QAA16311@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression: Makefile updated: 1.6 -> 1.7 --- Log message: Build bugpoint tests --- Diffs of the changes: Index: llvm/test/Regression/Makefile diff -u llvm/test/Regression/Makefile:1.6 llvm/test/Regression/Makefile:1.7 --- llvm/test/Regression/Makefile:1.6 Thu May 16 23:53:40 2002 +++ llvm/test/Regression/Makefile Wed Nov 20 16:30:50 2002 @@ -7,5 +7,5 @@ # testsuite. # LEVEL = ../.. -DIRS = Assembler CFrontend CBackend LLC Other Transforms Verifier +DIRS = Assembler BugPoint CFrontend CBackend LLC Other Transforms Verifier include $(LEVEL)/Makefile.common From brukman at cs.uiuc.edu Wed Nov 20 18:27:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Nov 20 18:27:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterClasses.cpp Message-ID: <200211210026.SAA18347@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterClasses.cpp updated: 1.1 -> 1.2 --- Log message: Booleans are types too. And they get stored in bytes. And InstructionSelection doesn't assert fail. And everyone's happy. Yay! --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterClasses.cpp diff -u llvm/lib/Target/X86/X86RegisterClasses.cpp:1.1 llvm/lib/Target/X86/X86RegisterClasses.cpp:1.2 --- llvm/lib/Target/X86/X86RegisterClasses.cpp:1.1 Wed Nov 20 12:59:43 2002 +++ llvm/lib/Target/X86/X86RegisterClasses.cpp Wed Nov 20 18:25:56 2002 @@ -101,6 +101,7 @@ const { switch (Ty->getPrimitiveID()) { + case Type::BoolTyID: case Type::SByteTyID: case Type::UByteTyID: return &X86ByteRegisterClassInstance; case Type::ShortTyID: From lattner at cs.uiuc.edu Wed Nov 20 18:31:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 18:31:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211210030.SAA18598@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.8 -> 1.9 --- Log message: Print another class of instructions correctly, giving us: xorl EDX, EDX for example. --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.8 llvm/lib/Target/X86/Printer.cpp:1.9 --- llvm/lib/Target/X86/Printer.cpp:1.8 Wed Nov 20 12:56:41 2002 +++ llvm/lib/Target/X86/Printer.cpp Wed Nov 20 18:30:01 2002 @@ -97,6 +97,12 @@ } +static bool isReg(const MachineOperand &MO) { + return MO.getType()==MachineOperand::MO_VirtualRegister || + MO.getType()==MachineOperand::MO_MachineRegister; +} + + // print - Print out an x86 instruction in intel syntax void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O, const TargetMachine &TM) const { @@ -137,20 +143,10 @@ // // 2 Operands: this is for things like mov that do not read a second input // - assert(((MI->getNumOperands() == 3 && - (MI->getOperand(0).getType()==MachineOperand::MO_VirtualRegister|| - MI->getOperand(0).getType()==MachineOperand::MO_MachineRegister) - && - (MI->getOperand(1).getType()==MachineOperand::MO_VirtualRegister|| - MI->getOperand(1).getType()==MachineOperand::MO_MachineRegister)) - || - (MI->getNumOperands() == 2 && - (MI->getOperand(0).getType()==MachineOperand::MO_VirtualRegister|| - MI->getOperand(0).getType()==MachineOperand::MO_MachineRegister) - && (MI->getOperand(MI->getNumOperands()-1).getType() == - MachineOperand::MO_VirtualRegister|| - MI->getOperand(MI->getNumOperands()-1).getType() == - MachineOperand::MO_MachineRegister))) + assert(isReg(MI->getOperand(0)) && + (MI->getNumOperands() == 2 || + (MI->getNumOperands() == 3 && isReg(MI->getOperand(1)))) && + isReg(MI->getOperand(MI->getNumOperands()-1)) && "Bad format for MRMDestReg!"); if (MI->getNumOperands() == 3 && MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) @@ -163,8 +159,34 @@ printOp(O, MI->getOperand(MI->getNumOperands()-1), RI); O << "\n"; return; - case X86II::MRMDestMem: case X86II::MRMSrcReg: + // There is a two forms that are acceptable for MRMSrcReg instructions, + // those with 3 and 2 operands: + // + // 3 Operands: in this form, the last register (the second input) is the + // ModR/M input. The first two operands should be the same, post register + // allocation. This is for things like: add r32, r/m32 + // + // 2 Operands: this is for things like mov that do not read a second input + // + assert(isReg(MI->getOperand(0)) && + isReg(MI->getOperand(1)) && + (MI->getNumOperands() == 2 || + (MI->getNumOperands() == 3 && isReg(MI->getOperand(2)))) + && "Bad format for MRMDestReg!"); + if (MI->getNumOperands() == 3 && + MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) + O << "**"; + + O << "\t"; + O << getName(MI->getOpCode()) << " "; + printOp(O, MI->getOperand(0), RI); + O << ", "; + printOp(O, MI->getOperand(MI->getNumOperands()-1), RI); + O << "\n"; + return; + + case X86II::MRMDestMem: case X86II::MRMSrcMem: default: O << "\t-"; MI->print(O, TM); break; From lattner at cs.uiuc.edu Wed Nov 20 19:34:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 19:34:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.h Message-ID: <200211210133.TAA19787@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.h updated: 1.11 -> 1.12 --- Log message: Add new prefix flag --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.11 llvm/lib/Target/X86/X86InstrInfo.h:1.12 --- llvm/lib/Target/X86/X86InstrInfo.h:1.11 Mon Nov 18 00:56:24 2002 +++ llvm/lib/Target/X86/X86InstrInfo.h Wed Nov 20 19:32:55 2002 @@ -65,6 +65,11 @@ // TB - TwoByte - Set if this instruction has a two byte opcode, which // starts with a 0x0F byte before the real opcode. TB = 1 << 4, + + // OpSize - Set if this instruction requires an operand size prefix (0x66), + // which most often indicates that the instruction operates on 16 bit data + // instead of 32 bit data. + OpSize = 1 << 5, }; } From lattner at cs.uiuc.edu Wed Nov 20 19:34:04 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 19:34:04 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211210133.TAA19800@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.9 -> 1.10 --- Log message: Implement printing more, implement opcode output more --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.9 llvm/lib/Target/X86/Printer.cpp:1.10 --- llvm/lib/Target/X86/Printer.cpp:1.9 Wed Nov 20 18:30:01 2002 +++ llvm/lib/Target/X86/Printer.cpp Wed Nov 20 19:33:44 2002 @@ -12,6 +12,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" +#include "Support/Statistic.h" namespace { struct Printer : public FunctionPass { @@ -103,22 +104,57 @@ } +// getX86RegNum - This function maps LLVM register identifiers to their X86 +// specific numbering, which is used in various places encoding instructions. +// +static unsigned getX86RegNum(unsigned RegNo) { + switch(RegNo) { + case X86::EAX: case X86::AX: case X86::AL: return 0; + case X86::ECX: case X86::CX: case X86::CL: return 1; + case X86::EDX: case X86::DX: case X86::DL: return 2; + case X86::EBX: case X86::BX: case X86::BL: return 3; + case X86::ESP: case X86::SP: case X86::AH: return 4; + case X86::EBP: case X86::BP: case X86::CH: return 5; + case X86::ESI: case X86::SI: case X86::DH: return 6; + case X86::EDI: case X86::DI: case X86::BH: return 7; + default: + assert(RegNo >= MRegisterInfo::FirstVirtualRegister && + "Unknown physical register!"); + DEBUG(std::cerr << "Register allocator hasn't allocated " << RegNo + << " correctly yet!\n"); + return 0; + } +} + +inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode, + unsigned RM) { + assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!"); + return RM | (RegOpcode << 3) | (Mod << 6); +} + +static unsigned char regModRMByte(unsigned ModRMReg, unsigned RegOpcodeField) { + return ModRMByte(3, RegOpcodeField, getX86RegNum(ModRMReg)); +} + + // print - Print out an x86 instruction in intel syntax void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O, const TargetMachine &TM) const { unsigned Opcode = MI->getOpcode(); const MachineInstrDescriptor &Desc = get(Opcode); - if (Desc.TSFlags & X86II::TB) - O << "0F "; + // Print instruction prefixes if neccesary + + if (Desc.TSFlags & X86II::OpSize) O << "66 "; // Operand size... + if (Desc.TSFlags & X86II::TB) O << "0F "; // Two-byte opcode prefix switch (Desc.TSFlags & X86II::FormMask) { case X86II::OtherFrm: - O << "\t"; + O << "\t\t"; O << "-"; MI->print(O, TM); break; case X86II::RawFrm: - toHex(O, getBaseOpcodeFor(Opcode)) << "\t"; + toHex(O, getBaseOpcodeFor(Opcode)) << "\t\t"; O << getName(MI->getOpCode()) << " "; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -130,9 +166,9 @@ case X86II::AddRegFrm: - O << "\t-"; MI->print(O, TM); break; + O << "\t\t-"; MI->print(O, TM); break; - case X86II::MRMDestReg: + case X86II::MRMDestReg: { // There are two acceptable forms of MRMDestReg instructions, those with 3 // and 2 operands: // @@ -152,14 +188,20 @@ MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) O << "**"; - O << "\t"; + toHex(O, getBaseOpcodeFor(Opcode)) << " "; + unsigned ModRMReg = MI->getOperand(0).getReg(); + unsigned ExtraReg = MI->getOperand(MI->getNumOperands()-1).getReg(); + toHex(O, regModRMByte(ModRMReg, getX86RegNum(ExtraReg))); + + O << "\t\t"; O << getName(MI->getOpCode()) << " "; printOp(O, MI->getOperand(0), RI); O << ", "; printOp(O, MI->getOperand(MI->getNumOperands()-1), RI); O << "\n"; return; - case X86II::MRMSrcReg: + } + case X86II::MRMSrcReg: { // There is a two forms that are acceptable for MRMSrcReg instructions, // those with 3 and 2 operands: // @@ -178,6 +220,11 @@ MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) O << "**"; + toHex(O, getBaseOpcodeFor(Opcode)) << " "; + unsigned ModRMReg = MI->getOperand(MI->getNumOperands()-1).getReg(); + unsigned ExtraReg = MI->getOperand(0).getReg(); + toHex(O, regModRMByte(ModRMReg, getX86RegNum(ExtraReg))); + O << "\t"; O << getName(MI->getOpCode()) << " "; printOp(O, MI->getOperand(0), RI); @@ -185,10 +232,10 @@ printOp(O, MI->getOperand(MI->getNumOperands()-1), RI); O << "\n"; return; - + } case X86II::MRMDestMem: case X86II::MRMSrcMem: default: - O << "\t-"; MI->print(O, TM); break; + O << "\t\t-"; MI->print(O, TM); break; } } From lattner at cs.uiuc.edu Wed Nov 20 19:35:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 19:35:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200211210134.TAA19807@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def updated: 1.21 -> 1.22 --- Log message: Huge diff do to reindeinting comments. Basically just adds OpSize flags for instructions that need them. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.21 llvm/lib/Target/X86/X86InstrInfo.def:1.22 --- llvm/lib/Target/X86/X86InstrInfo.def:1.21 Tue Nov 19 03:08:47 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Wed Nov 20 19:33:28 2002 @@ -32,122 +32,125 @@ I(PHI , "phi", 0, 0, 0) // The second instruction must always be the noop instruction: -I(NOOP , "nop", 0x90, 0, X86II::RawFrm | X86II::Void) // nop +I(NOOP , "nop", 0x90, 0, X86II::RawFrm | X86II::Void) // nop // Flow control instructions -I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void) // ret +I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void) // ret I(JMP , "jmp", 0x00, M_BRANCH_FLAG, X86II::Void) // jmp foo EB|E9 cb|w I(JNE , "jne", 0x00, M_BRANCH_FLAG, X86II::Void) // 75 cb, or 0f 85 cw|cd I(JE , "je", 0x00, M_BRANCH_FLAG, X86II::Void) // 74 cb, or 0f 84 cw|cd // Misc instructions -I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm) // leave +I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm) // leave // Move instructions -I(MOVrr8 , "movb", 0x88, 0, X86II::MRMDestReg) // R8 = R8 88/r -I(MOVrr16 , "movw", 0x89, 0, X86II::MRMDestReg) // R16 = R16 89/r -I(MOVrr32 , "movl", 0x89, 0, X86II::MRMDestReg) // R32 = R32 89/r -I(MOVir8 , "movb", 0xB0, 0, X86II::AddRegFrm) // R8 = imm8 B0+ rb -I(MOVir16 , "movw", 0xB8, 0, X86II::AddRegFrm) // R16 = imm16 B8+ rw -I(MOVir32 , "movl", 0xB8, 0, X86II::AddRegFrm) // R32 = imm32 B8+ rd -I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem) // R8 = [mem] 8A/r -I(MOVmr16 , "movw", 0x8B, 0, X86II::MRMSrcMem) // R16 = [mem] 8B/r -I(MOVmr32 , "movl", 0x8B, 0, X86II::MRMSrcMem) // R32 = [mem] 8B/r -I(MOVrm8 , "movb", 0x88, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R8 88/r -I(MOVrm16 , "movw", 0x89, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R16 89/r -I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R32 89/r +I(MOVrr8 , "movb", 0x88, 0, X86II::MRMDestReg) // R8 = R8 88/r +I(MOVrr16 , "movw", 0x89, 0, X86II::MRMDestReg | X86II::OpSize) // R16 = R16 89/r +I(MOVrr32 , "movl", 0x89, 0, X86II::MRMDestReg) // R32 = R32 89/r +I(MOVir8 , "movb", 0xB0, 0, X86II::AddRegFrm) // R8 = imm8 B0+ rb +I(MOVir16 , "movw", 0xB8, 0, X86II::AddRegFrm | X86II::OpSize) // R16 = imm16 B8+ rw +I(MOVir32 , "movl", 0xB8, 0, X86II::AddRegFrm) // R32 = imm32 B8+ rd +I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem) // R8 = [mem] 8A/r +I(MOVmr16 , "movw", 0x8B, 0, X86II::MRMSrcMem | X86II::OpSize) // R16 = [mem] 8B/r +I(MOVmr32 , "movl", 0x8B, 0, X86II::MRMSrcMem) // R32 = [mem] 8B/r +I(MOVrm8 , "movb", 0x88, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R8 88/r +I(MOVrm16 , "movw", 0x89, 0, X86II::MRMDestMem | X86II::Void | // [mem] = R16 89/r + X86II::OpSize) +I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R32 89/r // Arithmetic instructions -I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg) // R8 += R8 00/r -I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg) // R16 += R16 01/r -I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg) // R32 += R32 01/r -I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg) // R8 -= R8 2A/r -I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg) // R16 -= R16 2B/r -I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg) // R32 -= R32 2B/r -I(MULrr8 , "mulb", 0xF6, 0, X86II::Void) // AX = AL*R8 F6/4 -I(MULrr16 , "mulw", 0xF7, 0, X86II::Void) // DX:AX= AX*R16 F7/4 -I(MULrr32 , "mull", 0xF7, 0, X86II::Void) // ED:EA= EA*R32 F7/4 +I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg) // R8 += R8 00/r +I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg | X86II::OpSize) // R16 += R16 01/r +I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg) // R32 += R32 01/r +I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg) // R8 -= R8 2A/r +I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize) // R16 -= R16 2B/r +I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg) // R32 -= R32 2B/r +I(MULrr8 , "mulb", 0xF6, 0, X86II::Void) // AX = AL*R8 F6/4 +I(MULrr16 , "mulw", 0xF7, 0, X86II::Void | X86II::OpSize) // DX:AX= AX*R16 F7/4 +I(MULrr32 , "mull", 0xF7, 0, X86II::Void) // ED:EA= EA*R32 F7/4 // unsigned division/remainder -I(DIVrr8 , "divb", 0xF6, 0, X86II::Void) // AX/r8= AL&AH F6/6 -I(DIVrr16 , "divw", 0xF7, 0, X86II::Void) // DA/r16=AX&DX F7/6 -I(DIVrr32 , "divl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6 +I(DIVrr8 , "divb", 0xF6, 0, X86II::Void) // AX/r8= AL&AH F6/6 +I(DIVrr16 , "divw", 0xF7, 0, X86II::Void | X86II::OpSize) // DA/r16=AX&DX F7/6 +I(DIVrr32 , "divl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6 // signed division/remainder -I(IDIVrr8 , "idivb", 0xF6, 0, X86II::Void) // AX/r8= AL&AH F6/6 -I(IDIVrr16 , "idivw", 0xF7, 0, X86II::Void) // DA/r16=AX&DX F7/6 -I(IDIVrr32 , "idivl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6 +I(IDIVrr8 , "idivb", 0xF6, 0, X86II::Void) // AX/r8= AL&AH F6/6 +I(IDIVrr16 , "idivw", 0xF7, 0, X86II::Void | X86II::OpSize) // DA/r16=AX&DX F7/6 +I(IDIVrr32 , "idivl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6 // Logical operators -I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg) // R8 &= R8 20/r -I(ANDrr16 , "andw", 0x21, 0, X86II::MRMDestReg) // R16 &= R16 21/r -I(ANDrr32 , "andl", 0x21, 0, X86II::MRMDestReg) // R32 &= R32 21/r -I(ORrr8 , "orb", 0x08, 0, X86II::MRMDestReg) // R8 |= R8 08/r -I(ORrr16 , "orw", 0x09, 0, X86II::MRMDestReg) // R16 |= R16 09/r -I(ORrr32 , "orl", 0x09, 0, X86II::MRMDestReg) // R32 |= R32 09/r -I(XORrr8 , "xorb", 0x30, 0, X86II::MRMDestReg) // R8 ^= R8 30/r -I(XORrr16 , "xorw", 0x31, 0, X86II::MRMDestReg) // R16 ^= R16 31/r -I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg) // R32 ^= R32 31/r +I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg) // R8 &= R8 20/r +I(ANDrr16 , "andw", 0x21, 0, X86II::MRMDestReg | X86II::OpSize) // R16 &= R16 21/r +I(ANDrr32 , "andl", 0x21, 0, X86II::MRMDestReg) // R32 &= R32 21/r +I(ORrr8 , "orb", 0x08, 0, X86II::MRMDestReg) // R8 |= R8 08/r +I(ORrr16 , "orw", 0x09, 0, X86II::MRMDestReg | X86II::OpSize) // R16 |= R16 09/r +I(ORrr32 , "orl", 0x09, 0, X86II::MRMDestReg) // R32 |= R32 09/r +I(XORrr8 , "xorb", 0x30, 0, X86II::MRMDestReg) // R8 ^= R8 30/r +I(XORrr16 , "xorw", 0x31, 0, X86II::MRMDestReg | X86II::OpSize) // R16 ^= R16 31/r +I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg) // R32 ^= R32 31/r // Shift instructions -I(SHLrr8 , "shlb", 0xD2, 0, 0) // R8 <<= cl D2/4 -I(SHLrr16 , "shlw", 0xD3, 0, 0) // R16 <<= cl D3/4 -I(SHLrr32 , "shll", 0xD3, 0, 0) // R32 <<= cl D3/4 -I(SHLir8 , "shlb", 0xC0, 0, 0) // R8 <<= imm8 C0/4 ib -I(SHLir16 , "shlw", 0xC1, 0, 0) // R16 <<= imm8 C1/4 ib -I(SHLir32 , "shll", 0xC1, 0, 0) // R32 <<= imm8 C1/4 ib -I(SHRrr8 , "shrb", 0xD2, 0, 0) // R8 >>>= cl D2/5 -I(SHRrr16 , "shrw", 0xD3, 0, 0) // R16 >>>= cl D3/5 -I(SHRrr32 , "shrl", 0xD3, 0, 0) // R32 >>>= cl D3/5 -I(SHRir8 , "shrb", 0xC0, 0, 0) // R8 >>>= imm8 C0/5 ib -I(SHRir16 , "shrw", 0xC1, 0, 0) // R16 >>>= imm8 C1/5 ib -I(SHRir32 , "shrl", 0xC1, 0, 0) // R32 >>>= imm8 C1/5 ib -I(SARrr8 , "sarb", 0xD2, 0, 0) // R8 >>= cl D2/7 -I(SARrr16 , "sarw", 0xD3, 0, 0) // R16 >>= cl D3/7 -I(SARrr32 , "sarl", 0xD3, 0, 0) // R32 >>= cl D3/7 -I(SARir8 , "sarb", 0xC0, 0, 0) // R8 >>= imm8 C0/7 ib -I(SARir16 , "sarw", 0xC1, 0, 0) // R16 >>= imm8 C1/7 ib -I(SARir32 , "sarl", 0xC1, 0, 0) // R32 >>= imm8 C1/7 ib +I(SHLrr8 , "shlb", 0xD2, 0, 0) // R8 <<= cl D2/4 +I(SHLrr16 , "shlw", 0xD3, 0, X86II::OpSize) // R16 <<= cl D3/4 +I(SHLrr32 , "shll", 0xD3, 0, 0) // R32 <<= cl D3/4 +I(SHLir8 , "shlb", 0xC0, 0, 0) // R8 <<= imm8 C0/4 ib +I(SHLir16 , "shlw", 0xC1, 0, X86II::OpSize) // R16 <<= imm8 C1/4 ib +I(SHLir32 , "shll", 0xC1, 0, 0) // R32 <<= imm8 C1/4 ib +I(SHRrr8 , "shrb", 0xD2, 0, 0) // R8 >>>= cl D2/5 +I(SHRrr16 , "shrw", 0xD3, 0, X86II::OpSize) // R16 >>>= cl D3/5 +I(SHRrr32 , "shrl", 0xD3, 0, 0) // R32 >>>= cl D3/5 +I(SHRir8 , "shrb", 0xC0, 0, 0) // R8 >>>= imm8 C0/5 ib +I(SHRir16 , "shrw", 0xC1, 0, X86II::OpSize) // R16 >>>= imm8 C1/5 ib +I(SHRir32 , "shrl", 0xC1, 0, 0) // R32 >>>= imm8 C1/5 ib +I(SARrr8 , "sarb", 0xD2, 0, 0) // R8 >>= cl D2/7 +I(SARrr16 , "sarw", 0xD3, 0, X86II::OpSize) // R16 >>= cl D3/7 +I(SARrr32 , "sarl", 0xD3, 0, 0) // R32 >>= cl D3/7 +I(SARir8 , "sarb", 0xC0, 0, 0) // R8 >>= imm8 C0/7 ib +I(SARir16 , "sarw", 0xC1, 0, X86II::OpSize) // R16 >>= imm8 C1/7 ib +I(SARir32 , "sarl", 0xC1, 0, 0) // R32 >>= imm8 C1/7 ib // Floating point loads -I(FLDr4 , "flds", 0xD9, 0, X86II::Void) // push float D9/0 -I(FLDr8 , "fldl ", 0xDD, 0, X86II::Void) // push double DD/0 +I(FLDr4 , "flds", 0xD9, 0, X86II::Void) // push float D9/0 +I(FLDr8 , "fldl ", 0xDD, 0, X86II::Void) // push double DD/0 // Floating point compares -I(FUCOMPP , "fucompp", 0xDA, 0, X86II::Void) // compare+pop2x DA E9 +I(FUCOMPP , "fucompp", 0xDA, 0, X86II::Void) // compare+pop2x DA E9 // Floating point flag ops -I(FNSTSWr8 , "fnstsw", 0xDF, 0, X86II::Void) // AX = fp flags DF E0 +I(FNSTSWr8 , "fnstsw", 0xDF, 0, X86II::Void) // AX = fp flags DF E0 // Condition code ops, incl. set if equal/not equal/... -I(SAHF , "sahf", 0x9E, 0, 0) // flags = AH 9E -I(SETA , "seta", 0x97, 0, X86II::TB) // R8 = > unsign 0F 97 -I(SETAE , "setae", 0x93, 0, X86II::TB) // R8 = >=unsign 0F 93 -I(SETB , "setb", 0x92, 0, X86II::TB) // R8 = < unsign 0F 92 -I(SETBE , "setbe", 0x96, 0, X86II::TB) // R8 = <=unsign 0F 96 -I(SETE , "sete", 0x94, 0, X86II::TB) // R8 = == 0F 94 -I(SETG , "setg", 0x9F, 0, X86II::TB) // R8 = > signed 0F 9F -I(SETGE , "setge", 0x9D, 0, X86II::TB) // R8 = >=signed 0F 9D -I(SETL , "setl", 0x9C, 0, X86II::TB) // R8 = < signed 0F 9C -I(SETLE , "setle", 0x9E, 0, X86II::TB) // R8 = <=signed 0F 9E -I(SETNE , "setne", 0x95, 0, X86II::TB) // R8 = != 0F 95 +I(SAHF , "sahf", 0x9E, 0, 0) // flags = AH 9E +I(SETA , "seta", 0x97, 0, X86II::TB) // R8 = > unsign 0F 97 +I(SETAE , "setae", 0x93, 0, X86II::TB) // R8 = >=unsign 0F 93 +I(SETB , "setb", 0x92, 0, X86II::TB) // R8 = < unsign 0F 92 +I(SETBE , "setbe", 0x96, 0, X86II::TB) // R8 = <=unsign 0F 96 +I(SETE , "sete", 0x94, 0, X86II::TB) // R8 = == 0F 94 +I(SETG , "setg", 0x9F, 0, X86II::TB) // R8 = > signed 0F 9F +I(SETGE , "setge", 0x9D, 0, X86II::TB) // R8 = >=signed 0F 9D +I(SETL , "setl", 0x9C, 0, X86II::TB) // R8 = < signed 0F 9C +I(SETLE , "setle", 0x9E, 0, X86II::TB) // R8 = <=signed 0F 9E +I(SETNE , "setne", 0x95, 0, X86II::TB) // R8 = != 0F 95 // Integer comparisons -I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg) // compare R8,R8 38/r -I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg) // compare R16,R16 39/r -I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg) // compare R32,R32 39/r -I(CMPri8 , "cmp", 0x80, 0, 0) // compare R8, imm8 80 /7 ib +I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg) // compare R8,R8 38/r +I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg | X86II::OpSize) // compare R16,R16 39/r +I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg) // compare R32,R32 39/r +I(CMPri8 , "cmp", 0x80, 0, 0) // compare R8, imm8 80 /7 ib // Sign extenders (first 3 are good for DIV/IDIV; the others are more general) -I(CBW , "cbw", 0x98, 0, X86II::RawFrm) // AX = signext(AL) -I(CWD , "cwd", 0x99, 0, X86II::RawFrm) // DX:AX = signext(AX) -I(CDQ , "cdq", 0x99, 0, X86II::RawFrm) // EDX:EAX = signext(EAX) -I(MOVSXr16r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB) // R32 = signext(R8) 0F BE /r -I(MOVSXr32r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB) // R32 = signext(R8) 0F BE /r -I(MOVSXr32r16 , "movsx", 0xBF, 0, X86II::MRMSrcReg | X86II::TB) // R32 = signext(R16) 0F BF /r -I(MOVZXr16r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB) // R32 = zeroext(R8) 0F B6 /r -I(MOVZXr32r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB) // R32 = zeroext(R8) 0F B6 /r -I(MOVZXr32r16 , "movzx", 0xB7, 0, X86II::MRMSrcReg | X86II::TB) // R32 = zeroext(R16) 0F B7 /r +I(CBW , "cbw", 0x98, 0, X86II::RawFrm) // AX = signext(AL) +I(CWD , "cwd", 0x99, 0, X86II::RawFrm) // DX:AX = signext(AX) +I(CDQ , "cdq", 0x99, 0, X86II::RawFrm) // EDX:EAX = signext(EAX) +I(MOVSXr16r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB | // R16 = signext(R8) + X86II::OpSize) +I(MOVSXr32r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB) // R32 = signext(R8) +I(MOVSXr32r16 , "movsx", 0xBF, 0, X86II::MRMSrcReg | X86II::TB) // R32 = signext(R16) +I(MOVZXr16r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB | // R16 = zeroext(R8) + X86II::OpSize) +I(MOVZXr32r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB) // R32 = zeroext(R8) +I(MOVZXr32r16 , "movzx", 0xB7, 0, X86II::MRMSrcReg | X86II::TB) // R32 = zeroext(R16) // At this point, I is dead, so undefine the macro #undef I From lattner at cs.uiuc.edu Wed Nov 20 20:01:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 20:01:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211210200.UAA20195@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.30 -> 1.31 --- Log message: Dont' set flags --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.30 llvm/lib/Target/X86/InstSelectSimple.cpp:1.31 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.30 Tue Nov 19 18:58:23 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Nov 20 19:59:50 2002 @@ -240,7 +240,7 @@ // Move fp status word (concodes) to ax. BuildMI (BB, X86::FNSTSWr8, 1, X86::AX); // Load real concodes from ax. - BuildMI (BB, X86::SAHF, 1, X86::EFLAGS).addReg(X86::AH); + BuildMI (BB, X86::SAHF, 1).addReg(X86::AH); } else { // integer comparison @@ -250,16 +250,13 @@ switch (comparisonWidth) { case 1: - BuildMI (BB, X86::CMPrr8, 2, - X86::EFLAGS).addReg (reg1).addReg (reg2); + BuildMI (BB, X86::CMPrr8, 2).addReg (reg1).addReg (reg2); break; case 2: - BuildMI (BB, X86::CMPrr16, 2, - X86::EFLAGS).addReg (reg1).addReg (reg2); + BuildMI (BB, X86::CMPrr16, 2).addReg (reg1).addReg (reg2); break; case 4: - BuildMI (BB, X86::CMPrr32, 2, - X86::EFLAGS).addReg (reg1).addReg (reg2); + BuildMI (BB, X86::CMPrr32, 2).addReg (reg1).addReg (reg2); break; case 8: default: @@ -413,7 +410,7 @@ // followed by jump-if-equal to ifFalse, and jump-if-nonequal to // ifTrue unsigned int condReg = getReg (BI.getCondition ()); - BuildMI (BB, X86::CMPri8, 2, X86::EFLAGS).addReg (condReg).addZImm (0); + BuildMI (BB, X86::CMPri8, 2).addReg (condReg).addZImm (0); BuildMI (BB, X86::JNE, 1).addPCDisp (BI.getSuccessor (0)); BuildMI (BB, X86::JE, 1).addPCDisp (BI.getSuccessor (1)); } From lattner at cs.uiuc.edu Wed Nov 20 20:01:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Nov 20 20:01:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211210200.UAA20202@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.10 -> 1.11 --- Log message: Support Registers of the form (B8+ rd) for example --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.10 llvm/lib/Target/X86/Printer.cpp:1.11 --- llvm/lib/Target/X86/Printer.cpp:1.10 Wed Nov 20 19:33:44 2002 +++ llvm/lib/Target/X86/Printer.cpp Wed Nov 20 20:00:20 2002 @@ -78,7 +78,11 @@ else O << "%reg" << MO.getReg(); return; - + + case MachineOperand::MO_SignExtendedImmed: + case MachineOperand::MO_UnextendedImmed: + O << (int)MO.getImmedValue(); + return; default: O << ""; return; } @@ -97,10 +101,24 @@ return O; } +static std::ostream &emitConstant(std::ostream &O, unsigned Val, unsigned Size){ + // Output the constant in little endian byte order... + for (unsigned i = 0; i != Size; ++i) { + toHex(O, Val) << " "; + Val >>= 8; + } + return O; +} + static bool isReg(const MachineOperand &MO) { - return MO.getType()==MachineOperand::MO_VirtualRegister || - MO.getType()==MachineOperand::MO_MachineRegister; + return MO.getType() == MachineOperand::MO_VirtualRegister || + MO.getType() == MachineOperand::MO_MachineRegister; +} + +static bool isImmediate(const MachineOperand &MO) { + return MO.getType() == MachineOperand::MO_SignExtendedImmed || + MO.getType() == MachineOperand::MO_UnextendedImmed; } @@ -150,11 +168,12 @@ switch (Desc.TSFlags & X86II::FormMask) { case X86II::OtherFrm: - O << "\t\t"; + O << "\t\t\t"; O << "-"; MI->print(O, TM); break; case X86II::RawFrm: - toHex(O, getBaseOpcodeFor(Opcode)) << "\t\t"; + toHex(O, getBaseOpcodeFor(Opcode)); + O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -165,9 +184,35 @@ return; - case X86II::AddRegFrm: - O << "\t\t-"; MI->print(O, TM); break; - + case X86II::AddRegFrm: { + // There are currently two forms of acceptable AddRegFrm instructions. + // Either the instruction JUST takes a single register (like inc, dec, etc), + // or it takes a register and an immediate of the same size as the register + // (move immediate f.e.). + // + assert(isReg(MI->getOperand(0)) && + (MI->getNumOperands() == 1 || + (MI->getNumOperands() == 2 && isImmediate(MI->getOperand(1)))) && + "Illegal form for AddRegFrm instruction!"); + + unsigned Reg = MI->getOperand(0).getReg(); + toHex(O, getBaseOpcodeFor(Opcode) + getX86RegNum(Reg)) << " "; + + if (MI->getNumOperands() == 2) { + unsigned Size = 4; + emitConstant(O, MI->getOperand(1).getImmedValue(), Size); + } + + O << "\n\t\t\t\t"; + O << getName(MI->getOpCode()) << " "; + printOp(O, MI->getOperand(0), RI); + if (MI->getNumOperands() == 2) { + O << ", "; + printOp(O, MI->getOperand(MI->getNumOperands()-1), RI); + } + O << "\n"; + return; + } case X86II::MRMDestReg: { // There are two acceptable forms of MRMDestReg instructions, those with 3 // and 2 operands: @@ -193,7 +238,7 @@ unsigned ExtraReg = MI->getOperand(MI->getNumOperands()-1).getReg(); toHex(O, regModRMByte(ModRMReg, getX86RegNum(ExtraReg))); - O << "\t\t"; + O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; printOp(O, MI->getOperand(0), RI); O << ", "; @@ -225,7 +270,7 @@ unsigned ExtraReg = MI->getOperand(0).getReg(); toHex(O, regModRMByte(ModRMReg, getX86RegNum(ExtraReg))); - O << "\t"; + O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; printOp(O, MI->getOperand(0), RI); O << ", "; @@ -236,6 +281,6 @@ case X86II::MRMDestMem: case X86II::MRMSrcMem: default: - O << "\t\t-"; MI->print(O, TM); break; + O << "\t\t\t-"; MI->print(O, TM); break; } } From lattner at cs.uiuc.edu Thu Nov 21 09:53:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 09:53:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211211552.JAA27099@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.31 -> 1.32 --- Log message: Simplify setcc code a bit --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.31 llvm/lib/Target/X86/InstSelectSimple.cpp:1.32 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.31 Wed Nov 20 19:59:50 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Nov 21 09:52:38 2002 @@ -81,7 +81,13 @@ void visitXor(BinaryOperator &B) { visitSimpleBinary(B, 4); } // Binary comparison operators - void visitSetCondInst(SetCondInst &I); + void visitSetCCInst(SetCondInst &I, unsigned OpNum); + void visitSetEQ(SetCondInst &I) { visitSetCCInst(I, 0); } + void visitSetNE(SetCondInst &I) { visitSetCCInst(I, 1); } + void visitSetLT(SetCondInst &I) { visitSetCCInst(I, 2); } + void visitSetGT(SetCondInst &I) { visitSetCCInst(I, 3); } + void visitSetLE(SetCondInst &I) { visitSetCCInst(I, 4); } + void visitSetGE(SetCondInst &I) { visitSetCCInst(I, 5); } // Memory Instructions void visitLoadInst(LoadInst &I); @@ -193,77 +199,52 @@ /// compare-and-pop-twice, and then copying the concodes to the main /// processor's concodes (I didn't make this up, it's in the Intel manual) /// -void -ISel::visitSetCondInst (SetCondInst & I) -{ +void ISel::visitSetCCInst(SetCondInst &I, unsigned OpNum) { // The arguments are already supposed to be of the same type. - Value *var1 = I.getOperand (0); - Value *var2 = I.getOperand (1); - unsigned reg1 = getReg (var1); - unsigned reg2 = getReg (var2); - unsigned resultReg = getReg (I); - unsigned comparisonWidth = var1->getType ()->getPrimitiveSize (); - unsigned unsignedComparison = var1->getType ()->isUnsigned (); - unsigned resultWidth = I.getType ()->getPrimitiveSize (); - bool fpComparison = var1->getType ()->isFloatingPoint (); - if (fpComparison) - { - // Push the variables on the stack with fldl opcodes. - // FIXME: assuming var1, var2 are in memory, if not, spill to - // stack first - switch (comparisonWidth) - { - case 4: - BuildMI (BB, X86::FLDr4, 1, X86::NoReg).addReg (reg1); - break; - case 8: - BuildMI (BB, X86::FLDr8, 1, X86::NoReg).addReg (reg1); - break; - default: - visitInstruction (I); - break; - } - switch (comparisonWidth) - { - case 4: - BuildMI (BB, X86::FLDr4, 1, X86::NoReg).addReg (reg2); - break; - case 8: - BuildMI (BB, X86::FLDr8, 1, X86::NoReg).addReg (reg2); - break; - default: - visitInstruction (I); - break; - } - // (Non-trapping) compare and pop twice. - BuildMI (BB, X86::FUCOMPP, 0); - // Move fp status word (concodes) to ax. - BuildMI (BB, X86::FNSTSWr8, 1, X86::AX); - // Load real concodes from ax. - BuildMI (BB, X86::SAHF, 1).addReg(X86::AH); - } - else - { // integer comparison - // Emit: cmp , (do the comparison). We can - // compare 8-bit with 8-bit, 16-bit with 16-bit, 32-bit with - // 32-bit. - switch (comparisonWidth) - { - case 1: - BuildMI (BB, X86::CMPrr8, 2).addReg (reg1).addReg (reg2); - break; - case 2: - BuildMI (BB, X86::CMPrr16, 2).addReg (reg1).addReg (reg2); - break; - case 4: - BuildMI (BB, X86::CMPrr32, 2).addReg (reg1).addReg (reg2); - break; - case 8: - default: - visitInstruction (I); - break; - } - } + const Type *CompTy = I.getOperand(0)->getType(); + unsigned reg1 = getReg(I.getOperand(0)); + unsigned reg2 = getReg(I.getOperand(1)); + + unsigned Class = getClass(CompTy); + switch (Class) { + // Emit: cmp , (do the comparison). We can + // compare 8-bit with 8-bit, 16-bit with 16-bit, 32-bit with + // 32-bit. + case cByte: + BuildMI (BB, X86::CMPrr8, 2).addReg (reg1).addReg (reg2); + break; + case cShort: + BuildMI (BB, X86::CMPrr16, 2).addReg (reg1).addReg (reg2); + break; + case cInt: + BuildMI (BB, X86::CMPrr32, 2).addReg (reg1).addReg (reg2); + break; + + // Push the variables on the stack with fldl opcodes. + // FIXME: assuming var1, var2 are in memory, if not, spill to + // stack first + case cFloat: // Floats + BuildMI (BB, X86::FLDr4, 1, X86::NoReg).addReg (reg1); + BuildMI (BB, X86::FLDr4, 1, X86::NoReg).addReg (reg2); + break; + case cDouble: // Doubles + BuildMI (BB, X86::FLDr8, 1, X86::NoReg).addReg (reg1); + BuildMI (BB, X86::FLDr8, 1, X86::NoReg).addReg (reg2); + break; + case cLong: + default: + visitInstruction(I); + } + + if (CompTy->isFloatingPoint()) { + // (Non-trapping) compare and pop twice. + BuildMI (BB, X86::FUCOMPP, 0); + // Move fp status word (concodes) to ax. + BuildMI (BB, X86::FNSTSWr8, 1, X86::AX); + // Load real concodes from ax. + BuildMI (BB, X86::SAHF, 1).addReg(X86::AH); + } + // Emit setOp instruction (extract concode; clobbers ax), // using the following mapping: // LLVM -> X86 signed X86 unsigned @@ -274,59 +255,16 @@ // setgt -> setg seta // setle -> setle setbe // setge -> setge setae - switch (I.getOpcode ()) - { - case Instruction::SetEQ: - BuildMI (BB, X86::SETE, 0, X86::AL); - break; - case Instruction::SetGE: - if (unsignedComparison) - BuildMI (BB, X86::SETAE, 0, X86::AL); - else - BuildMI (BB, X86::SETGE, 0, X86::AL); - break; - case Instruction::SetGT: - if (unsignedComparison) - BuildMI (BB, X86::SETA, 0, X86::AL); - else - BuildMI (BB, X86::SETG, 0, X86::AL); - break; - case Instruction::SetLE: - if (unsignedComparison) - BuildMI (BB, X86::SETBE, 0, X86::AL); - else - BuildMI (BB, X86::SETLE, 0, X86::AL); - break; - case Instruction::SetLT: - if (unsignedComparison) - BuildMI (BB, X86::SETB, 0, X86::AL); - else - BuildMI (BB, X86::SETL, 0, X86::AL); - break; - case Instruction::SetNE: - BuildMI (BB, X86::SETNE, 0, X86::AL); - break; - default: - visitInstruction (I); - break; - } + + static const unsigned OpcodeTab[2][6] = { + { X86::SETE, X86::SETNE, X86::SETB, X86::SETA, X86::SETBE, X86::SETAE }, + { X86::SETE, X86::SETNE, X86::SETL, X86::SETG, X86::SETLE, X86::SETGE }, + }; + + BuildMI(BB, OpcodeTab[CompTy->isSigned()][OpNum], 0, X86::AL); + // Put it in the result using a move. - switch (resultWidth) - { - case 1: - BuildMI (BB, X86::MOVrr8, 1, resultReg).addReg (X86::AL); - break; - case 2: - BuildMI (BB, X86::MOVZXr16r8, 1, resultReg).addReg (X86::AL); - break; - case 4: - BuildMI (BB, X86::MOVZXr32r8, 1, resultReg).addReg (X86::AL); - break; - case 8: - default: - visitInstruction (I); - break; - } + BuildMI (BB, X86::MOVrr8, 1, getReg(I)).addReg(X86::AL); } From lattner at cs.uiuc.edu Thu Nov 21 10:20:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 10:20:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp X86InstrInfo.def Message-ID: <200211211619.KAA27283@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.32 -> 1.33 X86InstrInfo.def updated: 1.22 -> 1.23 --- Log message: Rename the SetCC X86 instructions to reflect the fact that they are the register versions --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.32 llvm/lib/Target/X86/InstSelectSimple.cpp:1.33 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.32 Thu Nov 21 09:52:38 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Nov 21 10:19:42 2002 @@ -257,8 +257,8 @@ // setge -> setge setae static const unsigned OpcodeTab[2][6] = { - { X86::SETE, X86::SETNE, X86::SETB, X86::SETA, X86::SETBE, X86::SETAE }, - { X86::SETE, X86::SETNE, X86::SETL, X86::SETG, X86::SETLE, X86::SETGE }, + {X86::SETEr, X86::SETNEr, X86::SETBr, X86::SETAr, X86::SETBEr, X86::SETAEr}, + {X86::SETEr, X86::SETNEr, X86::SETLr, X86::SETGr, X86::SETLEr, X86::SETGEr}, }; BuildMI(BB, OpcodeTab[CompTy->isSigned()][OpNum], 0, X86::AL); Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.22 llvm/lib/Target/X86/X86InstrInfo.def:1.23 --- llvm/lib/Target/X86/X86InstrInfo.def:1.22 Wed Nov 20 19:33:28 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Thu Nov 21 10:19:42 2002 @@ -122,16 +122,16 @@ // Condition code ops, incl. set if equal/not equal/... I(SAHF , "sahf", 0x9E, 0, 0) // flags = AH 9E -I(SETA , "seta", 0x97, 0, X86II::TB) // R8 = > unsign 0F 97 -I(SETAE , "setae", 0x93, 0, X86II::TB) // R8 = >=unsign 0F 93 -I(SETB , "setb", 0x92, 0, X86II::TB) // R8 = < unsign 0F 92 -I(SETBE , "setbe", 0x96, 0, X86II::TB) // R8 = <=unsign 0F 96 -I(SETE , "sete", 0x94, 0, X86II::TB) // R8 = == 0F 94 -I(SETG , "setg", 0x9F, 0, X86II::TB) // R8 = > signed 0F 9F -I(SETGE , "setge", 0x9D, 0, X86II::TB) // R8 = >=signed 0F 9D -I(SETL , "setl", 0x9C, 0, X86II::TB) // R8 = < signed 0F 9C -I(SETLE , "setle", 0x9E, 0, X86II::TB) // R8 = <=signed 0F 9E -I(SETNE , "setne", 0x95, 0, X86II::TB) // R8 = != 0F 95 +I(SETAr , "seta", 0x97, 0, X86II::TB) // R8 = > unsign 0F 97 +I(SETAEr , "setae", 0x93, 0, X86II::TB) // R8 = >=unsign 0F 93 +I(SETBr , "setb", 0x92, 0, X86II::TB) // R8 = < unsign 0F 92 +I(SETBEr , "setbe", 0x96, 0, X86II::TB) // R8 = <=unsign 0F 96 +I(SETEr , "sete", 0x94, 0, X86II::TB) // R8 = == 0F 94 +I(SETGr , "setg", 0x9F, 0, X86II::TB) // R8 = > signed 0F 9F +I(SETGEr , "setge", 0x9D, 0, X86II::TB) // R8 = >=signed 0F 9D +I(SETLr , "setl", 0x9C, 0, X86II::TB) // R8 = < signed 0F 9C +I(SETLEr , "setle", 0x9E, 0, X86II::TB) // R8 = <=signed 0F 9E +I(SETNEr , "setne", 0x95, 0, X86II::TB) // R8 = != 0F 95 // Integer comparisons I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg) // compare R8,R8 38/r From lattner at cs.uiuc.edu Thu Nov 21 10:55:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 10:55:01 2002 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200211211654.KAA27888@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.42 -> 1.43 --- Log message: User defined operators are not supposed to live beyond the lifetime of the pass. Detect and flag them. --- Diffs of the changes: Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.42 llvm/lib/VMCore/Verifier.cpp:1.43 --- llvm/lib/VMCore/Verifier.cpp:1.42 Wed Nov 20 12:33:41 2002 +++ llvm/lib/VMCore/Verifier.cpp Thu Nov 21 10:54:22 2002 @@ -137,6 +137,8 @@ void visitInstruction(Instruction &I); void visitTerminatorInst(TerminatorInst &I); void visitReturnInst(ReturnInst &RI); + void visitUserOp1(Instruction &I); + void visitUserOp2(Instruction &I) { visitUserOp1(I); } // CheckFailed - A check failed, so print out the condition and the message // that failed. This provides a nice place to put a breakpoint if you want @@ -248,6 +250,13 @@ visitTerminatorInst(RI); } +// visitUserOp1 - User defined operators shouldn't live beyond the lifetime of a +// pass, if any exist, it's an error. +// +void Verifier::visitUserOp1(Instruction &I) { + Assert1(0, "User-defined operators should not live outside of a pass!", + &I); +} // visitPHINode - Ensure that a PHI node is well formed. void Verifier::visitPHINode(PHINode &PN) { From lattner at cs.uiuc.edu Thu Nov 21 11:10:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 11:10:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211211709.LAA28251@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.11 -> 1.12 --- Log message: Add printing support for /0 /1 type instructions --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.11 llvm/lib/Target/X86/Printer.cpp:1.12 --- llvm/lib/Target/X86/Printer.cpp:1.11 Wed Nov 20 20:00:20 2002 +++ llvm/lib/Target/X86/Printer.cpp Thu Nov 21 11:09:01 2002 @@ -208,7 +208,7 @@ printOp(O, MI->getOperand(0), RI); if (MI->getNumOperands() == 2) { O << ", "; - printOp(O, MI->getOperand(MI->getNumOperands()-1), RI); + printOp(O, MI->getOperand(1), RI); } O << "\n"; return; @@ -278,6 +278,49 @@ O << "\n"; return; } + + case X86II::MRMS0r: case X86II::MRMS1r: + case X86II::MRMS2r: case X86II::MRMS3r: + case X86II::MRMS4r: case X86II::MRMS5r: + case X86II::MRMS6r: case X86II::MRMS7r: { + unsigned ExtraField = (Desc.TSFlags & X86II::FormMask)-X86II::MRMS0r; + + // In this form, the following are valid formats: + // 1. sete r + // 2. shl rdest, rinput + // 3. sbb rdest, rinput, immediate [rdest = rinput] + // + assert(MI->getNumOperands() > 0 && MI->getNumOperands() < 4 && + isReg(MI->getOperand(0)) && "Bad MRMSxR format!"); + assert((MI->getNumOperands() < 2 || isReg(MI->getOperand(1))) && + "Bad MRMSxR format!"); + assert((MI->getNumOperands() < 3 || isImmediate(MI->getOperand(2))) && + "Bad MRMSxR format!"); + + if (MI->getNumOperands() > 1 && + MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) + O << "**"; + + toHex(O, getBaseOpcodeFor(Opcode)) << " "; + toHex(O, regModRMByte(MI->getOperand(0).getReg(), ExtraField)); + + if (MI->getNumOperands() == 3) { + unsigned Size = 4; + emitConstant(O, MI->getOperand(1).getImmedValue(), Size); + } + + O << "\n\t\t\t\t"; + O << getName(MI->getOpCode()) << " "; + printOp(O, MI->getOperand(0), RI); + if (MI->getNumOperands() == 3) { + O << ", "; + printOp(O, MI->getOperand(2), RI); + } + O << "\n"; + + return; + } + case X86II::MRMDestMem: case X86II::MRMSrcMem: default: From lattner at cs.uiuc.edu Thu Nov 21 11:10:07 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 11:10:07 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.h Message-ID: <200211211709.LAA28256@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.h updated: 1.12 -> 1.13 --- Log message: Add support for /0 /1, etc type instructions --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.12 llvm/lib/Target/X86/X86InstrInfo.h:1.13 --- llvm/lib/Target/X86/X86InstrInfo.h:1.12 Wed Nov 20 19:32:55 2002 +++ llvm/lib/Target/X86/X86InstrInfo.h Thu Nov 21 11:08:49 2002 @@ -52,24 +52,35 @@ /// MRMSrcMem = 6, - /// TODO: Mod/RM that uses a fixed opcode extension, like /0 + /// MRMS[0-7][rm] - These forms are used to represent instructions that use + /// a Mod/RM byte, and use the middle field to hold extended opcode + /// information. In the intel manual these are represented as /0, /1, ... + /// - FormMask = 7, + // First, instructions that operate on a register r/m operand... + MRMS0r = 16, MRMS1r = 17, MRMS2r = 18, MRMS3r = 19, // Format /0 /1 /2 /3 + MRMS4r = 20, MRMS5r = 21, MRMS6r = 22, MRMS7r = 23, // Format /4 /5 /6 /7 + + // Next, instructions that operate on a memory r/m operand... + MRMS0m = 24, MRMS1m = 25, MRMS2m = 26, MRMS3m = 27, // Format /0 /1 /2 /3 + MRMS4m = 28, MRMS5m = 29, MRMS6m = 30, MRMS7m = 31, // Format /4 /5 /6 /7 + + FormMask = 31, //===------------------------------------------------------------------===// // Actual flags... /// Void - Set if this instruction produces no value - Void = 1 << 3, + Void = 1 << 5, // TB - TwoByte - Set if this instruction has a two byte opcode, which // starts with a 0x0F byte before the real opcode. - TB = 1 << 4, + TB = 1 << 6, // OpSize - Set if this instruction requires an operand size prefix (0x66), // which most often indicates that the instruction operates on 16 bit data // instead of 32 bit data. - OpSize = 1 << 5, + OpSize = 1 << 7, }; } From lattner at cs.uiuc.edu Thu Nov 21 11:12:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 11:12:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200211211711.LAA28275@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def updated: 1.23 -> 1.24 --- Log message: Add printing support for sahf & setcc --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.23 llvm/lib/Target/X86/X86InstrInfo.def:1.24 --- llvm/lib/Target/X86/X86InstrInfo.def:1.23 Thu Nov 21 10:19:42 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Thu Nov 21 11:10:57 2002 @@ -91,7 +91,7 @@ I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg) // R32 ^= R32 31/r // Shift instructions -I(SHLrr8 , "shlb", 0xD2, 0, 0) // R8 <<= cl D2/4 +I(SHLrr8 , "shlb", 0xD2, 0, X86II::MRMS4r) // R8 <<= cl D2/4 I(SHLrr16 , "shlw", 0xD3, 0, X86II::OpSize) // R16 <<= cl D3/4 I(SHLrr32 , "shll", 0xD3, 0, 0) // R32 <<= cl D3/4 I(SHLir8 , "shlb", 0xC0, 0, 0) // R8 <<= imm8 C0/4 ib @@ -121,22 +121,22 @@ I(FNSTSWr8 , "fnstsw", 0xDF, 0, X86II::Void) // AX = fp flags DF E0 // Condition code ops, incl. set if equal/not equal/... -I(SAHF , "sahf", 0x9E, 0, 0) // flags = AH 9E -I(SETAr , "seta", 0x97, 0, X86II::TB) // R8 = > unsign 0F 97 -I(SETAEr , "setae", 0x93, 0, X86II::TB) // R8 = >=unsign 0F 93 -I(SETBr , "setb", 0x92, 0, X86II::TB) // R8 = < unsign 0F 92 -I(SETBEr , "setbe", 0x96, 0, X86II::TB) // R8 = <=unsign 0F 96 -I(SETEr , "sete", 0x94, 0, X86II::TB) // R8 = == 0F 94 -I(SETGr , "setg", 0x9F, 0, X86II::TB) // R8 = > signed 0F 9F -I(SETGEr , "setge", 0x9D, 0, X86II::TB) // R8 = >=signed 0F 9D -I(SETLr , "setl", 0x9C, 0, X86II::TB) // R8 = < signed 0F 9C -I(SETLEr , "setle", 0x9E, 0, X86II::TB) // R8 = <=signed 0F 9E -I(SETNEr , "setne", 0x95, 0, X86II::TB) // R8 = != 0F 95 +I(SAHF , "sahf", 0x9E, 0, X86II::RawFrm) // flags = AH +I(SETBr , "setb", 0x92, 0, X86II::TB | X86II::MRMS0r) // R8 = < unsign +I(SETAEr , "setae", 0x93, 0, X86II::TB | X86II::MRMS0r) // R8 = >=unsign +I(SETEr , "sete", 0x94, 0, X86II::TB | X86II::MRMS0r) // R8 = == +I(SETNEr , "setne", 0x95, 0, X86II::TB | X86II::MRMS0r) // R8 = != +I(SETBEr , "setbe", 0x96, 0, X86II::TB | X86II::MRMS0r) // R8 = <=unsign +I(SETAr , "seta", 0x97, 0, X86II::TB | X86II::MRMS0r) // R8 = > unsign +I(SETLr , "setl", 0x9C, 0, X86II::TB | X86II::MRMS0r) // R8 = < signed +I(SETGEr , "setge", 0x9D, 0, X86II::TB | X86II::MRMS0r) // R8 = >=signed +I(SETLEr , "setle", 0x9E, 0, X86II::TB | X86II::MRMS0r) // R8 = <=signed +I(SETGr , "setg", 0x9F, 0, X86II::TB | X86II::MRMS0r) // R8 = > signed // Integer comparisons -I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg) // compare R8,R8 38/r -I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg | X86II::OpSize) // compare R16,R16 39/r -I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg) // compare R32,R32 39/r +I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg) // compare R8,R8 +I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg | X86II::OpSize) // compare R16,R16 +I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg) // compare R32,R32 I(CMPri8 , "cmp", 0x80, 0, 0) // compare R8, imm8 80 /7 ib // Sign extenders (first 3 are good for DIV/IDIV; the others are more general) From lattner at cs.uiuc.edu Thu Nov 21 11:14:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 11:14:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200211211713.LAA28293@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def updated: 1.24 -> 1.25 --- Log message: Remove opcode information for instructions that are completely defined now --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.24 llvm/lib/Target/X86/X86InstrInfo.def:1.25 --- llvm/lib/Target/X86/X86InstrInfo.def:1.24 Thu Nov 21 11:10:57 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Thu Nov 21 11:12:55 2002 @@ -38,18 +38,18 @@ I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void) // ret I(JMP , "jmp", 0x00, M_BRANCH_FLAG, X86II::Void) // jmp foo EB|E9 cb|w I(JNE , "jne", 0x00, M_BRANCH_FLAG, X86II::Void) // 75 cb, or 0f 85 cw|cd -I(JE , "je", 0x00, M_BRANCH_FLAG, X86II::Void) // 74 cb, or 0f 84 cw|cd +I(JE , "je", 0x00, M_BRANCH_FLAG, X86II::Void) // 74 cb, or 0f 84 cw|cd // Misc instructions I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm) // leave // Move instructions -I(MOVrr8 , "movb", 0x88, 0, X86II::MRMDestReg) // R8 = R8 88/r -I(MOVrr16 , "movw", 0x89, 0, X86II::MRMDestReg | X86II::OpSize) // R16 = R16 89/r -I(MOVrr32 , "movl", 0x89, 0, X86II::MRMDestReg) // R32 = R32 89/r -I(MOVir8 , "movb", 0xB0, 0, X86II::AddRegFrm) // R8 = imm8 B0+ rb -I(MOVir16 , "movw", 0xB8, 0, X86II::AddRegFrm | X86II::OpSize) // R16 = imm16 B8+ rw -I(MOVir32 , "movl", 0xB8, 0, X86II::AddRegFrm) // R32 = imm32 B8+ rd +I(MOVrr8 , "movb", 0x88, 0, X86II::MRMDestReg) // R8 = R8 +I(MOVrr16 , "movw", 0x89, 0, X86II::MRMDestReg | X86II::OpSize) // R16 = R16 +I(MOVrr32 , "movl", 0x89, 0, X86II::MRMDestReg) // R32 = R32 +I(MOVir8 , "movb", 0xB0, 0, X86II::AddRegFrm) // R8 = imm8 +I(MOVir16 , "movw", 0xB8, 0, X86II::AddRegFrm | X86II::OpSize) // R16 = imm16 +I(MOVir32 , "movl", 0xB8, 0, X86II::AddRegFrm) // R32 = imm32 I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem) // R8 = [mem] 8A/r I(MOVmr16 , "movw", 0x8B, 0, X86II::MRMSrcMem | X86II::OpSize) // R16 = [mem] 8B/r I(MOVmr32 , "movl", 0x8B, 0, X86II::MRMSrcMem) // R32 = [mem] 8B/r @@ -59,12 +59,12 @@ I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void) // [mem] = R32 89/r // Arithmetic instructions -I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg) // R8 += R8 00/r -I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg | X86II::OpSize) // R16 += R16 01/r -I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg) // R32 += R32 01/r -I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg) // R8 -= R8 2A/r -I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize) // R16 -= R16 2B/r -I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg) // R32 -= R32 2B/r +I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg) // R8 += R8 +I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg | X86II::OpSize) // R16 += R16 +I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg) // R32 += R32 +I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg) // R8 -= R8 +I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize) // R16 -= R16 +I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg) // R32 -= R32 I(MULrr8 , "mulb", 0xF6, 0, X86II::Void) // AX = AL*R8 F6/4 I(MULrr16 , "mulw", 0xF7, 0, X86II::Void | X86II::OpSize) // DX:AX= AX*R16 F7/4 I(MULrr32 , "mull", 0xF7, 0, X86II::Void) // ED:EA= EA*R32 F7/4 @@ -80,15 +80,15 @@ I(IDIVrr32 , "idivl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6 // Logical operators -I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg) // R8 &= R8 20/r -I(ANDrr16 , "andw", 0x21, 0, X86II::MRMDestReg | X86II::OpSize) // R16 &= R16 21/r -I(ANDrr32 , "andl", 0x21, 0, X86II::MRMDestReg) // R32 &= R32 21/r -I(ORrr8 , "orb", 0x08, 0, X86II::MRMDestReg) // R8 |= R8 08/r -I(ORrr16 , "orw", 0x09, 0, X86II::MRMDestReg | X86II::OpSize) // R16 |= R16 09/r -I(ORrr32 , "orl", 0x09, 0, X86II::MRMDestReg) // R32 |= R32 09/r -I(XORrr8 , "xorb", 0x30, 0, X86II::MRMDestReg) // R8 ^= R8 30/r -I(XORrr16 , "xorw", 0x31, 0, X86II::MRMDestReg | X86II::OpSize) // R16 ^= R16 31/r -I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg) // R32 ^= R32 31/r +I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg) // R8 &= R8 +I(ANDrr16 , "andw", 0x21, 0, X86II::MRMDestReg | X86II::OpSize) // R16 &= R16 +I(ANDrr32 , "andl", 0x21, 0, X86II::MRMDestReg) // R32 &= R32 +I(ORrr8 , "orb", 0x08, 0, X86II::MRMDestReg) // R8 |= R8 +I(ORrr16 , "orw", 0x09, 0, X86II::MRMDestReg | X86II::OpSize) // R16 |= R16 +I(ORrr32 , "orl", 0x09, 0, X86II::MRMDestReg) // R32 |= R32 +I(XORrr8 , "xorb", 0x30, 0, X86II::MRMDestReg) // R8 ^= R8 +I(XORrr16 , "xorw", 0x31, 0, X86II::MRMDestReg | X86II::OpSize) // R16 ^= R16 +I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg) // R32 ^= R32 // Shift instructions I(SHLrr8 , "shlb", 0xD2, 0, X86II::MRMS4r) // R8 <<= cl D2/4 From lattner at cs.uiuc.edu Thu Nov 21 11:19:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 11:19:00 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/test-ret.ll Message-ID: <200211211718.LAA28439@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: test-ret.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Nov 21 11:21:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 11:21:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/test-phi.ll test0.ll test1.ll test2.ll test4.ll Message-ID: <200211211720.LAA28475@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: test-phi.ll added (r1.1) test0.ll (r1.4) removed test1.ll (r1.1) removed test2.ll (r1.1) removed test4.ll (r1.2) removed --- Log message: Shuffle testcases around --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Nov 21 11:21:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 11:21:05 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/test-branch.ll test3.ll Message-ID: <200211211720.LAA28489@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: test-branch.ll added (r1.1) test3.ll (r1.2) removed --- Log message: Move test --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Nov 21 11:28:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 11:28:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211211727.LAA28555@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.33 -> 1.34 --- Log message: Fix a bug that prevented compilation of multiple functions --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.33 llvm/lib/Target/X86/InstSelectSimple.cpp:1.34 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.33 Thu Nov 21 10:19:42 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Nov 21 11:26:58 2002 @@ -44,6 +44,7 @@ F = &MachineFunction::construct(&Fn, TM); visit(Fn); RegMap.clear(); + CurReg = MRegisterInfo::FirstVirtualRegister; F = 0; return false; // We never modify the LLVM itself. } From lattner at cs.uiuc.edu Thu Nov 21 12:55:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 12:55:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211211854.MAA29858@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.34 -> 1.35 --- Log message: Remove implicit information from instruction selector --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.34 llvm/lib/Target/X86/InstSelectSimple.cpp:1.35 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.34 Thu Nov 21 11:26:58 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Nov 21 12:54:29 2002 @@ -398,12 +398,10 @@ visitInstruction(I); static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX }; - static const unsigned Clobbers[] ={ X86::AH , X86::DX , X86::EDX }; static const unsigned MulOpcode[]={ X86::MULrr8, X86::MULrr16, X86::MULrr32 }; static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 }; unsigned Reg = Regs[Class]; - unsigned Clobber = Clobbers[Class]; unsigned Op0Reg = getReg(I.getOperand(0)); unsigned Op1Reg = getReg(I.getOperand(1)); @@ -411,8 +409,7 @@ BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg); // Emit the appropriate multiply instruction... - BuildMI(BB, MulOpcode[Class], 3) - .addReg(Reg, UseAndDef).addReg(Op1Reg).addClobber(Clobber); + BuildMI(BB, MulOpcode[Class], 1).addReg(Op1Reg); // Put the result into the destination register... BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(Reg); @@ -458,8 +455,7 @@ } // Emit the appropriate divide or remainder instruction... - BuildMI(BB, DivOpcode[isSigned][Class], 2) - .addReg(Reg, UseAndDef).addReg(ExtReg, UseAndDef).addReg(Op1Reg); + BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg); // Figure out which register we want to pick the result out of... unsigned DestReg = (I.getOpcode() == Instruction::Div) ? Reg : ExtReg; From lattner at cs.uiuc.edu Thu Nov 21 12:55:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 12:55:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200211211854.MAA29863@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def updated: 1.25 -> 1.26 --- Log message: Add printing information for MUL and DIV --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.25 llvm/lib/Target/X86/X86InstrInfo.def:1.26 --- llvm/lib/Target/X86/X86InstrInfo.def:1.25 Thu Nov 21 11:12:55 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Thu Nov 21 12:54:14 2002 @@ -36,9 +36,9 @@ // Flow control instructions I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void) // ret -I(JMP , "jmp", 0x00, M_BRANCH_FLAG, X86II::Void) // jmp foo EB|E9 cb|w -I(JNE , "jne", 0x00, M_BRANCH_FLAG, X86II::Void) // 75 cb, or 0f 85 cw|cd -I(JE , "je", 0x00, M_BRANCH_FLAG, X86II::Void) // 74 cb, or 0f 84 cw|cd +I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::Void) // jmp foo +I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::TB | X86II::Void) +I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::TB | X86II::Void) // Misc instructions I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm) // leave @@ -65,19 +65,22 @@ I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg) // R8 -= R8 I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize) // R16 -= R16 I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg) // R32 -= R32 -I(MULrr8 , "mulb", 0xF6, 0, X86II::Void) // AX = AL*R8 F6/4 -I(MULrr16 , "mulw", 0xF7, 0, X86II::Void | X86II::OpSize) // DX:AX= AX*R16 F7/4 -I(MULrr32 , "mull", 0xF7, 0, X86II::Void) // ED:EA= EA*R32 F7/4 +I(MULrr8 , "mulb", 0xF6, 0, X86II::MRMS4r | X86II::Void) // AX = AL*R8 +I(MULrr16 , "mulw", 0xF7, 0, X86II::MRMS4r | X86II::Void | // DX:AX= AX*R16 + X86II::OpSize) +I(MULrr32 , "mull", 0xF7, 0, X86II::MRMS4r | X86II::Void) // ED:EA= EA*R32 // unsigned division/remainder -I(DIVrr8 , "divb", 0xF6, 0, X86II::Void) // AX/r8= AL&AH F6/6 -I(DIVrr16 , "divw", 0xF7, 0, X86II::Void | X86II::OpSize) // DA/r16=AX&DX F7/6 -I(DIVrr32 , "divl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6 +I(DIVrr8 , "divb", 0xF6, 0, X86II::MRMS6r | X86II::Void) // AX/r8= AL&AH +I(DIVrr16 , "divw", 0xF7, 0, X86II::MRMS6r | X86II::Void | // DA/r16=AX&DX + X86II::OpSize) +I(DIVrr32 , "divl", 0xF7, 0, X86II::MRMS6r | X86II::Void) // DA/r32=EAX&DX // signed division/remainder -I(IDIVrr8 , "idivb", 0xF6, 0, X86II::Void) // AX/r8= AL&AH F6/6 -I(IDIVrr16 , "idivw", 0xF7, 0, X86II::Void | X86II::OpSize) // DA/r16=AX&DX F7/6 -I(IDIVrr32 , "idivl", 0xF7, 0, X86II::Void) // DA/r32=EAX&DX F7/6 +I(IDIVrr8 , "idivb", 0xF6, 0, X86II::MRMS7r | X86II::Void) // AX/r8= AL&AH +I(IDIVrr16 , "idivw", 0xF7, 0, X86II::MRMS7r | X86II::Void | // DA/r16=AX&DX + X86II::OpSize) +I(IDIVrr32 , "idivl", 0xF7, 0, X86II::MRMS7r | X86II::Void) // DA/r32=EAX&DX // Logical operators I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg) // R8 &= R8 From lattner at cs.uiuc.edu Thu Nov 21 14:45:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 14:45:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211212044.OAA30360@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.12 -> 1.13 --- Log message: The big change here is to handle printing/emission of X86II::MRMSrcMem instructions. Right now the only users are load instructions, and Misha's spill code --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.12 llvm/lib/Target/X86/Printer.cpp:1.13 --- llvm/lib/Target/X86/Printer.cpp:1.12 Thu Nov 21 11:09:01 2002 +++ llvm/lib/Target/X86/Printer.cpp Thu Nov 21 14:44:15 2002 @@ -68,6 +68,28 @@ return false; } +static bool isReg(const MachineOperand &MO) { + return MO.getType() == MachineOperand::MO_VirtualRegister || + MO.getType() == MachineOperand::MO_MachineRegister; +} + +static bool isImmediate(const MachineOperand &MO) { + return MO.getType() == MachineOperand::MO_SignExtendedImmed || + MO.getType() == MachineOperand::MO_UnextendedImmed; +} + +static bool isScale(const MachineOperand &MO) { + return isImmediate(MO) && + (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || + MO.getImmedValue() == 4 || MO.getImmedValue() == 8); +} + +static bool isMem(const MachineInstr *MI, unsigned Op) { + return Op+4 <= MI->getNumOperands() && + isReg(MI->getOperand(Op )) && isScale(MI->getOperand(Op+1)) && + isReg(MI->getOperand(Op+2)) && isImmediate(MI->getOperand(Op+3)); +} + static void printOp(std::ostream &O, const MachineOperand &MO, const MRegisterInfo &RI) { switch (MO.getType()) { @@ -88,6 +110,36 @@ } } +static void printMemReference(std::ostream &O, const MachineInstr *MI, + unsigned Op, const MRegisterInfo &RI) { + assert(isMem(MI, Op) && "Invalid memory reference!"); + const MachineOperand &BaseReg = MI->getOperand(Op); + const MachineOperand &Scale = MI->getOperand(Op+1); + const MachineOperand &IndexReg = MI->getOperand(Op+2); + const MachineOperand &Disp = MI->getOperand(Op+3); + + O << "["; + bool NeedPlus = false; + if (BaseReg.getReg()) { + printOp(O, BaseReg, RI); + NeedPlus = true; + } + + if (IndexReg.getReg()) { + if (NeedPlus) O << " + "; + if (IndexReg.getImmedValue() != 1) + O << IndexReg.getImmedValue() << "*"; + printOp(O, IndexReg, RI); + NeedPlus = true; + } + + if (Disp.getImmedValue()) { + if (NeedPlus) O << " + "; + printOp(O, Disp, RI); + } + O << "]"; +} + static inline void toHexDigit(std::ostream &O, unsigned char V) { if (V >= 10) O << (char)('A'+V-10); @@ -110,15 +162,10 @@ return O; } - -static bool isReg(const MachineOperand &MO) { - return MO.getType() == MachineOperand::MO_VirtualRegister || - MO.getType() == MachineOperand::MO_MachineRegister; -} - -static bool isImmediate(const MachineOperand &MO) { - return MO.getType() == MachineOperand::MO_SignExtendedImmed || - MO.getType() == MachineOperand::MO_UnextendedImmed; +namespace N86 { // Native X86 Register numbers... + enum { + EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7 + }; } @@ -127,14 +174,14 @@ // static unsigned getX86RegNum(unsigned RegNo) { switch(RegNo) { - case X86::EAX: case X86::AX: case X86::AL: return 0; - case X86::ECX: case X86::CX: case X86::CL: return 1; - case X86::EDX: case X86::DX: case X86::DL: return 2; - case X86::EBX: case X86::BX: case X86::BL: return 3; - case X86::ESP: case X86::SP: case X86::AH: return 4; - case X86::EBP: case X86::BP: case X86::CH: return 5; - case X86::ESI: case X86::SI: case X86::DH: return 6; - case X86::EDI: case X86::DI: case X86::BH: return 7; + case X86::EAX: case X86::AX: case X86::AL: return N86::EAX; + case X86::ECX: case X86::CX: case X86::CL: return N86::ECX; + case X86::EDX: case X86::DX: case X86::DL: return N86::EDX; + case X86::EBX: case X86::BX: case X86::BL: return N86::EBX; + case X86::ESP: case X86::SP: case X86::AH: return N86::ESP; + case X86::EBP: case X86::BP: case X86::CH: return N86::EBP; + case X86::ESI: case X86::SI: case X86::DH: return N86::ESI; + case X86::EDI: case X86::DI: case X86::BH: return N86::EDI; default: assert(RegNo >= MRegisterInfo::FirstVirtualRegister && "Unknown physical register!"); @@ -150,8 +197,94 @@ return RM | (RegOpcode << 3) | (Mod << 6); } -static unsigned char regModRMByte(unsigned ModRMReg, unsigned RegOpcodeField) { - return ModRMByte(3, RegOpcodeField, getX86RegNum(ModRMReg)); +static void emitRegModRMByte(std::ostream &O, unsigned ModRMReg, + unsigned RegOpcodeField) { + toHex(O, ModRMByte(3, RegOpcodeField, getX86RegNum(ModRMReg))); +} + +inline static void emitSIBByte(std::ostream &O, unsigned SS, unsigned Index, + unsigned Base) { + // SIB byte is in the same format as the ModRMByte... + toHex(O, ModRMByte(SS, Index, Base)); +} + +static bool isDisp8(int Value) { + return Value == (signed char)Value; +} + +static void emitMemModRMByte(std::ostream &O, const MachineInstr *MI, + unsigned Op, unsigned RegOpcodeField) { + assert(isMem(MI, Op) && "Invalid memory reference!"); + const MachineOperand &BaseReg = MI->getOperand(Op); + const MachineOperand &Scale = MI->getOperand(Op+1); + const MachineOperand &IndexReg = MI->getOperand(Op+2); + const MachineOperand &Disp = MI->getOperand(Op+3); + + // Is a SIB byte needed? + if (IndexReg.getReg() == 0 && BaseReg.getReg() != X86::ESP) { + if (BaseReg.getReg() == 0) { // Just a displacement? + // Emit special case [disp32] encoding + toHex(O, ModRMByte(0, RegOpcodeField, 5)); + emitConstant(O, Disp.getImmedValue(), 4); + } else { + unsigned BaseRegNo = getX86RegNum(BaseReg.getReg()); + if (Disp.getImmedValue() == 0 && BaseRegNo != N86::EBP) { + // Emit simple indirect register encoding... [EAX] f.e. + toHex(O, ModRMByte(0, RegOpcodeField, BaseRegNo)); + } else if (isDisp8(Disp.getImmedValue())) { + // Emit the disp8 encoding... [REG+disp8] + toHex(O, ModRMByte(1, RegOpcodeField, BaseRegNo)); + emitConstant(O, Disp.getImmedValue(), 1); + } else { + // Emit the most general non-SIB encoding: [REG+disp32] + toHex(O, ModRMByte(1, RegOpcodeField, BaseRegNo)); + emitConstant(O, Disp.getImmedValue(), 4); + } + } + + } else { // We need a SIB byte, so start by outputting the ModR/M byte first + assert(IndexReg.getReg() != X86::ESP && "Cannot use ESP as index reg!"); + + bool ForceDisp32 = false; + if (BaseReg.getReg() == 0) { + // If there is no base register, we emit the special case SIB byte with + // MOD=0, BASE=5, to JUST get the index, scale, and displacement. + toHex(O, ModRMByte(0, RegOpcodeField, 4)); + ForceDisp32 = true; + } else if (Disp.getImmedValue() == 0) { + // Emit no displacement ModR/M byte + toHex(O, ModRMByte(0, RegOpcodeField, 4)); + } else if (isDisp8(Disp.getImmedValue())) { + // Emit the disp8 encoding... + toHex(O, ModRMByte(1, RegOpcodeField, 4)); + } else { + // Emit the normal disp32 encoding... + toHex(O, ModRMByte(2, RegOpcodeField, 4)); + } + + // Calculate what the SS field value should be... + static const unsigned SSTable[] = { ~0, 0, 1, ~0, 2, ~0, ~0, ~0, 3 }; + unsigned SS = SSTable[Scale.getImmedValue()]; + + if (BaseReg.getReg() == 0) { + // Handle the SIB byte for the case where there is no base. The + // displacement has already been output. + assert(IndexReg.getReg() && "Index register must be specified!"); + emitSIBByte(O, SS, getX86RegNum(IndexReg.getReg()), 5); + } else { + unsigned BaseRegNo = getX86RegNum(BaseReg.getReg()); + unsigned IndexRegNo = getX86RegNum(IndexReg.getReg()); + emitSIBByte(O, SS, IndexRegNo, BaseRegNo); + } + + // Do we need to output a displacement? + if (Disp.getImmedValue() != 0 || ForceDisp32) { + if (!ForceDisp32 && isDisp8(Disp.getImmedValue())) + emitConstant(O, Disp.getImmedValue(), 1); + else + emitConstant(O, Disp.getImmedValue(), 4); + } + } } @@ -236,7 +369,7 @@ toHex(O, getBaseOpcodeFor(Opcode)) << " "; unsigned ModRMReg = MI->getOperand(0).getReg(); unsigned ExtraReg = MI->getOperand(MI->getNumOperands()-1).getReg(); - toHex(O, regModRMByte(ModRMReg, getX86RegNum(ExtraReg))); + emitRegModRMByte(O, ModRMReg, getX86RegNum(ExtraReg)); O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; @@ -268,7 +401,7 @@ toHex(O, getBaseOpcodeFor(Opcode)) << " "; unsigned ModRMReg = MI->getOperand(MI->getNumOperands()-1).getReg(); unsigned ExtraReg = MI->getOperand(0).getReg(); - toHex(O, regModRMByte(ModRMReg, getX86RegNum(ExtraReg))); + emitRegModRMByte(O, ModRMReg, getX86RegNum(ExtraReg)); O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; @@ -279,6 +412,35 @@ return; } + case X86II::MRMSrcMem: { + // These instructions are the same as MRMSrcReg, but instead of having a + // register reference for the mod/rm field, it's a memory reference. + + //I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem) + // R8 = [mem] 8A/r + + assert(isReg(MI->getOperand(0)) && + (MI->getNumOperands() == 1+4 && isMem(MI, 1)) || + (MI->getNumOperands() == 2+4 && isReg(MI->getOperand(1)) && + isMem(MI, 2)) + && "Bad format for MRMDestReg!"); + if (MI->getNumOperands() == 2+4 && + MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) + O << "**"; + + toHex(O, getBaseOpcodeFor(Opcode)) << " "; + unsigned ExtraReg = MI->getOperand(0).getReg(); + emitMemModRMByte(O, MI, MI->getNumOperands()-4, getX86RegNum(ExtraReg)); + + O << "\n\t\t\t\t"; + O << getName(MI->getOpCode()) << " "; + printOp(O, MI->getOperand(0), RI); + O << ", PTR "; + printMemReference(O, MI, MI->getNumOperands()-4, RI); + O << "\n"; + return; + } + case X86II::MRMS0r: case X86II::MRMS1r: case X86II::MRMS2r: case X86II::MRMS3r: case X86II::MRMS4r: case X86II::MRMS5r: @@ -302,7 +464,7 @@ O << "**"; toHex(O, getBaseOpcodeFor(Opcode)) << " "; - toHex(O, regModRMByte(MI->getOperand(0).getReg(), ExtraField)); + emitRegModRMByte(O, MI->getOperand(0).getReg(), ExtraField); if (MI->getNumOperands() == 3) { unsigned Size = 4; @@ -322,7 +484,6 @@ } case X86II::MRMDestMem: - case X86II::MRMSrcMem: default: O << "\t\t\t-"; MI->print(O, TM); break; } From lattner at cs.uiuc.edu Thu Nov 21 15:04:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 15:04:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211212103.PAA30535@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.13 -> 1.14 --- Log message: Implement printing of store instructions --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.13 llvm/lib/Target/X86/Printer.cpp:1.14 --- llvm/lib/Target/X86/Printer.cpp:1.13 Thu Nov 21 14:44:15 2002 +++ llvm/lib/Target/X86/Printer.cpp Thu Nov 21 15:03:39 2002 @@ -379,6 +379,25 @@ O << "\n"; return; } + + case X86II::MRMDestMem: { + // These instructions are the same as MRMDestReg, but instead of having a + // register reference for the mod/rm field, it's a memory reference. + // + assert(isMem(MI, 0) && MI->getNumOperands() == 4+1 && + isReg(MI->getOperand(4)) && "Bad format for MRMDestMem!"); + toHex(O, getBaseOpcodeFor(Opcode)) << " "; + emitMemModRMByte(O, MI, 0, getX86RegNum(MI->getOperand(4).getReg())); + + O << "\n\t\t\t\t"; + O << getName(MI->getOpCode()) << " PTR "; + printMemReference(O, MI, 0, RI); + O << ", "; + printOp(O, MI->getOperand(4), RI); + O << "\n"; + return; + } + case X86II::MRMSrcReg: { // There is a two forms that are acceptable for MRMSrcReg instructions, // those with 3 and 2 operands: @@ -415,10 +434,7 @@ case X86II::MRMSrcMem: { // These instructions are the same as MRMSrcReg, but instead of having a // register reference for the mod/rm field, it's a memory reference. - - //I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem) - // R8 = [mem] 8A/r - + // assert(isReg(MI->getOperand(0)) && (MI->getNumOperands() == 1+4 && isMem(MI, 1)) || (MI->getNumOperands() == 2+4 && isReg(MI->getOperand(1)) && @@ -483,7 +499,6 @@ return; } - case X86II::MRMDestMem: default: O << "\t\t\t-"; MI->print(O, TM); break; } From lattner at cs.uiuc.edu Thu Nov 21 15:05:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 15:05:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211212105.PAA30547@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.14 -> 1.15 --- Log message: Minor code cleanups --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.14 llvm/lib/Target/X86/Printer.cpp:1.15 --- llvm/lib/Target/X86/Printer.cpp:1.14 Thu Nov 21 15:03:39 2002 +++ llvm/lib/Target/X86/Printer.cpp Thu Nov 21 15:04:50 2002 @@ -295,7 +295,6 @@ const MachineInstrDescriptor &Desc = get(Opcode); // Print instruction prefixes if neccesary - if (Desc.TSFlags & X86II::OpSize) O << "66 "; // Operand size... if (Desc.TSFlags & X86II::TB) O << "0F "; // Two-byte opcode prefix @@ -304,6 +303,7 @@ O << "\t\t\t"; O << "-"; MI->print(O, TM); break; + case X86II::RawFrm: toHex(O, getBaseOpcodeFor(Opcode)); O << "\n\t\t\t\t"; @@ -315,7 +315,6 @@ } O << "\n"; return; - case X86II::AddRegFrm: { // There are currently two forms of acceptable AddRegFrm instructions. From lattner at cs.uiuc.edu Thu Nov 21 16:49:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 16:49:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211212248.QAA31497@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.15 -> 1.16 --- Log message: Fix off by one bug --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.15 llvm/lib/Target/X86/Printer.cpp:1.16 --- llvm/lib/Target/X86/Printer.cpp:1.15 Thu Nov 21 15:04:50 2002 +++ llvm/lib/Target/X86/Printer.cpp Thu Nov 21 16:48:15 2002 @@ -483,7 +483,7 @@ if (MI->getNumOperands() == 3) { unsigned Size = 4; - emitConstant(O, MI->getOperand(1).getImmedValue(), Size); + emitConstant(O, MI->getOperand(2).getImmedValue(), Size); } O << "\n\t\t\t\t"; From lattner at cs.uiuc.edu Thu Nov 21 16:49:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 16:49:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.h Message-ID: <200211212248.QAA31502@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.h updated: 1.13 -> 1.14 --- Log message: Add fixme --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.13 llvm/lib/Target/X86/X86InstrInfo.h:1.14 --- llvm/lib/Target/X86/X86InstrInfo.h:1.13 Thu Nov 21 11:08:49 2002 +++ llvm/lib/Target/X86/X86InstrInfo.h Thu Nov 21 16:48:01 2002 @@ -77,6 +77,9 @@ // starts with a 0x0F byte before the real opcode. TB = 1 << 6, + // FIXME: There are several more two byte opcode escapes: D8-DF + // Handle this. + // OpSize - Set if this instruction requires an operand size prefix (0x66), // which most often indicates that the instruction operates on 16 bit data // instead of 32 bit data. From lattner at cs.uiuc.edu Thu Nov 21 16:50:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 16:50:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200211212249.QAA31524@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def updated: 1.26 -> 1.27 --- Log message: Printing support for more stuff --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.26 llvm/lib/Target/X86/X86InstrInfo.def:1.27 --- llvm/lib/Target/X86/X86InstrInfo.def:1.26 Thu Nov 21 12:54:14 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Thu Nov 21 16:49:46 2002 @@ -95,27 +95,27 @@ // Shift instructions I(SHLrr8 , "shlb", 0xD2, 0, X86II::MRMS4r) // R8 <<= cl D2/4 -I(SHLrr16 , "shlw", 0xD3, 0, X86II::OpSize) // R16 <<= cl D3/4 -I(SHLrr32 , "shll", 0xD3, 0, 0) // R32 <<= cl D3/4 -I(SHLir8 , "shlb", 0xC0, 0, 0) // R8 <<= imm8 C0/4 ib -I(SHLir16 , "shlw", 0xC1, 0, X86II::OpSize) // R16 <<= imm8 C1/4 ib -I(SHLir32 , "shll", 0xC1, 0, 0) // R32 <<= imm8 C1/4 ib -I(SHRrr8 , "shrb", 0xD2, 0, 0) // R8 >>>= cl D2/5 -I(SHRrr16 , "shrw", 0xD3, 0, X86II::OpSize) // R16 >>>= cl D3/5 -I(SHRrr32 , "shrl", 0xD3, 0, 0) // R32 >>>= cl D3/5 -I(SHRir8 , "shrb", 0xC0, 0, 0) // R8 >>>= imm8 C0/5 ib -I(SHRir16 , "shrw", 0xC1, 0, X86II::OpSize) // R16 >>>= imm8 C1/5 ib -I(SHRir32 , "shrl", 0xC1, 0, 0) // R32 >>>= imm8 C1/5 ib -I(SARrr8 , "sarb", 0xD2, 0, 0) // R8 >>= cl D2/7 -I(SARrr16 , "sarw", 0xD3, 0, X86II::OpSize) // R16 >>= cl D3/7 -I(SARrr32 , "sarl", 0xD3, 0, 0) // R32 >>= cl D3/7 -I(SARir8 , "sarb", 0xC0, 0, 0) // R8 >>= imm8 C0/7 ib -I(SARir16 , "sarw", 0xC1, 0, X86II::OpSize) // R16 >>= imm8 C1/7 ib -I(SARir32 , "sarl", 0xC1, 0, 0) // R32 >>= imm8 C1/7 ib +I(SHLrr16 , "shlw", 0xD3, 0, X86II::MRMS4r | X86II::OpSize) // R16 <<= cl D3/4 +I(SHLrr32 , "shll", 0xD3, 0, X86II::MRMS4r) // R32 <<= cl D3/4 +I(SHLir8 , "shlb", 0xC0, 0, X86II::MRMS4r) // R8 <<= imm8 C0/4 ib +I(SHLir16 , "shlw", 0xC1, 0, X86II::MRMS4r | X86II::OpSize) // R16 <<= imm8 C1/4 ib +I(SHLir32 , "shll", 0xC1, 0, X86II::MRMS4r) // R32 <<= imm8 C1/4 ib +I(SHRrr8 , "shrb", 0xD2, 0, X86II::MRMS5r) // R8 >>>= cl D2/5 +I(SHRrr16 , "shrw", 0xD3, 0, X86II::MRMS5r | X86II::OpSize) // R16 >>>= cl D3/5 +I(SHRrr32 , "shrl", 0xD3, 0, X86II::MRMS5r) // R32 >>>= cl D3/5 +I(SHRir8 , "shrb", 0xC0, 0, X86II::MRMS5r) // R8 >>>= imm8 C0/5 ib +I(SHRir16 , "shrw", 0xC1, 0, X86II::MRMS5r | X86II::OpSize) // R16 >>>= imm8 C1/5 ib +I(SHRir32 , "shrl", 0xC1, 0, X86II::MRMS5r) // R32 >>>= imm8 C1/5 ib +I(SARrr8 , "sarb", 0xD2, 0, X86II::MRMS7r) // R8 >>= cl D2/7 +I(SARrr16 , "sarw", 0xD3, 0, X86II::MRMS7r | X86II::OpSize) // R16 >>= cl D3/7 +I(SARrr32 , "sarl", 0xD3, 0, X86II::MRMS7r) // R32 >>= cl D3/7 +I(SARir8 , "sarb", 0xC0, 0, X86II::MRMS7r) // R8 >>= imm8 C0/7 ib +I(SARir16 , "sarw", 0xC1, 0, X86II::MRMS7r | X86II::OpSize) // R16 >>= imm8 C1/7 ib +I(SARir32 , "sarl", 0xC1, 0, X86II::MRMS7r) // R32 >>= imm8 C1/7 ib // Floating point loads -I(FLDr4 , "flds", 0xD9, 0, X86II::Void) // push float D9/0 -I(FLDr8 , "fldl ", 0xDD, 0, X86II::Void) // push double DD/0 +I(FLDr4 , "flds", 0xD9, 0, X86II::MRMS0m) // push float D9/0 +I(FLDr8 , "fldl ", 0xDD, 0, X86II::MRMS0m) // push double DD/0 // Floating point compares I(FUCOMPP , "fucompp", 0xDA, 0, X86II::Void) // compare+pop2x DA E9 @@ -140,7 +140,7 @@ I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg) // compare R8,R8 I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg | X86II::OpSize) // compare R16,R16 I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg) // compare R32,R32 -I(CMPri8 , "cmp", 0x80, 0, 0) // compare R8, imm8 80 /7 ib +I(CMPri8 , "cmp", 0x80, 0, X86II::MRMS7r) // compare R8, imm8 // Sign extenders (first 3 are good for DIV/IDIV; the others are more general) I(CBW , "cbw", 0x98, 0, X86II::RawFrm) // AX = signext(AL) From lattner at cs.uiuc.edu Thu Nov 21 16:50:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 16:50:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211212250.QAA31529@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.35 -> 1.36 --- Log message: Don't add implicit operands --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.35 llvm/lib/Target/X86/InstSelectSimple.cpp:1.36 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.35 Thu Nov 21 12:54:29 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Nov 21 16:49:20 2002 @@ -225,12 +225,12 @@ // FIXME: assuming var1, var2 are in memory, if not, spill to // stack first case cFloat: // Floats - BuildMI (BB, X86::FLDr4, 1, X86::NoReg).addReg (reg1); - BuildMI (BB, X86::FLDr4, 1, X86::NoReg).addReg (reg2); + BuildMI (BB, X86::FLDr4, 1).addReg (reg1); + BuildMI (BB, X86::FLDr4, 1).addReg (reg2); break; case cDouble: // Doubles - BuildMI (BB, X86::FLDr8, 1, X86::NoReg).addReg (reg1); - BuildMI (BB, X86::FLDr8, 1, X86::NoReg).addReg (reg2); + BuildMI (BB, X86::FLDr8, 1).addReg (reg1); + BuildMI (BB, X86::FLDr8, 1).addReg (reg2); break; case cLong: default: @@ -522,7 +522,7 @@ const unsigned *OpTab = // Figure out the operand table to use NonConstantOperand[isLeftShift*2+isOperandSigned]; - BuildMI(BB, OpTab[OperandClass], 2, DestReg).addReg(Op0r).addReg(X86::CL); + BuildMI(BB, OpTab[OperandClass], 1, DestReg).addReg(Op0r); } } From lattner at cs.uiuc.edu Thu Nov 21 17:31:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 17:31:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200211212330.RAA31766@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.16 -> 1.17 --- Log message: Handle cmp Reg, 0 correctly --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.16 llvm/lib/Target/X86/Printer.cpp:1.17 --- llvm/lib/Target/X86/Printer.cpp:1.16 Thu Nov 21 16:48:15 2002 +++ llvm/lib/Target/X86/Printer.cpp Thu Nov 21 17:30:00 2002 @@ -199,7 +199,7 @@ static void emitRegModRMByte(std::ostream &O, unsigned ModRMReg, unsigned RegOpcodeField) { - toHex(O, ModRMByte(3, RegOpcodeField, getX86RegNum(ModRMReg))); + toHex(O, ModRMByte(3, RegOpcodeField, getX86RegNum(ModRMReg))) << " "; } inline static void emitSIBByte(std::ostream &O, unsigned SS, unsigned Index, @@ -460,38 +460,41 @@ case X86II::MRMS2r: case X86II::MRMS3r: case X86II::MRMS4r: case X86II::MRMS5r: case X86II::MRMS6r: case X86II::MRMS7r: { - unsigned ExtraField = (Desc.TSFlags & X86II::FormMask)-X86II::MRMS0r; - // In this form, the following are valid formats: // 1. sete r + // 2. cmp reg, immediate // 2. shl rdest, rinput // 3. sbb rdest, rinput, immediate [rdest = rinput] // assert(MI->getNumOperands() > 0 && MI->getNumOperands() < 4 && isReg(MI->getOperand(0)) && "Bad MRMSxR format!"); - assert((MI->getNumOperands() < 2 || isReg(MI->getOperand(1))) && + assert((MI->getNumOperands() != 2 || + isReg(MI->getOperand(1)) || isImmediate(MI->getOperand(1))) && "Bad MRMSxR format!"); - assert((MI->getNumOperands() < 3 || isImmediate(MI->getOperand(2))) && + assert((MI->getNumOperands() < 3 || + (isReg(MI->getOperand(1)) && isImmediate(MI->getOperand(2)))) && "Bad MRMSxR format!"); - if (MI->getNumOperands() > 1 && + if (MI->getNumOperands() > 1 && isReg(MI->getOperand(1)) && MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) O << "**"; toHex(O, getBaseOpcodeFor(Opcode)) << " "; + unsigned ExtraField = (Desc.TSFlags & X86II::FormMask)-X86II::MRMS0r; emitRegModRMByte(O, MI->getOperand(0).getReg(), ExtraField); - if (MI->getNumOperands() == 3) { + if (isImmediate(MI->getOperand(MI->getNumOperands()-1))) { unsigned Size = 4; - emitConstant(O, MI->getOperand(2).getImmedValue(), Size); + emitConstant(O, MI->getOperand(MI->getNumOperands()-1).getImmedValue(), + Size); } O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; printOp(O, MI->getOperand(0), RI); - if (MI->getNumOperands() == 3) { + if (isImmediate(MI->getOperand(MI->getNumOperands()-1))) { O << ", "; - printOp(O, MI->getOperand(2), RI); + printOp(O, MI->getOperand(MI->getNumOperands()-1), RI); } O << "\n"; From lattner at cs.uiuc.edu Thu Nov 21 17:31:08 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Nov 21 17:31:08 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/test-branch.ll Message-ID: <200211212330.RAA31811@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: test-branch.ll updated: 1.1 -> 1.2 --- Log message: Make testcase more interesting --- Diffs of the changes: Index: llvm/test/Regression/Jello/test-branch.ll diff -u llvm/test/Regression/Jello/test-branch.ll:1.1 llvm/test/Regression/Jello/test-branch.ll:1.2 --- llvm/test/Regression/Jello/test-branch.ll:1.1 Thu Nov 21 11:20:32 2002 +++ llvm/test/Regression/Jello/test-branch.ll Thu Nov 21 17:30:08 2002 @@ -2,5 +2,8 @@ void %main() { br label %Test Test: + %X = seteq int 0, 4 + br bool %X, label %Test, label %Label +Label: ret void } From lattner at cs.uiuc.edu Fri Nov 22 05:08:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Nov 22 05:08:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200211221107.FAA13704@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.36 -> 1.37 --- Log message: lib/Target/X86/InstSelectSimple.cpp: Add visitCallInst, visitCastInst. --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.36 llvm/lib/Target/X86/InstSelectSimple.cpp:1.37 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.36 Thu Nov 21 16:49:20 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Fri Nov 22 05:07:01 2002 @@ -63,8 +63,11 @@ // Visitation methods for various instructions. These methods simply emit // fixed X86 code for each instruction. // + + // Control flow operators void visitReturnInst(ReturnInst &RI); void visitBranchInst(BranchInst &BI); + void visitCallInst(CallInst &I); // Arithmetic operators void visitSimpleBinary(BinaryOperator &B, unsigned OpcodeClass); @@ -97,6 +100,7 @@ // Other operators void visitShiftInst(ShiftInst &I); void visitPHINode(PHINode &I); + void visitCastInst(CastInst &I); void visitInstruction(Instruction &I) { std::cerr << "Cannot instruction select: " << I; @@ -359,6 +363,11 @@ } } +void +ISel::visitCallInst (CallInst &CI) +{ + visitInstruction (CI); +} /// visitSimpleBinary - Implement simple binary operators for integral types... /// OperatorClass is one of: 0 for Add, 1 for Sub, 2 for And, 3 for Or, @@ -572,6 +581,11 @@ } } +void +ISel::visitCastInst (CastInst &CI) +{ + visitInstruction (CI); +} /// createSimpleX86InstructionSelector - This pass converts an LLVM function /// into a machine code representation is a very simple peep-hole fashion. The From lattner at cs.uiuc.edu Fri Nov 22 13:10:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Nov 22 13:10:01 2002 Subject: [llvm-commits] CVS: llvm/www/www-index.html Message-ID: <200211221909.NAA08636@tank.cs.uiuc.edu> Changes in directory llvm/www: www-index.html updated: 1.9 -> 1.10 --- Log message: Fix typeo --- Diffs of the changes: Index: llvm/www/www-index.html diff -u llvm/www/www-index.html:1.9 llvm/www/www-index.html:1.10 --- llvm/www/www-index.html:1.9 Mon Oct 28 18:47:36 2002 +++ llvm/www/www-index.html Fri Nov 22 13:09:35 2002 @@ -118,7 +118,7 @@ href="pubs/LLVMCompilationStrategy.pdf">The LLVM Instruction Set and Compilation Strategy"
    - Chris Lattner & Vikram Adve, Techincal + Chris Lattner & Vikram Adve, Technical Report #UIUCDCS-R-2002-2292, Computer Science Dept., Univ. of Illinois, Aug. 2002.
    From brukman at cs.uiuc.edu Fri Nov 22 16:33:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 16:33:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineFunction.h Message-ID: <200211222232.QAA11599@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineFunction.h updated: 1.20 -> 1.21 --- Log message: Set SSARegMap to NULL after deleting it. --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineFunction.h diff -u llvm/include/llvm/CodeGen/MachineFunction.h:1.20 llvm/include/llvm/CodeGen/MachineFunction.h:1.21 --- llvm/include/llvm/CodeGen/MachineFunction.h:1.20 Tue Nov 19 18:53:10 2002 +++ llvm/include/llvm/CodeGen/MachineFunction.h Fri Nov 22 16:32:15 2002 @@ -97,7 +97,10 @@ void addRegMap(unsigned Reg, const TargetRegisterClass *RegClass) { SSARegMapping->addRegMap(Reg, RegClass); } - void clearSSARegMap() { delete SSARegMapping; } + void clearSSARegMap() { + delete SSARegMapping; + SSARegMapping = NULL; + } // Provide accessors for the MachineBasicBlock list... typedef iplist BasicBlockListType; From brukman at cs.uiuc.edu Fri Nov 22 16:42:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 16:42:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200211222241.QAA11922@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.89 -> 1.90 --- Log message: Instead of checking op.getType() against MO_VirtualRegister and MO_MachineRegister, we no longer distinguish Virtual vs. Machine registers externally, they're ALL registers, all equal. Registers are only differentiated whether they are >= MRegisterInfo::FirstVirtual or not. --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.89 llvm/include/llvm/CodeGen/MachineInstr.h:1.90 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.89 Mon Nov 18 00:57:05 2002 +++ llvm/include/llvm/CodeGen/MachineInstr.h Fri Nov 22 16:40:52 2002 @@ -10,6 +10,7 @@ #define LLVM_CODEGEN_MACHINEINSTR_H #include "llvm/Annotation.h" +#include "llvm/Target/MRegisterInfo.h" #include "Support/iterator" #include "Support/NonCopyable.h" #include @@ -151,6 +152,19 @@ // operand type before invoking the corresponding accessor. // MachineOperandType getType() const { return opType; } + + + // This is to finally stop caring whether we have a virtual or machine + // register -- an easier interface is to simply call both virtual and machine + // registers essentially the same, yet be able to distinguish when + // necessary. Thus the instruction selector can just add registers without + // abandon, and the register allocator won't be confused. + bool isVirtualRegister() const { + return (opType == MO_VirtualRegister || opType == MO_MachineRegister) + && regNum >= MRegisterInfo::FirstVirtualRegister; + } + + bool isMachineRegister() const { return !isVirtualRegister(); } inline Value* getVRegValue () const { assert(opType == MO_VirtualRegister || opType == MO_CCRegister || From brukman at cs.uiuc.edu Fri Nov 22 16:42:05 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 16:42:05 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200211222241.QAA11953@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.2 -> 1.3 --- Log message: Added virtual functions for storing and retrieving values from the stack. --- Diffs of the changes: Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.2 llvm/include/llvm/Target/MRegisterInfo.h:1.3 --- llvm/include/llvm/Target/MRegisterInfo.h:1.2 Wed Nov 20 12:54:53 2002 +++ llvm/include/llvm/Target/MRegisterInfo.h Fri Nov 22 16:41:23 2002 @@ -107,15 +107,20 @@ const MRegisterDesc &get(unsigned RegNo) const { return operator[](RegNo); } - virtual void copyReg2PCRel(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, - unsigned SrcReg, unsigned ImmOffset, - unsigned dataSize) const = 0; + virtual MachineBasicBlock::iterator + storeReg2RegOffset(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned SrcReg, unsigned DestReg, + unsigned ImmOffset, unsigned dataSize) const = 0; - virtual void copyPCRel2Reg(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, - unsigned ImmOffset, unsigned DestReg, - unsigned dataSize) const = 0; + virtual MachineBasicBlock::iterator + loadRegOffset2Reg(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned DestReg, unsigned SrcReg, + unsigned ImmOffset, unsigned dataSize) const = 0; + + virtual unsigned getFramePointer() const = 0; + virtual unsigned getStackPointer() const = 0; /// Register class iterators typedef const TargetRegisterClass* const_iterator; From brukman at cs.uiuc.edu Fri Nov 22 16:43:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 16:43:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrBuilder.h Message-ID: <200211222242.QAA12011@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrBuilder.h updated: 1.1 -> 1.2 --- Log message: Add a simple way to add memory locations of format [reg+offset] --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrBuilder.h diff -u llvm/lib/Target/X86/X86InstrBuilder.h:1.1 llvm/lib/Target/X86/X86InstrBuilder.h:1.2 --- llvm/lib/Target/X86/X86InstrBuilder.h:1.1 Sun Nov 17 15:03:35 2002 +++ llvm/lib/Target/X86/X86InstrBuilder.h Fri Nov 22 16:42:12 2002 @@ -25,4 +25,13 @@ return MIB.addReg(Reg).addZImm(1).addMReg(0).addSImm(0); } + +/// addRegOffset - +/// +/// +inline const MachineInstrBuilder &addRegOffset(const MachineInstrBuilder &MIB, + unsigned Reg, unsigned Offset) { + return MIB.addReg(Reg).addZImm(1).addMReg(0).addSImm(Offset); +} + #endif From brukman at cs.uiuc.edu Fri Nov 22 16:43:05 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 16:43:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200211222243.QAA12024@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.8 -> 1.9 --- Log message: Added -*- C++ -*- mode to the comments. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.8 llvm/lib/Target/X86/X86InstrInfo.cpp:1.9 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.8 Mon Nov 18 00:56:24 2002 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Fri Nov 22 16:42:50 2002 @@ -1,4 +1,4 @@ -//===- X86InstrInfo.cpp - X86 Instruction Information ---------------===// +//===- X86InstrInfo.cpp - X86 Instruction Information -----------*- C++ -*-===// // // This file contains the X86 implementation of the MachineInstrInfo class. // From brukman at cs.uiuc.edu Fri Nov 22 16:44:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 16:44:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.h X86RegisterInfo.cpp Message-ID: <200211222243.QAA12041@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.h updated: 1.2 -> 1.3 X86RegisterInfo.cpp updated: 1.2 -> 1.3 --- Log message: Added methods to read/write values to stack in .h, fixed implementation in .cpp to return the iterator correctly. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.2 llvm/lib/Target/X86/X86RegisterInfo.h:1.3 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.2 Wed Nov 20 12:59:43 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.h Fri Nov 22 16:43:47 2002 @@ -17,15 +17,20 @@ MRegisterInfo::const_iterator const_regclass_begin() const; MRegisterInfo::const_iterator const_regclass_end() const; - void copyReg2PCRel(MachineBasicBlock *MBB, + MachineBasicBlock::iterator + storeReg2RegOffset(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI, - unsigned SrcReg, unsigned ImmOffset, - unsigned dataSize) const; + unsigned DestReg, unsigned SrcReg, + unsigned ImmOffset, unsigned dataSize) const; - void copyPCRel2Reg(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, - unsigned ImmOffset, unsigned DestReg, - unsigned dataSize) const; + MachineBasicBlock::iterator + loadRegOffset2Reg(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned DestReg, unsigned SrcReg, + unsigned ImmOffset, unsigned dataSize) const; + + unsigned getFramePointer() const; + unsigned getStackPointer() const; /// Returns register class appropriate for input SSA register /// Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.2 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.3 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.2 Wed Nov 20 12:59:43 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Fri Nov 22 16:43:47 2002 @@ -1,4 +1,4 @@ -//===- X86RegisterInfo.cpp - X86 Register Information ---------------------===// +//===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===// // // This file contains the X86 implementation of the MRegisterInfo class. // @@ -6,6 +6,7 @@ #include "X86.h" #include "X86RegisterInfo.h" +#include "X86InstrBuilder.h" #include "llvm/Constants.h" #include "llvm/Type.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -23,23 +24,35 @@ } -void X86RegisterInfo::copyReg2PCRel(MachineBasicBlock *MBB, +MachineBasicBlock::iterator +X86RegisterInfo::storeReg2RegOffset(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI, - unsigned SrcReg, unsigned ImmOffset, - unsigned dataSize) const + unsigned SrcReg, unsigned DestReg, + unsigned ImmOffset, unsigned dataSize) + const { - MachineInstrBuilder MI = BuildMI(X86::MOVmr32, 2) - .addPCDisp(ConstantUInt::get(Type::UIntTy, ImmOffset)).addReg(SrcReg); - MBB->insert(MBBI, &*MI); + MachineInstr *MI = addRegOffset(BuildMI(X86::MOVmr32, 5).addReg(SrcReg), + DestReg, ImmOffset); + return ++(MBB->insert(MBBI, MI)); } -void X86RegisterInfo::copyPCRel2Reg(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, - unsigned ImmOffset, unsigned DestReg, - unsigned dataSize) const +MachineBasicBlock::iterator +X86RegisterInfo::loadRegOffset2Reg(MachineBasicBlock *MBB, + MachineBasicBlock::iterator &MBBI, + unsigned DestReg, unsigned SrcReg, + unsigned ImmOffset, unsigned dataSize) + const { - MachineInstrBuilder MI = BuildMI(X86::MOVrm32, 2) - .addReg(DestReg).addPCDisp(ConstantUInt::get(Type::UIntTy, ImmOffset)); - MBB->insert(MBBI, &*MI); + MachineInstr *MI = addRegOffset(BuildMI(X86::MOVrm32, 5).addReg(DestReg), + SrcReg, ImmOffset); + return ++(MBB->insert(MBBI, MI)); } + +unsigned X86RegisterInfo::getFramePointer() const { + return X86::EBP; +} + +unsigned X86RegisterInfo::getStackPointer() const { + return X86::ESP; +} From brukman at cs.uiuc.edu Fri Nov 22 16:45:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 16:45:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocSimple.cpp Message-ID: <200211222244.QAA12054@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocSimple.cpp added (r1.1) --- Log message: A simple (spilling) register allocator. --- Diffs of the changes: From brukman at cs.uiuc.edu Fri Nov 22 16:46:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 16:46:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86TargetMachine.cpp Message-ID: <200211222245.QAA12069@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86TargetMachine.cpp updated: 1.2 -> 1.3 --- Log message: Enable the register allocator pass. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.2 llvm/lib/Target/X86/X86TargetMachine.cpp:1.3 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.2 Tue Oct 29 18:47:49 2002 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Fri Nov 22 16:45:07 2002 @@ -36,8 +36,12 @@ PM.add(createMachineFunctionPrinterPass()); // Perform register allocation to convert to a concrete x86 representation - //PM.add(createSimpleX86RegisterAllocator(*this)); + PM.add(createSimpleX86RegisterAllocator(*this)); + // Print the instruction selected machine code... + // PM.add(createMachineFunctionPrinterPass()); + + // Print the register-allocated code PM.add(createX86CodePrinterPass(*this, std::cerr)); //PM.add(createEmitX86CodeToMemory(*this)); From brukman at cs.uiuc.edu Fri Nov 22 17:16:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Nov 22 17:16:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200211222315.RAA12981@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.3 -> 1.4 --- Log message: Oops. Got the MOVrm and MOVmr mixed up. Fixed. We can now print out instructions correctly. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.3 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.4 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.3 Fri Nov 22 16:43:47 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Fri Nov 22 17:15:27 2002 @@ -31,7 +31,7 @@ unsigned ImmOffset, unsigned dataSize) const { - MachineInstr *MI = addRegOffset(BuildMI(X86::MOVmr32, 5).addReg(SrcReg), + MachineInstr *MI = addRegOffset(BuildMI(X86::MOVrm32, 5).addReg(SrcReg), DestReg, ImmOffset); return ++(MBB->insert(MBBI, MI)); } @@ -43,7 +43,7 @@ unsigned ImmOffset, unsigned dataSize) const { - MachineInstr *MI = addRegOffset(BuildMI(X86::MOVrm32, 5).addReg(DestReg), + MachineInstr *MI = addRegOffset(BuildMI(X86::MOVmr32, 5).addReg(DestReg), SrcReg, ImmOffset); return ++(MBB->insert(MBBI, MI)); }