From lattner at cs.uiuc.edu Mon Dec 2 10:14:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 10:14:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Message-ID: <200212021613.KAA30107@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.1 -> 1.2 --- Log message: Add comments --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.1 llvm/utils/TableGen/Record.h:1.2 --- llvm/utils/TableGen/Record.h:1.1 Sun Dec 1 19:23:04 2002 +++ llvm/utils/TableGen/Record.h Mon Dec 2 10:13:23 2002 @@ -48,6 +48,9 @@ return OS; } + +/// BitRecTy - 'bit' - Represent a single bit +/// struct BitRecTy : public RecTy { Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue(BitInit *BI) { return (Init*)BI; } @@ -58,6 +61,9 @@ void print(std::ostream &OS) const { OS << "bit"; } }; + +/// BitsRecTy - 'bits' - Represent a fixed number of bits +/// class BitsRecTy : public RecTy { unsigned Size; public: @@ -74,6 +80,9 @@ void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; } }; + +/// IntRecTy - 'int' - Represent an integer value of no particular size +/// struct IntRecTy : public RecTy { Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue(IntInit *II) { return (Init*)II; } @@ -83,6 +92,8 @@ void print(std::ostream &OS) const { OS << "int"; } }; +/// StringRecTy - 'string' - Represent an string value +/// struct StringRecTy : public RecTy { Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue(StringInit *SI) { return (Init*)SI; } @@ -90,6 +101,9 @@ void print(std::ostream &OS) const { OS << "string"; } }; +/// ListRecTy - 'list' - Represent a list defs, all of which must be +/// derived from the specified class. +/// class ListRecTy : public RecTy { Record *Class; public: @@ -100,6 +114,9 @@ void print(std::ostream &OS) const; }; +/// RecordRecTy - '' - Represent an instance of a class, such as: +/// (R32 X = EAX). +/// class RecordRecTy : public RecTy { Record *Rec; public: @@ -111,6 +128,8 @@ void print(std::ostream &OS) const; }; + + //===----------------------------------------------------------------------===// // Initializer Classes //===----------------------------------------------------------------------===// @@ -134,6 +153,9 @@ I.print(OS); return OS; } + +/// UnsetInit - ? - Represents an uninitialized value +/// struct UnsetInit : public Init { virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); @@ -143,6 +165,9 @@ virtual void print(std::ostream &OS) const { OS << "?"; } }; + +/// BitInit - true/false - Represent a concrete initializer for a bit. +/// class BitInit : public Init { bool Value; public: @@ -158,6 +183,9 @@ virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); } }; +/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value. +/// It contains a vector of bits, whose size is determined by the type. +/// class BitsInit : public Init { std::vector Bits; public: @@ -195,6 +223,9 @@ bool printAsUnset(std::ostream &OS) const; }; + +/// IntInit - 7 - Represent an initalization by a literal integer value. +/// class IntInit : public Init { int Value; public: @@ -211,6 +242,9 @@ virtual void print(std::ostream &OS) const { OS << Value; } }; + +/// StringInit - "foo" - Represent an initialization by a string value. +/// class StringInit : public Init { std::string Value; public: @@ -224,6 +258,8 @@ virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; } }; +/// ListInit - [AL, AH, CL] - Represent a list of defs +/// class ListInit : public Init { std::vector Records; public: @@ -245,6 +281,8 @@ virtual void print(std::ostream &OS) const; }; +/// VarInit - 'Opcode' - Represent a reference to an entire variable object. +/// class VarInit : public Init { std::string VarName; RecTy *Ty; @@ -264,6 +302,9 @@ virtual void print(std::ostream &OS) const { OS << VarName; } }; + +/// VarBitInit - Opcode{0} - Represent access to one bit of a variable +/// class VarBitInit : public Init { VarInit *VI; unsigned Bit; @@ -284,6 +325,9 @@ virtual Init *resolveReferences(Record &R); }; + +/// DefInit - AL - Represent a reference to a 'def' in the description +/// class DefInit : public Init { Record *Def; public: From lattner at cs.uiuc.edu Mon Dec 2 10:14:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 10:14:02 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Makefile Message-ID: <200212021613.KAA30119@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Makefile updated: 1.1 -> 1.2 --- Log message: Split up targets --- Diffs of the changes: Index: llvm/utils/TableGen/Makefile diff -u llvm/utils/TableGen/Makefile:1.1 llvm/utils/TableGen/Makefile:1.2 --- llvm/utils/TableGen/Makefile:1.1 Sun Dec 1 19:23:04 2002 +++ llvm/utils/TableGen/Makefile Mon Dec 2 10:13:42 2002 @@ -8,9 +8,14 @@ -rm -f FileParser.cpp FileParser.h FileLexer.cpp CommandLine.cpp -rm -f FileParser.output -test:: + +dump:: $(TOOLEXENAME_G) < X86.td - # -parse + +parse: + $(TOOLEXENAME_G) < X86.td -parse + +test:: @echo "enum {" @$(TOOLEXENAME_G) < X86.td -class=Register From lattner at cs.uiuc.edu Mon Dec 2 10:32:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 10:32:00 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Makefile Message-ID: <200212021631.KAA30281@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Makefile updated: 1.2 -> 1.3 --- Log message: Add correct dependency --- Diffs of the changes: Index: llvm/utils/TableGen/Makefile diff -u llvm/utils/TableGen/Makefile:1.2 llvm/utils/TableGen/Makefile:1.3 --- llvm/utils/TableGen/Makefile:1.2 Mon Dec 2 10:13:42 2002 +++ llvm/utils/TableGen/Makefile Mon Dec 2 10:31:46 2002 @@ -9,14 +9,13 @@ -rm -f FileParser.output -dump:: +dump:: $(TOOLEXENAME_G) $(TOOLEXENAME_G) < X86.td -parse: +parse: $(TOOLEXENAME_G) $(TOOLEXENAME_G) < X86.td -parse -test:: - +test:: $(TOOLEXENAME_G) @echo "enum {" @$(TOOLEXENAME_G) < X86.td -class=Register @echo From lattner at cs.uiuc.edu Mon Dec 2 10:44:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 10:44:00 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Message-ID: <200212021643.KAA30430@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.2 -> 1.3 --- Log message: Initial support for Field Expressions --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.2 llvm/utils/TableGen/Record.h:1.3 --- llvm/utils/TableGen/Record.h:1.2 Mon Dec 2 10:13:23 2002 +++ llvm/utils/TableGen/Record.h Mon Dec 2 10:42:52 2002 @@ -20,6 +20,7 @@ class VarInit; class VarBitInit; class DefInit; +class FieldInit; class Record; //===----------------------------------------------------------------------===// @@ -38,6 +39,7 @@ virtual Init *convertValue( VarInit *VI) { return 0; } virtual Init *convertValue(VarBitInit *VB) { return 0; } virtual Init *convertValue( DefInit *DI) { return 0; } + virtual Init *convertValue( FieldInit *FI) { return 0; } virtual void print(std::ostream &OS) const = 0; void dump() const; @@ -122,6 +124,8 @@ public: RecordRecTy(Record *R) : Rec(R) {} + Record *getRecord() const { return Rec; } + Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue( DefInit *DI); @@ -146,6 +150,12 @@ return 0; } + /// getFieldType - This method is used to implement the FieldInit class. + /// Implementors of this method should return the type of the named field if + /// they are of record type. + /// + virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; } + virtual Init *resolveReferences(Record &R) { return this; } }; @@ -297,6 +307,8 @@ RecTy *getType() const { return Ty; } virtual Init *convertInitializerBitRange(const std::vector &Bits); + + virtual RecTy *getFieldType(const std::string &FieldName) const; virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const { OS << VarName; } @@ -345,6 +357,28 @@ virtual void print(std::ostream &OS) const; }; + +/// FieldInit - X.Y - Represent a reference to a subfield of a variable +/// +class FieldInit : public Init { + Init *Rec; // Record we are referring to + std::string FieldName; // Field we are accessing + RecTy *Ty; // The type of this expression +public: + FieldInit(Init *R, const std::string &FN) + : Rec(R), FieldName(FN), Ty(R->getFieldType(FN)) { + assert(Ty && "FieldInit with non-record type!"); + } + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + virtual bool isComplete() const { return true; } + virtual void print(std::ostream &OS) const { + Rec->print(OS); OS << "." << FieldName; + } +}; //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Mon Dec 2 10:44:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 10:44:02 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200212021643.KAA30448@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.1 -> 1.2 --- Log message: Add support for field exprs --- Diffs of the changes: Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.1 llvm/utils/TableGen/FileParser.y:1.2 --- llvm/utils/TableGen/FileParser.y:1.1 Sun Dec 1 19:23:04 2002 +++ llvm/utils/TableGen/FileParser.y Mon Dec 2 10:43:43 2002 @@ -258,6 +258,13 @@ } | '[' DefList ']' { $$ = new ListInit(*$2); delete $2; + } | Value '.' ID { + if (!$1->getFieldType(*$3)) { + err() << "Cannot access field '" << *$3 << "' of value '" << *$1 << "!\n"; + abort(); + } + $$ = new FieldInit($1, *$3); + delete $3; }; DefList : /*empty */ { From lattner at cs.uiuc.edu Mon Dec 2 10:45:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 10:45:00 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Message-ID: <200212021644.KAA30453@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.1 -> 1.2 --- Log message: * Move BitsInit::resolveReferences up with the rest of BitsInit code * Initial support for field expressions --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.1 llvm/utils/TableGen/Record.cpp:1.2 --- llvm/utils/TableGen/Record.cpp:1.1 Sun Dec 1 19:23:04 2002 +++ llvm/utils/TableGen/Record.cpp Mon Dec 2 10:43:30 2002 @@ -206,6 +206,26 @@ return false; } +Init *BitsInit::resolveReferences(Record &R) { + bool Changed = false; + BitsInit *New = new BitsInit(getNumBits()); + + for (unsigned i = 0, e = Bits.size(); i != e; ++i) { + Init *B; + New->setBit(i, getBit(i)); + do { + B = New->getBit(i); + New->setBit(i, B->resolveReferences(R)); + Changed |= B != New->getBit(i); + } while (B != New->getBit(i)); + } + + if (Changed) + return New; + delete New; + return this; +} + Init *IntInit::convertInitializerBitRange(const std::vector &Bits) { BitsInit *BI = new BitsInit(Bits.size()); @@ -244,26 +264,12 @@ return BI; } -Init *BitsInit::resolveReferences(Record &R) { - bool Changed = false; - BitsInit *New = new BitsInit(getNumBits()); - - for (unsigned i = 0, e = Bits.size(); i != e; ++i) { - Init *B; - New->setBit(i, getBit(i)); - do { - B = New->getBit(i); - New->setBit(i, B->resolveReferences(R)); - Changed |= B != New->getBit(i); - } while (B != New->getBit(i)); - } - - if (Changed) - return New; - delete New; - return this; +RecTy *VarInit::getFieldType(const std::string &FieldName) const { + if (RecordRecTy *RTy = dynamic_cast(Ty)) + if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName)) + return RV->getType(); + return 0; } - Init *VarBitInit::resolveReferences(Record &R) { From lattner at cs.uiuc.edu Mon Dec 2 10:58:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 10:58:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Message-ID: <200212021657.KAA30549@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.3 -> 1.4 --- Log message: Add comments, factor out common code --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.3 llvm/utils/TableGen/Record.h:1.4 --- llvm/utils/TableGen/Record.h:1.3 Mon Dec 2 10:42:52 2002 +++ llvm/utils/TableGen/Record.h Mon Dec 2 10:57:01 2002 @@ -141,11 +141,27 @@ struct Init { virtual ~Init() {} - virtual bool isComplete() const = 0; + /// isComplete - This virtual method should be overridden by values that may + /// not be completely specified yet. + virtual bool isComplete() const { return true; } + + /// print - Print out this value. virtual void print(std::ostream &OS) const = 0; + + /// dump - Debugging method that may be called through a debugger, just + /// invokes print on cerr. void dump() const; + /// convertInitializerTo - This virtual function is a simple call-back + /// function that should be overridden to call the appropriate + /// RecTy::convertValue method. + /// virtual Init *convertInitializerTo(RecTy *Ty) = 0; + + /// convertInitializerBitRange - This method is used to implement the bitrange + /// selection operator. Given an initializer, it selects the specified bits + /// out, returning them as a new init of bits type. + /// virtual Init *convertInitializerBitRange(const std::vector &Bits) { return 0; } @@ -156,6 +172,11 @@ /// virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; } + /// resolveReferences - This method is used by classes that refer to other + /// variables which may not be defined at the time they expression is formed. + /// If a value is set for the variable later, this method will be called on + /// users of the value to allow the value to propagate out. + /// virtual Init *resolveReferences(Record &R) { return this; } }; @@ -189,7 +210,6 @@ return Ty->convertValue(this); } - virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); } }; @@ -248,7 +268,6 @@ } virtual Init *convertInitializerBitRange(const std::vector &Bits); - virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const { OS << Value; } }; @@ -264,7 +283,6 @@ return Ty->convertValue(this); } - virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; } }; @@ -287,7 +305,6 @@ return Ty->convertValue(this); } - virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const; }; @@ -310,7 +327,6 @@ virtual RecTy *getFieldType(const std::string &FieldName) const; - virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const { OS << VarName; } }; @@ -330,7 +346,6 @@ VarInit *getVariable() const { return VI; } unsigned getBitNum() const { return Bit; } - virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const { VI->print(OS); OS << "{" << Bit << "}"; } @@ -353,7 +368,6 @@ //virtual Init *convertInitializerBitRange(const std::vector &Bits); - virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const; }; @@ -374,7 +388,6 @@ return Ty->convertValue(this); } - virtual bool isComplete() const { return true; } virtual void print(std::ostream &OS) const { Rec->print(OS); OS << "." << FieldName; } @@ -392,7 +405,6 @@ Init *Value; public: RecordVal(const std::string &N, RecTy *T, unsigned P); - ~RecordVal() { /*delete Ty; delete Value; Bad for copy ctor!*/ } const std::string &getName() const { return Name; } From lattner at cs.uiuc.edu Mon Dec 2 11:45:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 11:45:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Message-ID: <200212021744.LAA31298@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.4 -> 1.5 --- Log message: Continued support for Field Initializer --- Diffs of the changes: Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.4 llvm/utils/TableGen/Record.h:1.5 --- llvm/utils/TableGen/Record.h:1.4 Mon Dec 2 10:57:01 2002 +++ llvm/utils/TableGen/Record.h Mon Dec 2 11:43:58 2002 @@ -59,6 +59,7 @@ Init *convertValue(BitsInit *BI); Init *convertValue(IntInit *II); Init *convertValue(VarInit *VI); + Init *convertValue(VarBitInit *VB) { return (Init*)VB; } void print(std::ostream &OS) const { OS << "bit"; } }; @@ -78,6 +79,7 @@ Init *convertValue(BitsInit *BI); Init *convertValue(IntInit *II); Init *convertValue(VarInit *VI); + Init *convertValue(FieldInit *VI); void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; } }; @@ -160,7 +162,8 @@ /// convertInitializerBitRange - This method is used to implement the bitrange /// selection operator. Given an initializer, it selects the specified bits - /// out, returning them as a new init of bits type. + /// out, returning them as a new init of bits type. If it is not legal to use + /// the bit subscript operator on this initializer, return null. /// virtual Init *convertInitializerBitRange(const std::vector &Bits) { return 0; @@ -308,46 +311,68 @@ virtual void print(std::ostream &OS) const; }; + +/// TypedInit - This is the common super-class of types that have a specific, +/// explicit, type. +/// +class TypedInit : public Init { + RecTy *Ty; +public: + TypedInit(RecTy *T) : Ty(T) {} + + RecTy *getType() const { return Ty; } + + /// resolveBitReference - This method is used to implement + /// VarBitInit::resolveReferences. If the bit is able to be resolved, we + /// simply return the resolved value, otherwise we return this. + /// + virtual Init *resolveBitReference(Record &R, unsigned Bit) = 0; +}; + /// VarInit - 'Opcode' - Represent a reference to an entire variable object. /// -class VarInit : public Init { +class VarInit : public TypedInit { std::string VarName; - RecTy *Ty; public: - VarInit(const std::string &VN, RecTy *T) : VarName(VN), Ty(T) {} + VarInit(const std::string &VN, RecTy *T) : TypedInit(T), VarName(VN) {} virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } const std::string &getName() const { return VarName; } - RecTy *getType() const { return Ty; } virtual Init *convertInitializerBitRange(const std::vector &Bits); + virtual Init *resolveBitReference(Record &R, unsigned Bit); + virtual RecTy *getFieldType(const std::string &FieldName) const; virtual void print(std::ostream &OS) const { OS << VarName; } }; -/// VarBitInit - Opcode{0} - Represent access to one bit of a variable +/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field. /// class VarBitInit : public Init { - VarInit *VI; + TypedInit *TI; unsigned Bit; public: - VarBitInit(VarInit *V, unsigned B) : VI(V), Bit(B) {} + VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) { + assert(T->getType() && dynamic_cast(T->getType()) && + ((BitsRecTy*)T->getType())->getNumBits() > B && + "Illegal VarBitInit expression!"); + } virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } - VarInit *getVariable() const { return VI; } + TypedInit *getVariable() const { return TI; } unsigned getBitNum() const { return Bit; } virtual void print(std::ostream &OS) const { - VI->print(OS); OS << "{" << Bit << "}"; + TI->print(OS); OS << "{" << Bit << "}"; } virtual Init *resolveReferences(Record &R); }; @@ -374,19 +399,22 @@ /// FieldInit - X.Y - Represent a reference to a subfield of a variable /// -class FieldInit : public Init { +class FieldInit : public TypedInit { Init *Rec; // Record we are referring to std::string FieldName; // Field we are accessing - RecTy *Ty; // The type of this expression public: FieldInit(Init *R, const std::string &FN) - : Rec(R), FieldName(FN), Ty(R->getFieldType(FN)) { - assert(Ty && "FieldInit with non-record type!"); + : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) { + assert(getType() && "FieldInit with non-record type!"); } virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } + + virtual Init *convertInitializerBitRange(const std::vector &Bits); + + virtual Init *resolveBitReference(Record &R, unsigned Bit); virtual void print(std::ostream &OS) const { Rec->print(OS); OS << "." << FieldName; From lattner at cs.uiuc.edu Mon Dec 2 11:45:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 11:45:02 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGen.cpp Message-ID: <200212021744.LAA31305@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGen.cpp updated: 1.1 -> 1.2 --- Log message: Adjustments due to new FieldInit stuff --- Diffs of the changes: Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.1 llvm/utils/TableGen/TableGen.cpp:1.2 --- llvm/utils/TableGen/TableGen.cpp:1.1 Sun Dec 1 19:23:04 2002 +++ llvm/utils/TableGen/TableGen.cpp Mon Dec 2 11:43:43 2002 @@ -236,7 +236,7 @@ unsigned Offset = 0; for (unsigned f = 0, e = Vals.size(); f != e; ++f) if (Vals[f].getPrefix()) { - BitsInit *FieldInit = (BitsInit*)Vals[f].getValue(); + BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue(); if (&Vals[f] == &Val) { // Read the bits directly now... for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) @@ -246,13 +246,19 @@ // Scan through the field looking for bit initializers of the current // variable... - for (unsigned i = 0, e = FieldInit->getNumBits(); i != e; ++i) + for (unsigned i = 0, e = FieldInitializer->getNumBits(); i != e; ++i) if (VarBitInit *VBI = - dynamic_cast(FieldInit->getBit(i))) { - if (VBI->getVariable()->getName() == Val.getName()) - Value |= getMemoryBit(Ptr, Offset+i) << VBI->getBitNum(); + dynamic_cast(FieldInitializer->getBit(i))) { + TypedInit *TI = VBI->getVariable(); + if (VarInit *VI = dynamic_cast(TI)) { + if (VI->getName() == Val.getName()) + Value |= getMemoryBit(Ptr, Offset+i) << VBI->getBitNum(); + } else if (FieldInit *FI = dynamic_cast(TI)) { + // FIXME: implement this! + std::cerr << "FIELD INIT not implemented yet!\n"; + } } - Offset += FieldInit->getNumBits(); + Offset += FieldInitializer->getNumBits(); } std::cout << "0x" << std::hex << Value << std::dec; From lattner at cs.uiuc.edu Mon Dec 2 11:45:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 11:45:03 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Message-ID: <200212021744.LAA31317@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.2 -> 1.3 --- Log message: Continued support for field initializer --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.2 llvm/utils/TableGen/Record.cpp:1.3 --- llvm/utils/TableGen/Record.cpp:1.2 Mon Dec 2 10:43:30 2002 +++ llvm/utils/TableGen/Record.cpp Mon Dec 2 11:44:35 2002 @@ -82,6 +82,10 @@ return 0; } +Init *BitsRecTy::convertValue(FieldInit *VI) { + return 0; +} + Init *IntRecTy::convertValue(BitsInit *BI) { int Result = 0; @@ -180,10 +184,10 @@ assert(getNumBits() != 0); VarBitInit *FirstBit = dynamic_cast(getBit(0)); if (FirstBit == 0) return true; - VarInit *Var = FirstBit->getVariable(); + TypedInit *Var = FirstBit->getVariable(); // Check to make sure the types are compatible. - BitsRecTy *Ty = dynamic_cast(Var->getType()); + BitsRecTy *Ty = dynamic_cast(FirstBit->getVariable()->getType()); if (Ty == 0) return true; if (Ty->getNumBits() != getNumBits()) return true; // Incompatible types! @@ -194,7 +198,7 @@ return true; } - OS << Var->getName(); + Var->print(OS); return false; } @@ -249,7 +253,7 @@ } Init *VarInit::convertInitializerBitRange(const std::vector &Bits) { - BitsRecTy *T = dynamic_cast(Ty); + BitsRecTy *T = dynamic_cast(getType()); if (T == 0) return 0; // Cannot subscript a non-bits variable... unsigned NumBits = T->getNumBits(); @@ -265,33 +269,64 @@ } RecTy *VarInit::getFieldType(const std::string &FieldName) const { - if (RecordRecTy *RTy = dynamic_cast(Ty)) + if (RecordRecTy *RTy = dynamic_cast(getType())) if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName)) return RV->getType(); return 0; } - -Init *VarBitInit::resolveReferences(Record &R) { - if (R.isTemplateArg(getVariable()->getName())) +Init *VarInit::resolveBitReference(Record &R, unsigned Bit) { + if (R.isTemplateArg(getName())) return this; - RecordVal *RV = R.getValue(getVariable()->getName()); + RecordVal *RV = R.getValue(getName()); assert(RV && "Reference to a non-existant variable?"); assert(dynamic_cast(RV->getValue())); BitsInit *BI = (BitsInit*)RV->getValue(); - assert(getBitNum() < BI->getNumBits() && "Bit reference out of range!"); - Init *B = BI->getBit(getBitNum()); + assert(Bit < BI->getNumBits() && "Bit reference out of range!"); + Init *B = BI->getBit(Bit); if (!dynamic_cast(B)) // If the bit is not set... return B; // Replace the VarBitInit with it. return this; } + + +Init *VarBitInit::resolveReferences(Record &R) { + Init *I = getVariable()->resolveBitReference(R, getBitNum()); + + if (I != getVariable()) + return I; + return this; +} + void DefInit::print(std::ostream &OS) const { OS << Def->getName(); } + +Init *FieldInit::convertInitializerBitRange(const std::vector &Bits) { + BitsRecTy *T = dynamic_cast(getType()); + if (T == 0) return 0; // Cannot subscript a non-bits field... + unsigned NumBits = T->getNumBits(); + + BitsInit *BI = new BitsInit(Bits.size()); + for (unsigned i = 0, e = Bits.size(); i != e; ++i) { + if (Bits[i] >= NumBits) { + delete BI; + return 0; + } + BI->setBit(i, new VarBitInit(this, Bits[i])); + } + return BI; +} + +Init *FieldInit::resolveBitReference(Record &R, unsigned Bit) { + // Can never be resolved yet. + return this; +} + //===----------------------------------------------------------------------===// // Other implementations From lattner at cs.uiuc.edu Mon Dec 2 11:55:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 11:55:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Record.h Message-ID: <200212021754.LAA31582@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.3 -> 1.4 Record.h updated: 1.5 -> 1.6 --- Log message: Continued support for field intitializers --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.3 llvm/utils/TableGen/Record.cpp:1.4 --- llvm/utils/TableGen/Record.cpp:1.3 Mon Dec 2 11:44:35 2002 +++ llvm/utils/TableGen/Record.cpp Mon Dec 2 11:53:54 2002 @@ -24,7 +24,7 @@ return new BitInit(Val != 0); } -Init *BitRecTy::convertValue(VarInit *VI) { +Init *BitRecTy::convertValue(TypedInit *VI) { if (dynamic_cast(VI->getType())) return VI; // Accept variable if it is already of bit type! return 0; @@ -65,7 +65,7 @@ return 0; } -Init *BitsRecTy::convertValue(VarInit *VI) { +Init *BitsRecTy::convertValue(TypedInit *VI) { if (BitsRecTy *BRT = dynamic_cast(VI->getType())) if (BRT->Size == Size) { BitsInit *Ret = new BitsInit(Size); @@ -82,9 +82,23 @@ return 0; } +#if 0 Init *BitsRecTy::convertValue(FieldInit *VI) { + if (BitsRecTy *BRT = dynamic_cast(VI->getType())) + if (BRT->Size == Size) { + BitsInit *Ret = new BitsInit(Size); + for (unsigned i = 0; i != Size; ++i) + Ret->setBit(i, new VarBitInit(VI, i)); + return Ret; + } + if (Size == 1 && dynamic_cast(VI->getType())) { + BitsInit *Ret = new BitsInit(1); + Ret->setBit(0, VI); + return Ret; + } return 0; } +#endif Init *IntRecTy::convertValue(BitsInit *BI) { @@ -98,15 +112,15 @@ return new IntInit(Result); } -Init *IntRecTy::convertValue(VarInit *VI) { - if (dynamic_cast(VI->getType())) - return VI; // Accept variable if already of the right type! +Init *IntRecTy::convertValue(TypedInit *TI) { + if (dynamic_cast(TI->getType())) + return TI; // Accept variable if already of the right type! return 0; } -Init *StringRecTy::convertValue(VarInit *VI) { - if (dynamic_cast(VI->getType())) - return VI; // Accept variable if already of the right type! +Init *StringRecTy::convertValue(TypedInit *TI) { + if (dynamic_cast(TI->getType())) + return TI; // Accept variable if already of the right type! return 0; } Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.5 llvm/utils/TableGen/Record.h:1.6 --- llvm/utils/TableGen/Record.h:1.5 Mon Dec 2 11:43:58 2002 +++ llvm/utils/TableGen/Record.h Mon Dec 2 11:53:54 2002 @@ -17,10 +17,11 @@ class IntInit; class StringInit; class ListInit; -class VarInit; -class VarBitInit; class DefInit; +class TypedInit; +class VarInit; class FieldInit; +class VarBitInit; class Record; //===----------------------------------------------------------------------===// @@ -36,10 +37,15 @@ virtual Init *convertValue( IntInit *II) { return 0; } virtual Init *convertValue(StringInit *SI) { return 0; } virtual Init *convertValue( ListInit *LI) { return 0; } - virtual Init *convertValue( VarInit *VI) { return 0; } virtual Init *convertValue(VarBitInit *VB) { return 0; } virtual Init *convertValue( DefInit *DI) { return 0; } - virtual Init *convertValue( FieldInit *FI) { return 0; } + virtual Init *convertValue( TypedInit *TI) { return 0; } + virtual Init *convertValue( VarInit *VI) { + return convertValue((TypedInit*)VI); + } + virtual Init *convertValue( FieldInit *FI) { + return convertValue((TypedInit*)FI); + } virtual void print(std::ostream &OS) const = 0; void dump() const; @@ -58,7 +64,7 @@ Init *convertValue(BitInit *BI) { return (Init*)BI; } Init *convertValue(BitsInit *BI); Init *convertValue(IntInit *II); - Init *convertValue(VarInit *VI); + Init *convertValue(TypedInit *VI); Init *convertValue(VarBitInit *VB) { return (Init*)VB; } void print(std::ostream &OS) const { OS << "bit"; } @@ -78,8 +84,7 @@ Init *convertValue(BitInit *UI); Init *convertValue(BitsInit *BI); Init *convertValue(IntInit *II); - Init *convertValue(VarInit *VI); - Init *convertValue(FieldInit *VI); + Init *convertValue(TypedInit *VI); void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; } }; @@ -91,7 +96,7 @@ Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue(IntInit *II) { return (Init*)II; } Init *convertValue(BitsInit *BI); - Init *convertValue(VarInit *VI); + Init *convertValue(TypedInit *TI); void print(std::ostream &OS) const { OS << "int"; } }; @@ -101,7 +106,7 @@ struct StringRecTy : public RecTy { Init *convertValue(UnsetInit *UI) { return (Init*)UI; } Init *convertValue(StringInit *SI) { return (Init*)SI; } - Init *convertValue(VarInit *VI); + Init *convertValue(TypedInit *VI); void print(std::ostream &OS) const { OS << "string"; } }; From lattner at cs.uiuc.edu Mon Dec 2 15:02:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:02:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachine.h Message-ID: <200212022101.PAA05574@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.20 -> 1.21 --- Log message: Add stub to emit machine code for JIT --- Diffs of the changes: Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.20 llvm/include/llvm/Target/TargetMachine.h:1.21 --- llvm/include/llvm/Target/TargetMachine.h:1.20 Wed Nov 20 12:54:53 2002 +++ llvm/include/llvm/Target/TargetMachine.h Mon Dec 2 15:00:50 2002 @@ -17,6 +17,7 @@ class MachineFrameInfo; class MachineCacheInfo; class MachineOptInfo; +class MachineCodeEmitter; class MRegisterInfo; class PassManager; class Pass; @@ -77,20 +78,31 @@ // virtual unsigned findOptimalStorageSize(const Type* ty) const; + /// addPassesToJITCompile - Add passes to the specified pass manager to + /// implement a fast dynamic compiler for this target. Return true if this is + /// not supported for this target. + /// + virtual bool addPassesToJITCompile(PassManager &PM) { return true; } + /// addPassesToEmitAssembly - Add passes to the specified pass manager to get - /// assembly langage code emited. Typically this will involve several steps - /// of code generation. This method should return true if code generation is - /// not supported. + /// assembly langage code emitted. Typically this will involve several steps + /// of code generation. This method should return true if assembly emission + /// is not supported. /// virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) { return true; } - /// addPassesToJITCompile - Add passes to the specified pass manager to - /// implement a fast dynamic compiler for this target. Return true if this is - /// not supported for this target. + /// addPassesToEmitMachineCode - Add passes to the specified pass manager to + /// get machine code emitted. This uses a MAchineCodeEmitter object to handle + /// actually outputting the machine code and resolving things like the address + /// of functions. This method should returns true if machine code emission is + /// not supported. /// - virtual bool addPassesToJITCompile(PassManager &PM) { return true; } + virtual bool addPassesToEmitMachineCode(PassManager &PM, + MachineCodeEmitter *MCE) { + return true; + } }; #endif From brukman at cs.uiuc.edu Mon Dec 2 15:11:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Dec 2 15:11:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200212022110.PAA07095@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.4 -> 1.5 --- Log message: Fix order of operands on a store from reg to [reg+offset]. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.4 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.5 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.4 Fri Nov 22 17:15:27 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Mon Dec 2 15:10:35 2002 @@ -31,8 +31,8 @@ unsigned ImmOffset, unsigned dataSize) const { - MachineInstr *MI = addRegOffset(BuildMI(X86::MOVrm32, 5).addReg(SrcReg), - DestReg, ImmOffset); + MachineInstr *MI = addRegOffset(BuildMI(X86::MOVrm32, 5), + DestReg, ImmOffset).addReg(SrcReg); return ++(MBB->insert(MBBI, MI)); } From brukman at cs.uiuc.edu Mon Dec 2 15:13:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Dec 2 15:13:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocSimple.cpp Message-ID: <200212022112.PAA07119@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocSimple.cpp updated: 1.1 -> 1.2 --- Log message: * Abstracted out stack space allocation into its own function * Added saving of register values to the stack --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocSimple.cpp diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.1 llvm/lib/CodeGen/RegAllocSimple.cpp:1.2 --- llvm/lib/CodeGen/RegAllocSimple.cpp:1.1 Fri Nov 22 16:44:32 2002 +++ llvm/lib/CodeGen/RegAllocSimple.cpp Mon Dec 2 15:11:58 2002 @@ -53,6 +53,10 @@ return RegsUsed.find(Reg) == RegsUsed.end(); } + /// + unsigned allocateStackSpaceFor(unsigned VirtReg, + const TargetRegisterClass *regClass); + /// Given size (in bytes), returns a register that is currently unused /// Side effect: marks that register as being used until manually cleared unsigned getFreeReg(unsigned virtualReg); @@ -84,6 +88,22 @@ } +unsigned RegAllocSimple::allocateStackSpaceFor(unsigned VirtReg, + const TargetRegisterClass *regClass) +{ + if (RegMap.find(VirtReg) == RegMap.end()) { + unsigned size = regClass->getDataSize(); + unsigned over = NumBytesAllocated - (NumBytesAllocated % ByteAlignment); + if (size >= ByteAlignment - over) { + // need to pad by (ByteAlignment - over) + NumBytesAllocated += ByteAlignment - over; + } + RegMap[VirtReg] = NumBytesAllocated; + NumBytesAllocated += size; + } + return RegMap[VirtReg]; +} + unsigned RegAllocSimple::getFreeReg(unsigned virtualReg) { const TargetRegisterClass* regClass = MF->getRegClass(virtualReg); unsigned physReg; @@ -112,29 +132,15 @@ const TargetRegisterClass* regClass = MF->getRegClass(VirtReg); assert(regClass); - unsigned stackOffset; - if (RegMap.find(VirtReg) == RegMap.end()) { - unsigned size = regClass->getDataSize(); - unsigned over = NumBytesAllocated - (NumBytesAllocated % ByteAlignment); - if (size >= ByteAlignment - over) { - // need to pad by (ByteAlignment - over) - NumBytesAllocated += ByteAlignment - over; - } - RegMap[VirtReg] = NumBytesAllocated; - NumBytesAllocated += size; - } - stackOffset = RegMap[VirtReg]; + unsigned stackOffset = allocateStackSpaceFor(VirtReg, regClass); PhysReg = getFreeReg(VirtReg); - // Add move instruction(s) - MachineBasicBlock::iterator newI = - RegInfo->loadRegOffset2Reg(CurrMBB, I, PhysReg, - RegInfo->getFramePointer(), - stackOffset, regClass->getDataSize()); - // FIXME: increment the frame pointer - return newI; + // Add move instruction(s) + return RegInfo->loadRegOffset2Reg(CurrMBB, I, PhysReg, + RegInfo->getFramePointer(), + stackOffset, regClass->getDataSize()); } MachineBasicBlock::iterator @@ -143,10 +149,9 @@ { const TargetRegisterClass* regClass = MF->getRegClass(VirtReg); assert(regClass); - assert(RegMap.find(VirtReg) != RegMap.end() && - "Virtual reg has no stack offset mapping!"); - unsigned offset = RegMap[VirtReg]; + unsigned offset = allocateStackSpaceFor(VirtReg, regClass); + // Add move instruction(s) return RegInfo->storeReg2RegOffset(CurrMBB, I, PhysReg, RegInfo->getFramePointer(), @@ -165,7 +170,6 @@ { CurrMBB = &(*MBB); - // FIXME: if return, special case => into return register //loop over each basic block for (MachineBasicBlock::iterator I = MBB->begin(); I != MBB->end(); ++I) { @@ -185,20 +189,18 @@ DEBUG(std::cerr << "const\n"); } else if (op.isVirtualRegister()) { virtualReg = (unsigned) op.getAllocatedRegNum(); -#if 0 - // FIXME: save register to stack - if (op.opIsDef()) { - MachineBasicBlock::iterator J = I; - saveRegToStack(++J, virtualReg, physReg); - } -#endif + // save register to stack if it's a def DEBUG(std::cerr << "op: " << op << "\n"); DEBUG(std::cerr << "\t inst[" << i << "]: "; MI->print(std::cerr, TM)); - I = moveUseToReg(I, virtualReg, physReg); - //MI = *I; - bool def = op.opIsDef() || op.opIsDefAndUse(); - MI->SetMachineOperandReg(i, physReg, def); + if (op.opIsDef()) { + physReg = getFreeReg(virtualReg); + MachineBasicBlock::iterator J = I; + I = saveRegToStack(++J, virtualReg, physReg); + } else { + I = moveUseToReg(I, virtualReg, physReg); + } + MI->SetMachineOperandReg(i, physReg); DEBUG(std::cerr << "virt: " << virtualReg << ", phys: " << op.getAllocatedRegNum() << "\n"); } From lattner at cs.uiuc.edu Mon Dec 2 15:14:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:14:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachine.h Message-ID: <200212022113.PAA07466@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.21 -> 1.22 --- Log message: Add comment about ownership semantics --- Diffs of the changes: Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.21 llvm/include/llvm/Target/TargetMachine.h:1.22 --- llvm/include/llvm/Target/TargetMachine.h:1.21 Mon Dec 2 15:00:50 2002 +++ llvm/include/llvm/Target/TargetMachine.h Mon Dec 2 15:13:45 2002 @@ -97,7 +97,8 @@ /// get machine code emitted. This uses a MAchineCodeEmitter object to handle /// actually outputting the machine code and resolving things like the address /// of functions. This method should returns true if machine code emission is - /// not supported. + /// not supported. The ownership of the MCE is not transfered to the backend + /// pass... the caller of this method should delete it. /// virtual bool addPassesToEmitMachineCode(PassManager &PM, MachineCodeEmitter *MCE) { From brukman at cs.uiuc.edu Mon Dec 2 15:15:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Dec 2 15:15:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/.cvsignore Message-ID: <200212022114.PAA07574@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: .cvsignore added (r1.1) --- Log message: Ignore generated files FileLexer.* and FileParser.* --- Diffs of the changes: From brukman at cs.uiuc.edu Mon Dec 2 15:16:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Dec 2 15:16:01 2002 Subject: [llvm-commits] CVS: llvm/lib/AsmParser/.cvsignore Message-ID: <200212022115.PAA07688@apoc.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: .cvsignore added (r1.1) --- Log message: Ignore generated files Lexer.cpp and llvmAsmParser.* --- Diffs of the changes: From brukman at cs.uiuc.edu Mon Dec 2 15:16:02 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon Dec 2 15:16:02 2002 Subject: [llvm-commits] CVS: llvm/utils/Burg/.cvsignore Message-ID: <200212022115.PAA07728@apoc.cs.uiuc.edu> Changes in directory llvm/utils/Burg: .cvsignore added (r1.1) --- Log message: Ignore generated files gram.tab.c and gram.tab.h --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Dec 2 15:16:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:16:03 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachine.h Message-ID: <200212022115.PAA07735@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.22 -> 1.23 --- Log message: The hopefully final version of addPassesToEmitMachineCode which does not have any question about ownership --- Diffs of the changes: Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.22 llvm/include/llvm/Target/TargetMachine.h:1.23 --- llvm/include/llvm/Target/TargetMachine.h:1.22 Mon Dec 2 15:13:45 2002 +++ llvm/include/llvm/Target/TargetMachine.h Mon Dec 2 15:15:42 2002 @@ -97,11 +97,10 @@ /// get machine code emitted. This uses a MAchineCodeEmitter object to handle /// actually outputting the machine code and resolving things like the address /// of functions. This method should returns true if machine code emission is - /// not supported. The ownership of the MCE is not transfered to the backend - /// pass... the caller of this method should delete it. + /// not supported. /// virtual bool addPassesToEmitMachineCode(PassManager &PM, - MachineCodeEmitter *MCE) { + MachineCodeEmitter &MCE) { return true; } }; From lattner at cs.uiuc.edu Mon Dec 2 15:22:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:22:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineCodeEmitter.h Message-ID: <200212022121.PAA08170@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineCodeEmitter.h added (r1.1) --- Log message: Initial version of MachineCodeEmitter interface: empty --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Dec 2 15:23:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:23:01 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/jello.cpp Message-ID: <200212022122.PAA08267@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: jello.cpp updated: 1.4 -> 1.5 --- Log message: Add initial support for machine code emission --- Diffs of the changes: Index: llvm/tools/jello/jello.cpp diff -u llvm/tools/jello/jello.cpp:1.4 llvm/tools/jello/jello.cpp:1.5 --- llvm/tools/jello/jello.cpp:1.4 Tue Oct 29 20:18:29 2002 +++ llvm/tools/jello/jello.cpp Mon Dec 2 15:22:04 2002 @@ -16,6 +16,15 @@ #include "Support/CommandLine.h" #include "Support/Statistic.h" + +#include "llvm/CodeGen/MachineCodeEmitter.h" + +struct JelloMachineCodeEmitter : public MachineCodeEmitter { + + +}; + + namespace { cl::opt InputFile(cl::desc(""), cl::Positional, cl::init("-")); @@ -48,9 +57,21 @@ } PassManager Passes; + + // Compile LLVM Code down to machine code in the intermediate representation if (Target.addPassesToJITCompile(Passes)) { std::cerr << argv[0] << ": target '" << Target.getName() << "' doesn't support JIT compilation!\n"; + return 1; + } + + // Turn the machine code intermediate representation into bytes in memory that + // may be executed. + // + JelloMachineCodeEmitter MCE; + if (Target.addPassesToEmitMachineCode(Passes, MCE)) { + std::cerr << argv[0] << ": target '" << Target.getName() + << "' doesn't support machine code emission!\n"; return 1; } From lattner at cs.uiuc.edu Mon Dec 2 15:25:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:25:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/MachineCodeEmitter.cpp X86TargetMachine.h Message-ID: <200212022124.PAA08960@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: MachineCodeEmitter.cpp added (r1.1) X86TargetMachine.h updated: 1.2 -> 1.3 --- Log message: Initial support for machine code emission --- Diffs of the changes: Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.2 llvm/lib/Target/X86/X86TargetMachine.h:1.3 --- llvm/lib/Target/X86/X86TargetMachine.h:1.2 Tue Oct 29 18:56:18 2002 +++ llvm/lib/Target/X86/X86TargetMachine.h Mon Dec 2 15:24:12 2002 @@ -30,6 +30,15 @@ /// not supported for this target. /// virtual bool addPassesToJITCompile(PassManager &PM); + + /// addPassesToEmitMachineCode - Add passes to the specified pass manager to + /// get machine code emitted. This uses a MAchineCodeEmitter object to handle + /// actually outputting the machine code and resolving things like the address + /// of functions. This method should returns true if machine code emission is + /// not supported. + /// + virtual bool addPassesToEmitMachineCode(PassManager &PM, + MachineCodeEmitter &MCE); }; #endif From lattner at cs.uiuc.edu Mon Dec 2 15:42:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:42:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.h Message-ID: <200212022141.PAA12004@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.h updated: 1.14 -> 1.15 --- Log message: Eliminate OtherFrm --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.14 llvm/lib/Target/X86/X86InstrInfo.h:1.15 --- llvm/lib/Target/X86/X86InstrInfo.h:1.14 Thu Nov 21 16:48:01 2002 +++ llvm/lib/Target/X86/X86InstrInfo.h Mon Dec 2 15:40:58 2002 @@ -20,37 +20,33 @@ // instructions. // - /// Other - An instruction gets this form if it doesn't fit any of the - /// catagories below. - OtherFrm = 0, - /// Raw - This form is for instructions that don't have any operands, so /// they are just a fixed opcode value, like 'leave'. - RawFrm = 1, + RawFrm = 0, /// AddRegFrm - This form is used for instructions like 'push r32' that have /// their one register operand added to their opcode. - AddRegFrm = 2, + AddRegFrm = 1, /// MRMDestReg - This form is used for instructions that use the Mod/RM byte /// to specify a destination, which in this case is a register. /// - MRMDestReg = 3, + MRMDestReg = 2, /// MRMDestMem - This form is used for instructions that use the Mod/RM byte /// to specify a destination, which in this case is memory. /// - MRMDestMem = 4, + MRMDestMem = 3, /// MRMSrcReg - This form is used for instructions that use the Mod/RM byte /// to specify a source, which in this case is a register. /// - MRMSrcReg = 5, + MRMSrcReg = 4, /// MRMSrcMem - This form is used for instructions that use the Mod/RM byte /// to specify a source, which in this case is memory. /// - MRMSrcMem = 6, + MRMSrcMem = 5, /// 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 From lattner at cs.uiuc.edu Mon Dec 2 15:42:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:42:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200212022141.PAA12018@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.18 -> 1.19 --- Log message: Remove comment Remove handling of OtherFrm --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.18 llvm/lib/Target/X86/Printer.cpp:1.19 --- llvm/lib/Target/X86/Printer.cpp:1.18 Sun Dec 1 17:25:59 2002 +++ llvm/lib/Target/X86/Printer.cpp Mon Dec 2 15:40:46 2002 @@ -42,8 +42,6 @@ MachineFunction & MF = MachineFunction::get (&F); const MachineInstrInfo & MII = TM.getInstrInfo (); - O << "; x86 printing only sorta implemented so far!\n"; - // Print out labels for the function. O << "\t.globl\t" << F.getName () << "\n"; O << "\t.type\t" << F.getName () << ", @function\n"; @@ -306,11 +304,6 @@ if (Desc.TSFlags & X86II::TB) O << "0F "; // Two-byte opcode prefix switch (Desc.TSFlags & X86II::FormMask) { - case X86II::OtherFrm: - O << "\t\t\t"; - O << "-"; MI->print(O, TM); - break; - case X86II::RawFrm: // The accepted forms of Raw instructions are: // 1. nop - No operand required From lattner at cs.uiuc.edu Mon Dec 2 15:45:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:45:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineCodeEmitter.h Message-ID: <200212022144.PAA12153@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineCodeEmitter.h updated: 1.1 -> 1.2 --- Log message: Start adding to the meat of MachineCodeEmitter --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineCodeEmitter.h diff -u llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.1 llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.2 --- llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.1 Mon Dec 2 15:21:36 2002 +++ llvm/include/llvm/CodeGen/MachineCodeEmitter.h Mon Dec 2 15:44:13 2002 @@ -10,11 +10,29 @@ #ifndef LLVM_CODEGEN_MACHINE_CODE_EMITTER_H #define LLVM_CODEGEN_MACHINE_CODE_EMITTER_H -struct MachineCodeEmitter { +class MachineFunction; +class MachineBasicBlock; +struct MachineCodeEmitter { + /// startFunction - This callback is invoked when the specified function is + /// about to be code generated. + /// + virtual void startFunction(MachineFunction &F) {} + /// finishFunction - This callback is invoked when the specified function has + /// finished code generation. + /// + virtual void finishFunction(MachineFunction &F) {} + + /// startBasicBlock - This callback is invoked when a new basic block is about + /// to be emitted. + /// + virtual void startBasicBlock(MachineBasicBlock &BB) {} + /// emitByte - This callback is invoked when a byte needs to be written to the + /// output stream. + virtual void emitByte(unsigned char B) {} }; #endif From lattner at cs.uiuc.edu Mon Dec 2 15:45:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:45:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/MachineCodeEmitter.cpp Message-ID: <200212022144.PAA12215@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: MachineCodeEmitter.cpp updated: 1.1 -> 1.2 --- Log message: Start implementing MachineCodeEmitter --- Diffs of the changes: Index: llvm/lib/Target/X86/MachineCodeEmitter.cpp diff -u llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.1 llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.2 --- llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.1 Mon Dec 2 15:24:12 2002 +++ llvm/lib/Target/X86/MachineCodeEmitter.cpp Mon Dec 2 15:44:34 2002 @@ -8,6 +8,8 @@ #include "X86TargetMachine.h" #include "llvm/PassManager.h" #include "llvm/CodeGen/MachineCodeEmitter.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" namespace { struct Emitter : public FunctionPass { @@ -15,10 +17,11 @@ MachineCodeEmitter &MCE; Emitter(TargetMachine &tm, MachineCodeEmitter &mce) : TM(tm), MCE(mce) {} - ~Emitter() { - } - bool runOnFunction(Function &F) { return false; } + bool runOnFunction(Function &F); + + void emitBasicBlock(MachineBasicBlock &MBB); + void emitInstruction(MachineInstr &MI); }; } @@ -33,4 +36,34 @@ MachineCodeEmitter &MCE) { PM.add(new Emitter(*this, MCE)); return false; +} + +bool Emitter::runOnFunction(Function &F) { + MachineFunction &MF = MachineFunction::get(&F); + + MCE.startFunction(MF); + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) + emitBasicBlock(*I); + MCE.finishFunction(MF); + return false; +} + +void Emitter::emitBasicBlock(MachineBasicBlock &MBB) { + MCE.startBasicBlock(MBB); + for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) + emitInstruction(**I); +} + +void Emitter::emitInstruction(MachineInstr &MI) { + unsigned Opcode = MI.getOpcode(); + const MachineInstrDescriptor &Desc = TM.getInstrInfo().get(Opcode); + + // Emit instruction prefixes if neccesary + if (Desc.TSFlags & X86II::OpSize) MCE.emitByte(0x66);// Operand size... + if (Desc.TSFlags & X86II::TB) MCE.emitByte(0x0F); // Two-byte opcode prefix + + switch (Desc.TSFlags & X86II::FormMask) { + case X86II::RawFrm: + ; + } } From lattner at cs.uiuc.edu Mon Dec 2 15:51:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:51:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86TargetMachine.h Message-ID: <200212022150.PAA12415@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86TargetMachine.h updated: 1.3 -> 1.4 --- Log message: Expose explicit type --- Diffs of the changes: Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.3 llvm/lib/Target/X86/X86TargetMachine.h:1.4 --- llvm/lib/Target/X86/X86TargetMachine.h:1.3 Mon Dec 2 15:24:12 2002 +++ llvm/lib/Target/X86/X86TargetMachine.h Mon Dec 2 15:50:41 2002 @@ -15,7 +15,7 @@ public: X86TargetMachine(); - virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; } + virtual const X86InstrInfo &getInstrInfo() const { return instrInfo; } virtual const MachineSchedInfo &getSchedInfo() const { abort(); } virtual const MachineRegInfo &getRegInfo() const { abort(); } virtual const MachineFrameInfo &getFrameInfo() const { abort(); } From lattner at cs.uiuc.edu Mon Dec 2 15:57:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:57:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/MachineCodeEmitter.cpp Message-ID: <200212022156.PAA12515@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: MachineCodeEmitter.cpp updated: 1.2 -> 1.3 --- Log message: More support for machine code emission: raw instructions --- Diffs of the changes: Index: llvm/lib/Target/X86/MachineCodeEmitter.cpp diff -u llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.2 llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.3 --- llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.2 Mon Dec 2 15:44:34 2002 +++ llvm/lib/Target/X86/MachineCodeEmitter.cpp Mon Dec 2 15:56:18 2002 @@ -13,10 +13,12 @@ namespace { struct Emitter : public FunctionPass { - TargetMachine &TM; - MachineCodeEmitter &MCE; + X86TargetMachine &TM; + const X86InstrInfo &II; + MachineCodeEmitter &MCE; - Emitter(TargetMachine &tm, MachineCodeEmitter &mce) : TM(tm), MCE(mce) {} + Emitter(X86TargetMachine &tm, MachineCodeEmitter &mce) + : TM(tm), II(TM.getInstrInfo()), MCE(mce) {} bool runOnFunction(Function &F); @@ -56,14 +58,21 @@ void Emitter::emitInstruction(MachineInstr &MI) { unsigned Opcode = MI.getOpcode(); - const MachineInstrDescriptor &Desc = TM.getInstrInfo().get(Opcode); + const MachineInstrDescriptor &Desc = II.get(Opcode); // Emit instruction prefixes if neccesary if (Desc.TSFlags & X86II::OpSize) MCE.emitByte(0x66);// Operand size... - if (Desc.TSFlags & X86II::TB) MCE.emitByte(0x0F); // Two-byte opcode prefix + if (Desc.TSFlags & X86II::TB) MCE.emitByte(0x0F);// Two-byte opcode prefix switch (Desc.TSFlags & X86II::FormMask) { case X86II::RawFrm: - ; + MCE.emitByte(II.getBaseOpcodeFor(Opcode)); + + if (MI.getNumOperands() == 1) { + assert(MI.getOperand(0).getType() == MachineOperand::MO_PCRelativeDisp); + MCE.emitPCRelativeDisp(MI.getOperand(0).getVRegValue()); + } + + break; } } From lattner at cs.uiuc.edu Mon Dec 2 15:57:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 15:57:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineCodeEmitter.h Message-ID: <200212022156.PAA12525@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineCodeEmitter.h updated: 1.2 -> 1.3 --- Log message: More support --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineCodeEmitter.h diff -u llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.2 llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.3 --- llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.2 Mon Dec 2 15:44:13 2002 +++ llvm/include/llvm/CodeGen/MachineCodeEmitter.h Mon Dec 2 15:56:28 2002 @@ -12,6 +12,7 @@ class MachineFunction; class MachineBasicBlock; +class Value; struct MachineCodeEmitter { @@ -32,7 +33,14 @@ /// emitByte - This callback is invoked when a byte needs to be written to the /// output stream. + /// virtual void emitByte(unsigned char B) {} + + /// emitPCRelativeDisp - This callback is invoked when we need to write out a + /// PC relative displacement for the specified Value*. This is used for call + /// and jump instructions typically. + /// + virtual void emitPCRelativeDisp(Value *V) {} }; #endif From lattner at cs.uiuc.edu Mon Dec 2 18:52:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 18:52:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86Implicit.cpp X86Implicit.h InstSelectSimple.cpp Message-ID: <200212030051.SAA30623@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86Implicit.cpp added (r1.1) X86Implicit.h added (r1.1) InstSelectSimple.cpp updated: 1.41 -> 1.42 --- Log message: brg X86Implicit.cpp, X86Implicit.h: New files. InstSelectSimple.cpp: Add some clarifications in visitCallInst comments. --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.41 llvm/lib/Target/X86/InstSelectSimple.cpp:1.42 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.41 Sun Dec 1 17:24:58 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Mon Dec 2 18:51:09 2002 @@ -397,6 +397,8 @@ { case cByte: case cShort: + // Promote V to 32 bits wide, and move the result into EAX, + // then push EAX. promote32 (X86::EAX, v); BuildMI (BB, X86::PUSHr32, 1).addReg (X86::EAX); break; @@ -405,7 +407,7 @@ BuildMI (BB, X86::PUSHr32, 1).addReg (argReg); break; default: - // FIXME + // FIXME: long/ulong/double args not handled. visitInstruction (CI); break; } From lattner at cs.uiuc.edu Mon Dec 2 23:42:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 23:42:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MachineInstrInfo.h Message-ID: <200212030541.XAA19502@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MachineInstrInfo.h updated: 1.35 -> 1.36 --- Log message: Add entries to track information about implicit uses and definitions of the instructions --- Diffs of the changes: Index: llvm/include/llvm/Target/MachineInstrInfo.h diff -u llvm/include/llvm/Target/MachineInstrInfo.h:1.35 llvm/include/llvm/Target/MachineInstrInfo.h:1.36 --- llvm/include/llvm/Target/MachineInstrInfo.h:1.35 Sun Nov 17 17:21:45 2002 +++ llvm/include/llvm/Target/MachineInstrInfo.h Mon Dec 2 23:41:32 2002 @@ -1,8 +1,8 @@ -//===-- llvm/Target/InstrInfo.h - Target Instruction Information --*-C++-*-==// +//===-- llvm/Target/MachineInstrInstrInfo.h - Instruction Infor ---*-C++-*-===// // // This file describes the target machine instructions to the code generator. // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #ifndef LLVM_TARGET_MACHINEINSTRINFO_H #define LLVM_TARGET_MACHINEINSTRINFO_H @@ -68,6 +68,8 @@ InstrSchedClass schedClass; // enum identifying instr sched class unsigned Flags; // flags identifying machine instr class unsigned TSFlags; // Target Specific Flag values + const unsigned *ImplicitUses; // Registers implicitly read by this instr + const unsigned *ImplicitDefs; // Registers implicitly defined by this instr }; From lattner at cs.uiuc.edu Mon Dec 2 23:43:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 23:43:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/Sparc.cpp Message-ID: <200212030542.XAA19513@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: Sparc.cpp updated: 1.56 -> 1.57 --- Log message: Initialize implicit uses/defs fields for sparc backend to empty list --- Diffs of the changes: Index: llvm/lib/Target/Sparc/Sparc.cpp diff -u llvm/lib/Target/Sparc/Sparc.cpp:1.56 llvm/lib/Target/Sparc/Sparc.cpp:1.57 --- llvm/lib/Target/Sparc/Sparc.cpp:1.56 Thu Oct 31 11:16:18 2002 +++ llvm/lib/Target/Sparc/Sparc.cpp Mon Dec 2 23:41:54 2002 @@ -23,12 +23,14 @@ #include "Support/CommandLine.h" using std::cerr; +static const unsigned ImplicitRegUseList[] = { 0 }; /* not used yet */ // Build the MachineInstruction Description Array... const MachineInstrDescriptor SparcMachineInstrDesc[] = { #define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \ NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \ { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \ - NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS, 0 }, + NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS, 0, \ + ImplicitRegUseList, ImplicitRegUseList }, #include "SparcInstr.def" }; From lattner at cs.uiuc.edu Mon Dec 2 23:44:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Dec 2 23:44:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.h X86InstrInfo.cpp X86InstrInfo.def X86Implicit.cpp X86Implicit.h Message-ID: <200212030543.XAA19530@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.h updated: 1.6 -> 1.7 X86InstrInfo.cpp updated: 1.9 -> 1.10 X86InstrInfo.def updated: 1.29 -> 1.30 X86Implicit.cpp (r1.1) removed X86Implicit.h (r1.1) removed --- Log message: * Move information about Implicit Defs/Uses into X86InstrInfo.def. * Expose information about implicit defs/uses of register through the MachineInstrInfo.h file. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.6 llvm/lib/Target/X86/X86.h:1.7 --- llvm/lib/Target/X86/X86.h:1.6 Sun Nov 17 23:37:11 2002 +++ llvm/lib/Target/X86/X86.h Mon Dec 2 23:42:53 2002 @@ -52,7 +52,7 @@ // This defines a large number of symbolic names for X86 instruction opcodes. enum Opcode { -#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS) ENUM, +#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPDEFS, IMPUSES) ENUM, #include "X86InstrInfo.def" }; } Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.9 llvm/lib/Target/X86/X86InstrInfo.cpp:1.10 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.9 Fri Nov 22 16:42:50 2002 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Mon Dec 2 23:42:53 2002 @@ -5,18 +5,24 @@ //===----------------------------------------------------------------------===// #include "X86InstrInfo.h" +#include "X86.h" #include "llvm/CodeGen/MachineInstr.h" -#include + +#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPDEFS, IMPUSES) +#define IMPREGSLIST(NAME, ...) \ + static const unsigned NAME[] = { __VA_ARGS__ }; +#include "X86InstrInfo.def" + // X86Insts - Turn the InstrInfo.def file into a bunch of instruction // descriptors // static const MachineInstrDescriptor X86Insts[] = { -#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS) \ +#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPDEFS, IMPUSES) \ { NAME, \ -1, /* Always vararg */ \ ((TSFLAGS) & X86II::Void) ? -1 : 0, /* Result is in 0 */ \ - 0, false, 0, 0, TSFLAGS, FLAGS, TSFLAGS }, + 0, false, 0, 0, TSFLAGS, FLAGS, TSFLAGS, IMPDEFS, IMPUSES }, #include "X86InstrInfo.def" }; @@ -26,7 +32,7 @@ static unsigned char BaseOpcodes[] = { -#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS) BASEOPCODE, +#define I(ENUM, NAME, BASEOPCODE, FLAGS, TSFLAGS, IMPDEFS, IMPUSES) BASEOPCODE, #include "X86InstrInfo.def" }; Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.29 llvm/lib/Target/X86/X86InstrInfo.def:1.30 --- llvm/lib/Target/X86/X86InstrInfo.def:1.29 Sun Dec 1 17:25:59 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Mon Dec 2 23:42:53 2002 @@ -17,6 +17,27 @@ #errror "Must define I macro before including X86/X86InstructionInfo.def!" #endif +// Macro to handle the implicit register uses lists... +#ifndef IMPREGSLIST +#define IMPREGSLIST(NAME, ...) +#endif + +// Implicit register usage info: O_ is for one register, T_ is for two registers +IMPREGSLIST(NoImpRegs, 0) +IMPREGSLIST(O_AL , X86::AL , 0) +IMPREGSLIST(O_AH , X86::AH , 0) +IMPREGSLIST(O_CL , X86::CL , 0) +IMPREGSLIST(O_AX , X86::AX , 0) +IMPREGSLIST(O_DX , X86::DX , 0) +IMPREGSLIST(O_EAX , X86::EAX, 0) +IMPREGSLIST(O_EDX , X86::EDX, 0) +IMPREGSLIST(O_EBP , X86::EBP, 0) +IMPREGSLIST(T_AXDX , X86::AX , X86::DX , 0) +IMPREGSLIST(T_EAXEDX , X86::EAX, X86::EDX, 0) + +#undef IMPREGSLIST + + // Arguments to be passed into the I macro // #1: Enum name - This ends up being the opcode symbol in the X86 namespace // #2: Opcode name, as used by the gnu assembler @@ -26,137 +47,139 @@ // #5: Target Specific Flags - Another bitfield containing X86 specific flags // that we are interested in for each instruction. These should be flags // defined in X86InstrInfo.h in the X86II namespace. +// #6: Name of the implicit register uses list +// #7: Name of the implicit register definitions list // // The first instruction must always be the PHI instruction: -I(PHI , "phi", 0, 0, 0) +I(PHI , "phi", 0, 0, 0, NoImpRegs, NoImpRegs) // 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, NoImpRegs, NoImpRegs) // nop // Flow control instructions -I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void) // ret -I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::RawFrm | X86II::Void) // jmp foo -I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void) -I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void) -I(CALLpcrel32 , "call", 0xE8, M_BRANCH_FLAG, X86II::Void) +I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // ret +I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // jmp foo +I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void, NoImpRegs, NoImpRegs) +I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void, NoImpRegs, NoImpRegs) +I(CALLpcrel32 , "call", 0xE8, M_BRANCH_FLAG, X86II::Void, NoImpRegs, NoImpRegs) // Misc instructions -I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm) // leave +I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm, O_EBP, O_EBP) // leave // Move instructions -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 -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 +I(MOVrr8 , "movb", 0x88, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 = R8 +I(MOVrr16 , "movw", 0x89, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 = R16 +I(MOVrr32 , "movl", 0x89, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 = R32 +I(MOVir8 , "movb", 0xB0, 0, X86II::AddRegFrm, NoImpRegs, NoImpRegs) // R8 = imm8 +I(MOVir16 , "movw", 0xB8, 0, X86II::AddRegFrm | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 = imm16 +I(MOVir32 , "movl", 0xB8, 0, X86II::AddRegFrm, NoImpRegs, NoImpRegs) // R32 = imm32 +I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem, NoImpRegs, NoImpRegs) // R8 = [mem] +I(MOVmr16 , "movw", 0x8B, 0, X86II::MRMSrcMem | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 = [mem] +I(MOVmr32 , "movl", 0x8B, 0, X86II::MRMSrcMem, NoImpRegs, NoImpRegs) // R32 = [mem] +I(MOVrm8 , "movb", 0x88, 0, X86II::MRMDestMem | X86II::Void, NoImpRegs, NoImpRegs) // [mem] = R8 +I(MOVrm16 , "movw", 0x89, 0, X86II::MRMDestMem | X86II::Void | // [mem] = R16 + X86II::OpSize, NoImpRegs, NoImpRegs) +I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void, NoImpRegs, NoImpRegs) // [mem] = R32 -I(PUSHr32 , "pushl", 0x50, 0, X86II::AddRegFrm | X86II::Void) +I(PUSHr32 , "pushl", 0x50, 0, X86II::AddRegFrm | X86II::Void, NoImpRegs, NoImpRegs) // Arithmetic instructions -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::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 +I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 += R8 +I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 += R16 +I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 += R32 +I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 -= R8 +I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 -= R16 +I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 -= R32 +I(MULrr8 , "mulb", 0xF6, 0, X86II::MRMS4r | X86II::Void, O_AL, O_AX) // AX = AL*R8 +I(MULrr16 , "mulw", 0xF7, 0, X86II::MRMS4r | X86II::Void | // DX:AX= AX*R16 + X86II::OpSize, O_AX, T_AXDX) +I(MULrr32 , "mull", 0xF7, 0, X86II::MRMS4r | X86II::Void, O_EAX, T_EAXEDX) // ED:EA= EA*R32 // unsigned division/remainder -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 +I(DIVrr8 , "divb", 0xF6, 0, X86II::MRMS6r | X86II::Void, O_AX, O_AX) // AX/r8= AL&AH +I(DIVrr16 , "divw", 0xF7, 0, X86II::MRMS6r | X86II::Void | // EDXEAX/r16=AX&DX + X86II::OpSize, T_AXDX, T_AXDX) +I(DIVrr32 , "divl", 0xF7, 0, X86II::MRMS6r | X86II::Void, T_EAXEDX, T_EAXEDX) // EDXEAX/r32=EAX&EDX // signed division/remainder -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 +I(IDIVrr8 , "idivb", 0xF6, 0, X86II::MRMS7r | X86II::Void, O_AX, O_AX) // AX/r8= AL&AH +I(IDIVrr16 , "idivw", 0xF7, 0, X86II::MRMS7r | X86II::Void | // DA/r16=AX&DX + X86II::OpSize, T_AXDX, T_AXDX) +I(IDIVrr32 , "idivl", 0xF7, 0, X86II::MRMS7r | X86II::Void, T_EAXEDX, T_EAXEDX) // DA/r32=EAX&DX // Logical operators -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 +I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 &= R8 +I(ANDrr16 , "andw", 0x21, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 &= R16 +I(ANDrr32 , "andl", 0x21, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 &= R32 +I(ORrr8 , "orb", 0x08, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 |= R8 +I(ORrr16 , "orw", 0x09, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 |= R16 +I(ORrr32 , "orl", 0x09, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 |= R32 +I(XORrr8 , "xorb", 0x30, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 ^= R8 +I(XORrr16 , "xorw", 0x31, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 ^= R16 +I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 ^= R32 // Shift instructions -I(SHLrr8 , "shlb", 0xD2, 0, X86II::MRMS4r) // R8 <<= cl D2/4 -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 +I(SHLrr8 , "shlb", 0xD2, 0, X86II::MRMS4r, O_CL, NoImpRegs) // R8 <<= cl D2/4 +I(SHLrr16 , "shlw", 0xD3, 0, X86II::MRMS4r | X86II::OpSize, O_CL, NoImpRegs) // R16 <<= cl D3/4 +I(SHLrr32 , "shll", 0xD3, 0, X86II::MRMS4r, O_CL, NoImpRegs) // R32 <<= cl D3/4 +I(SHLir8 , "shlb", 0xC0, 0, X86II::MRMS4r, NoImpRegs, NoImpRegs) // R8 <<= imm8 C0/4 ib +I(SHLir16 , "shlw", 0xC1, 0, X86II::MRMS4r | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 <<= imm8 C1/4 ib +I(SHLir32 , "shll", 0xC1, 0, X86II::MRMS4r, NoImpRegs, NoImpRegs) // R32 <<= imm8 C1/4 ib +I(SHRrr8 , "shrb", 0xD2, 0, X86II::MRMS5r, O_CL, NoImpRegs) // R8 >>>= cl D2/5 +I(SHRrr16 , "shrw", 0xD3, 0, X86II::MRMS5r | X86II::OpSize, O_CL, NoImpRegs) // R16 >>>= cl D3/5 +I(SHRrr32 , "shrl", 0xD3, 0, X86II::MRMS5r, O_CL, NoImpRegs) // R32 >>>= cl D3/5 +I(SHRir8 , "shrb", 0xC0, 0, X86II::MRMS5r, NoImpRegs, NoImpRegs) // R8 >>>= imm8 C0/5 ib +I(SHRir16 , "shrw", 0xC1, 0, X86II::MRMS5r | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 >>>= imm8 C1/5 ib +I(SHRir32 , "shrl", 0xC1, 0, X86II::MRMS5r, NoImpRegs, NoImpRegs) // R32 >>>= imm8 C1/5 ib +I(SARrr8 , "sarb", 0xD2, 0, X86II::MRMS7r, O_CL, NoImpRegs) // R8 >>= cl D2/7 +I(SARrr16 , "sarw", 0xD3, 0, X86II::MRMS7r | X86II::OpSize, O_CL, NoImpRegs) // R16 >>= cl D3/7 +I(SARrr32 , "sarl", 0xD3, 0, X86II::MRMS7r, O_CL, NoImpRegs) // R32 >>= cl D3/7 +I(SARir8 , "sarb", 0xC0, 0, X86II::MRMS7r, NoImpRegs, NoImpRegs) // R8 >>= imm8 C0/7 ib +I(SARir16 , "sarw", 0xC1, 0, X86II::MRMS7r | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 >>= imm8 C1/7 ib +I(SARir32 , "sarl", 0xC1, 0, X86II::MRMS7r, NoImpRegs, NoImpRegs) // R32 >>= imm8 C1/7 ib // Floating point loads -I(FLDr4 , "flds", 0xD9, 0, X86II::MRMS0m) // push float D9/0 -I(FLDr8 , "fldl ", 0xDD, 0, X86II::MRMS0m) // push double DD/0 +I(FLDr4 , "flds", 0xD9, 0, X86II::MRMS0m, NoImpRegs, NoImpRegs) // push float D9/0 +I(FLDr8 , "fldl ", 0xDD, 0, X86II::MRMS0m, NoImpRegs, NoImpRegs) // 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, NoImpRegs, NoImpRegs) // 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, NoImpRegs, O_AX) // AX = fp flags DF E0 // Condition code ops, incl. set if equal/not equal/... -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 +I(SAHF , "sahf", 0x9E, 0, X86II::RawFrm, O_AH, NoImpRegs) // flags = AH +I(SETBr , "setb", 0x92, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = < unsign +I(SETAEr , "setae", 0x93, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = >=unsign +I(SETEr , "sete", 0x94, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = == +I(SETNEr , "setne", 0x95, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = != +I(SETBEr , "setbe", 0x96, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = <=unsign +I(SETAr , "seta", 0x97, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = > unsign +I(SETLr , "setl", 0x9C, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = < signed +I(SETGEr , "setge", 0x9D, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = >=signed +I(SETLEr , "setle", 0x9E, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = <=signed +I(SETGr , "setg", 0x9F, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = > signed // Integer comparisons -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, X86II::MRMS7r) // compare R8, imm8 +I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // compare R8,R8 +I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // compare R16,R16 +I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // compare R32,R32 +I(CMPri8 , "cmp", 0x80, 0, X86II::MRMS7r, NoImpRegs, NoImpRegs) // 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) -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(CBW , "cbw", 0x98, 0, X86II::RawFrm, O_AL, O_AX) // AX = signext(AL) +I(CWD , "cwd", 0x99, 0, X86II::RawFrm, O_AX, O_DX) // DX:AX = signext(AX) +I(CDQ , "cdq", 0x99, 0, X86II::RawFrm, O_EAX, O_EDX) // EDX:EAX = signext(EAX) +I(MOVSXr16r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB | // R16 = signext(R8) + X86II::OpSize, NoImpRegs, NoImpRegs) +I(MOVSXr32r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB, NoImpRegs, NoImpRegs) // R32 = signext(R8) +I(MOVSXr32r16 , "movsx", 0xBF, 0, X86II::MRMSrcReg | X86II::TB, NoImpRegs, NoImpRegs) // 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) + X86II::OpSize, NoImpRegs, NoImpRegs) +I(MOVZXr32r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB, NoImpRegs, NoImpRegs) // R32 = zeroext(R8) +I(MOVZXr32r16 , "movzx", 0xB7, 0, X86II::MRMSrcReg | X86II::TB, NoImpRegs, NoImpRegs) // R32 = zeroext(R16) // At this point, I is dead, so undefine the macro #undef I From lattner at cs.uiuc.edu Tue Dec 3 00:01:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 00:01:00 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Makefile Message-ID: <200212030600.AAA20132@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Makefile updated: 1.3 -> 1.4 --- Log message: Don't delete temporary files --- Diffs of the changes: Index: llvm/utils/TableGen/Makefile diff -u llvm/utils/TableGen/Makefile:1.3 llvm/utils/TableGen/Makefile:1.4 --- llvm/utils/TableGen/Makefile:1.3 Mon Dec 2 10:31:46 2002 +++ llvm/utils/TableGen/Makefile Tue Dec 3 00:00:11 2002 @@ -2,6 +2,8 @@ TOOLNAME = tblgen USEDLIBS = support.a +.PRECIOUS: FileLexer.cpp FileParser.cpp + include $(LEVEL)/Makefile.common clean:: From lattner at cs.uiuc.edu Tue Dec 3 00:01:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 00:01:02 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Record.h Message-ID: <200212030600.AAA20166@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.4 -> 1.5 Record.h updated: 1.6 -> 1.7 --- Log message: Continue implementing field initializers --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.4 llvm/utils/TableGen/Record.cpp:1.5 --- llvm/utils/TableGen/Record.cpp:1.4 Mon Dec 2 11:53:54 2002 +++ llvm/utils/TableGen/Record.cpp Tue Dec 3 00:00:33 2002 @@ -82,25 +82,6 @@ return 0; } -#if 0 -Init *BitsRecTy::convertValue(FieldInit *VI) { - if (BitsRecTy *BRT = dynamic_cast(VI->getType())) - if (BRT->Size == Size) { - BitsInit *Ret = new BitsInit(Size); - for (unsigned i = 0; i != Size; ++i) - Ret->setBit(i, new VarBitInit(VI, i)); - return Ret; - } - if (Size == 1 && dynamic_cast(VI->getType())) { - BitsInit *Ret = new BitsInit(1); - Ret->setBit(0, VI); - return Ret; - } - return 0; -} -#endif - - Init *IntRecTy::convertValue(BitsInit *BI) { int Result = 0; for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) @@ -168,8 +149,8 @@ void BitsInit::print(std::ostream &OS) const { //if (!printInHex(OS)) return; - if (!printAsVariable(OS)) return; - if (!printAsUnset(OS)) return; + //if (!printAsVariable(OS)) return; + //if (!printAsUnset(OS)) return; OS << "{ "; for (unsigned i = 0, e = getNumBits(); i != e; ++i) { @@ -282,13 +263,6 @@ return BI; } -RecTy *VarInit::getFieldType(const std::string &FieldName) const { - if (RecordRecTy *RTy = dynamic_cast(getType())) - if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName)) - return RV->getType(); - return 0; -} - Init *VarInit::resolveBitReference(Record &R, unsigned Bit) { if (R.isTemplateArg(getName())) return this; @@ -306,16 +280,43 @@ return this; } +RecTy *VarInit::getFieldType(const std::string &FieldName) const { + if (RecordRecTy *RTy = dynamic_cast(getType())) + if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName)) + return RV->getType(); + return 0; +} + +Init *VarInit::getFieldInit(Record &R, const std::string &FieldName) const { + if (RecordRecTy *RTy = dynamic_cast(getType())) + if (const RecordVal *RV = R.getValue(VarName)) + if (Init *I = RV->getValue()->getFieldInit(R, FieldName)) + return I; + else + return (Init*)this; + return 0; +} + Init *VarBitInit::resolveReferences(Record &R) { Init *I = getVariable()->resolveBitReference(R, getBitNum()); - if (I != getVariable()) return I; return this; } +RecTy *DefInit::getFieldType(const std::string &FieldName) const { + if (const RecordVal *RV = Def->getValue(FieldName)) + return RV->getType(); + return 0; +} + +Init *DefInit::getFieldInit(Record &R, const std::string &FieldName) const { + return Def->getValue(FieldName)->getValue(); +} + + void DefInit::print(std::ostream &OS) const { OS << Def->getName(); } @@ -337,7 +338,16 @@ } Init *FieldInit::resolveBitReference(Record &R, unsigned Bit) { - // Can never be resolved yet. + Init *BitsVal = Rec->getFieldInit(R, FieldName); + assert(BitsVal && "No initializer found!"); + + if (BitsInit *BI = dynamic_cast(BitsVal)) { + assert(Bit < BI->getNumBits() && "Bit reference out of range!"); + Init *B = BI->getBit(Bit); + + if (dynamic_cast(B)) // If the bit is set... + return B; // Replace the VarBitInit with it. + } return this; } Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.6 llvm/utils/TableGen/Record.h:1.7 --- llvm/utils/TableGen/Record.h:1.6 Mon Dec 2 11:53:54 2002 +++ llvm/utils/TableGen/Record.h Tue Dec 3 00:00:33 2002 @@ -180,6 +180,14 @@ /// virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; } + /// getFieldInit - This method complements getFieldType to return the + /// initializer for the specified field. If getFieldType returns non-null + /// this method should return non-null, otherwise it returns null. + /// + virtual Init *getFieldInit(Record &R, const std::string &FieldName) const { + return 0; + } + /// resolveReferences - This method is used by classes that refer to other /// variables which may not be defined at the time they expression is formed. /// If a value is set for the variable later, this method will be called on @@ -352,6 +360,7 @@ virtual Init *resolveBitReference(Record &R, unsigned Bit); virtual RecTy *getFieldType(const std::string &FieldName) const; + virtual Init *getFieldInit(Record &R, const std::string &FieldName) const; virtual void print(std::ostream &OS) const { OS << VarName; } }; @@ -397,6 +406,9 @@ Record *getDef() const { return Def; } //virtual Init *convertInitializerBitRange(const std::vector &Bits); + + virtual RecTy *getFieldType(const std::string &FieldName) const; + virtual Init *getFieldInit(Record &R, const std::string &FieldName) const; virtual void print(std::ostream &OS) const; }; From lattner at cs.uiuc.edu Tue Dec 3 00:10:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 00:10:02 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/jello.cpp Message-ID: <200212030609.AAA20375@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: jello.cpp updated: 1.5 -> 1.6 --- Log message: Implement trivially simple debugger for MachineCodeEmitter interface --- Diffs of the changes: Index: llvm/tools/jello/jello.cpp diff -u llvm/tools/jello/jello.cpp:1.5 llvm/tools/jello/jello.cpp:1.6 --- llvm/tools/jello/jello.cpp:1.5 Mon Dec 2 15:22:04 2002 +++ llvm/tools/jello/jello.cpp Tue Dec 3 00:09:26 2002 @@ -18,10 +18,23 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" - +#include "llvm/CodeGen/MachineFunction.h" struct JelloMachineCodeEmitter : public MachineCodeEmitter { + void startFunction(MachineFunction &F) { + std::cout << "\n**** Writing machine code for function: " + << F.getFunction()->getName() << "\n"; + } + void startBasicBlock(MachineBasicBlock &BB) { + std::cout << "\n--- Basic Block: " << BB.getBasicBlock()->getName() << "\n"; + } + void emitByte(unsigned char B) { + std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " "; + } + void emitPCRelativeDisp(Value *V) { + std::cout << "<" << V->getName() << ": 0x00 0x00 0x00 0x00> "; + } }; From lattner at cs.uiuc.edu Tue Dec 3 00:34:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 00:34:01 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/jello.cpp Message-ID: <200212030633.AAA20849@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: jello.cpp updated: 1.6 -> 1.7 --- Log message: Final tweak to printer --- Diffs of the changes: Index: llvm/tools/jello/jello.cpp diff -u llvm/tools/jello/jello.cpp:1.6 llvm/tools/jello/jello.cpp:1.7 --- llvm/tools/jello/jello.cpp:1.6 Tue Dec 3 00:09:26 2002 +++ llvm/tools/jello/jello.cpp Tue Dec 3 00:33:30 2002 @@ -24,7 +24,9 @@ std::cout << "\n**** Writing machine code for function: " << F.getFunction()->getName() << "\n"; } - + void finishFunction(MachineFunction &F) { + std::cout << "\n"; + } void startBasicBlock(MachineBasicBlock &BB) { std::cout << "\n--- Basic Block: " << BB.getBasicBlock()->getName() << "\n"; } From lattner at cs.uiuc.edu Tue Dec 3 00:35:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 00:35:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/MachineCodeEmitter.cpp Printer.cpp Message-ID: <200212030634.AAA20904@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: MachineCodeEmitter.cpp updated: 1.3 -> 1.4 Printer.cpp updated: 1.19 -> 1.20 --- Log message: Split the machine code emitter completely out of the printer --- Diffs of the changes: Index: llvm/lib/Target/X86/MachineCodeEmitter.cpp diff -u llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.3 llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.4 --- llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.3 Mon Dec 2 15:56:18 2002 +++ llvm/lib/Target/X86/MachineCodeEmitter.cpp Tue Dec 3 00:34:06 2002 @@ -6,24 +6,35 @@ //===----------------------------------------------------------------------===// #include "X86TargetMachine.h" +#include "X86.h" #include "llvm/PassManager.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" namespace { - struct Emitter : public FunctionPass { + class Emitter : public FunctionPass { X86TargetMachine &TM; const X86InstrInfo &II; MachineCodeEmitter &MCE; + public: Emitter(X86TargetMachine &tm, MachineCodeEmitter &mce) : TM(tm), II(TM.getInstrInfo()), MCE(mce) {} bool runOnFunction(Function &F); + private: void emitBasicBlock(MachineBasicBlock &MBB); void emitInstruction(MachineInstr &MI); + + void emitRegModRMByte(unsigned ModRMReg, unsigned RegOpcodeField); + void emitSIBByte(unsigned SS, unsigned Index, unsigned Base); + void emitConstant(unsigned Val, unsigned Size); + + void emitMemModRMByte(const MachineInstr &MI, + unsigned Op, unsigned RegOpcodeField); + }; } @@ -56,6 +67,141 @@ emitInstruction(**I); } + +namespace N86 { // Native X86 Register numbers... + enum { + EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7 + }; +} + + +// 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 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!"); + assert(0 && "Register allocator hasn't allocated reg correctly yet!"); + 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); +} + +void Emitter::emitRegModRMByte(unsigned ModRMReg, unsigned RegOpcodeFld){ + MCE.emitByte(ModRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg))); +} + +void Emitter::emitSIBByte(unsigned SS, unsigned Index, unsigned Base) { + // SIB byte is in the same format as the ModRMByte... + MCE.emitByte(ModRMByte(SS, Index, Base)); +} + +void Emitter::emitConstant(unsigned Val, unsigned Size) { + // Output the constant in little endian byte order... + for (unsigned i = 0; i != Size; ++i) { + MCE.emitByte(Val & 255); + Val >>= 8; + } +} + +static bool isDisp8(int Value) { + return Value == (signed char)Value; +} + +void Emitter::emitMemModRMByte(const MachineInstr &MI, + unsigned Op, unsigned RegOpcodeField) { + 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 + MCE.emitByte(ModRMByte(0, RegOpcodeField, 5)); + emitConstant(Disp.getImmedValue(), 4); + } else { + unsigned BaseRegNo = getX86RegNum(BaseReg.getReg()); + if (Disp.getImmedValue() == 0 && BaseRegNo != N86::EBP) { + // Emit simple indirect register encoding... [EAX] f.e. + MCE.emitByte(ModRMByte(0, RegOpcodeField, BaseRegNo)); + } else if (isDisp8(Disp.getImmedValue())) { + // Emit the disp8 encoding... [REG+disp8] + MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo)); + emitConstant(Disp.getImmedValue(), 1); + } else { + // Emit the most general non-SIB encoding: [REG+disp32] + MCE.emitByte(ModRMByte(1, RegOpcodeField, BaseRegNo)); + emitConstant(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. + MCE.emitByte(ModRMByte(0, RegOpcodeField, 4)); + ForceDisp32 = true; + } else if (Disp.getImmedValue() == 0) { + // Emit no displacement ModR/M byte + MCE.emitByte(ModRMByte(0, RegOpcodeField, 4)); + } else if (isDisp8(Disp.getImmedValue())) { + // Emit the disp8 encoding... + MCE.emitByte(ModRMByte(1, RegOpcodeField, 4)); + } else { + // Emit the normal disp32 encoding... + MCE.emitByte(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(SS, getX86RegNum(IndexReg.getReg()), 5); + } else { + unsigned BaseRegNo = getX86RegNum(BaseReg.getReg()); + unsigned IndexRegNo = getX86RegNum(IndexReg.getReg()); + emitSIBByte(SS, IndexRegNo, BaseRegNo); + } + + // Do we need to output a displacement? + if (Disp.getImmedValue() != 0 || ForceDisp32) { + if (!ForceDisp32 && isDisp8(Disp.getImmedValue())) + emitConstant(Disp.getImmedValue(), 1); + else + emitConstant(Disp.getImmedValue(), 4); + } + } +} + +static bool isImmediate(const MachineOperand &MO) { + return MO.getType() == MachineOperand::MO_SignExtendedImmed || + MO.getType() == MachineOperand::MO_UnextendedImmed; +} + void Emitter::emitInstruction(MachineInstr &MI) { unsigned Opcode = MI.getOpcode(); const MachineInstrDescriptor &Desc = II.get(Opcode); @@ -64,15 +210,57 @@ if (Desc.TSFlags & X86II::OpSize) MCE.emitByte(0x66);// Operand size... if (Desc.TSFlags & X86II::TB) MCE.emitByte(0x0F);// Two-byte opcode prefix + unsigned char BaseOpcode = II.getBaseOpcodeFor(Opcode); switch (Desc.TSFlags & X86II::FormMask) { case X86II::RawFrm: - MCE.emitByte(II.getBaseOpcodeFor(Opcode)); + MCE.emitByte(BaseOpcode); if (MI.getNumOperands() == 1) { assert(MI.getOperand(0).getType() == MachineOperand::MO_PCRelativeDisp); MCE.emitPCRelativeDisp(MI.getOperand(0).getVRegValue()); } + break; + case X86II::AddRegFrm: + MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg())); + if (MI.getNumOperands() == 2) { + unsigned Size = 4; + emitConstant(MI.getOperand(1).getImmedValue(), Size); + } + break; + case X86II::MRMDestReg: + MCE.emitByte(BaseOpcode); + emitRegModRMByte(MI.getOperand(0).getReg(), + getX86RegNum(MI.getOperand(MI.getNumOperands()-1).getReg())); + break; + case X86II::MRMDestMem: + MCE.emitByte(BaseOpcode); + emitMemModRMByte(MI, 0, getX86RegNum(MI.getOperand(4).getReg())); + break; + case X86II::MRMSrcReg: + MCE.emitByte(BaseOpcode); + emitRegModRMByte(MI.getOperand(MI.getNumOperands()-1).getReg(), + getX86RegNum(MI.getOperand(0).getReg())); + break; + case X86II::MRMSrcMem: + MCE.emitByte(BaseOpcode); + emitMemModRMByte(MI, MI.getNumOperands()-4, + getX86RegNum(MI.getOperand(0).getReg())); + break; + case X86II::MRMS0r: case X86II::MRMS1r: + case X86II::MRMS2r: case X86II::MRMS3r: + case X86II::MRMS4r: case X86II::MRMS5r: + case X86II::MRMS6r: case X86II::MRMS7r: + MCE.emitByte(BaseOpcode); + emitRegModRMByte(MI.getOperand(0).getReg(), + (Desc.TSFlags & X86II::FormMask)-X86II::MRMS0r); + + if (isImmediate(MI.getOperand(MI.getNumOperands()-1))) { + unsigned Size = 4; + emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), Size); + } break; + + } } Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.19 llvm/lib/Target/X86/Printer.cpp:1.20 --- llvm/lib/Target/X86/Printer.cpp:1.19 Mon Dec 2 15:40:46 2002 +++ llvm/lib/Target/X86/Printer.cpp Tue Dec 3 00:34:06 2002 @@ -108,7 +108,7 @@ O << (int)MO.getImmedValue(); return; case MachineOperand::MO_PCRelativeDisp: - O << "< " << MO.getVRegValue()->getName() << ">"; + O << "<" << MO.getVRegValue()->getName() << ">"; return; default: O << ""; return; @@ -145,164 +145,12 @@ O << "]"; } -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; -} - -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; -} - -namespace N86 { // Native X86 Register numbers... - enum { - EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7 - }; -} - - -// 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 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!"); - 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 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); - } - } -} - - // 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); - // 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::RawFrm: // The accepted forms of Raw instructions are: @@ -312,14 +160,6 @@ assert(MI->getNumOperands() == 0 || (MI->getNumOperands() == 1 && isPCRelativeDisp(MI->getOperand(0))) && "Illegal raw instruction!"); - toHex(O, getBaseOpcodeFor(Opcode)) << " "; - - if (MI->getNumOperands() == 1) { - Value *V = MI->getOperand(0).getVRegValue(); - emitConstant(O, 0, 4); - } - - O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; if (MI->getNumOperands() == 1) { @@ -340,14 +180,7 @@ "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) { @@ -377,12 +210,6 @@ MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) O << "**"; - toHex(O, getBaseOpcodeFor(Opcode)) << " "; - unsigned ModRMReg = MI->getOperand(0).getReg(); - unsigned ExtraReg = MI->getOperand(MI->getNumOperands()-1).getReg(); - emitRegModRMByte(O, ModRMReg, getX86RegNum(ExtraReg)); - - O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; printOp(O, MI->getOperand(0), RI); O << ", "; @@ -397,10 +224,7 @@ // 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 << ", "; @@ -428,12 +252,6 @@ 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(); - emitRegModRMByte(O, ModRMReg, getX86RegNum(ExtraReg)); - - O << "\n\t\t\t\t"; O << getName(MI->getOpCode()) << " "; printOp(O, MI->getOperand(0), RI); O << ", "; @@ -455,11 +273,6 @@ 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 "; @@ -491,17 +304,6 @@ 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 (isImmediate(MI->getOperand(MI->getNumOperands()-1))) { - unsigned Size = 4; - 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 (isImmediate(MI->getOperand(MI->getNumOperands()-1))) { From lattner at cs.uiuc.edu Tue Dec 3 01:37:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 01:37:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212030736.BAA31048@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.42 -> 1.43 --- Log message: brg Add support for cast ... to bool in visitCastInst (it's a start, anyways...) --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.42 llvm/lib/Target/X86/InstSelectSimple.cpp:1.43 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.42 Mon Dec 2 18:51:09 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Dec 3 01:36:03 2002 @@ -641,9 +641,20 @@ //the former is that the register allocator could use any register it wants, //but for now this obviously doesn't matter. :) -// if target type is bool -// Emit Compare -// Emit Set-if-not-zero + Type *targetType = CI.getType (); + Value *operand = CI.getOperand (0); + unsigned int operandReg = getReg (operand); + Type *sourceType = operand->getType (); + unsigned int destReg = getReg (CI); + + // cast to bool: + if (targetType == Type::BoolTy) { + // Emit Compare + BuildMI (BB, X86::CMPri8, 2).addReg (operandReg).addZImm (0); + // Emit Set-if-not-zero + BuildMI (BB, X86::SETNEr, 1, destReg); + return; + } // if size of target type == size of source type // Emit Mov reg(target) <- reg(source) From lattner at cs.uiuc.edu Tue Dec 3 12:17:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 12:17:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212031816.MAA23013@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.43 -> 1.44 --- Log message: Fix the build --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.43 llvm/lib/Target/X86/InstSelectSimple.cpp:1.44 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.43 Tue Dec 3 01:36:03 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Dec 3 12:15:59 2002 @@ -641,10 +641,10 @@ //the former is that the register allocator could use any register it wants, //but for now this obviously doesn't matter. :) - Type *targetType = CI.getType (); + const Type *targetType = CI.getType (); Value *operand = CI.getOperand (0); unsigned int operandReg = getReg (operand); - Type *sourceType = operand->getType (); + const Type *sourceType = operand->getType (); unsigned int destReg = getReg (CI); // cast to bool: From lattner at cs.uiuc.edu Tue Dec 3 12:33:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 12:33:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Linker.cpp Message-ID: <200212031832.MAA24015@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Linker.cpp updated: 1.34 -> 1.35 --- Log message: Fix big bug introduced with symbol table changes --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/Linker.cpp diff -u llvm/lib/Transforms/Utils/Linker.cpp:1.34 llvm/lib/Transforms/Utils/Linker.cpp:1.35 --- llvm/lib/Transforms/Utils/Linker.cpp:1.34 Wed Nov 20 12:34:39 2002 +++ llvm/lib/Transforms/Utils/Linker.cpp Tue Dec 3 12:32:30 2002 @@ -173,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 = (SymbolTable*)&Src->getSymbolTable(); + SymbolTable *ST = (SymbolTable*)&Dest->getSymbolTable(); // Loop over all of the globals in the src module, mapping them over as we go // @@ -263,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 = (SymbolTable*)&Src->getSymbolTable(); + SymbolTable *ST = (SymbolTable*)&Dest->getSymbolTable(); // Loop over all of the functions in the src module, mapping them over as we // go From lattner at cs.uiuc.edu Tue Dec 3 13:41:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 13:41:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/InstCount.cpp Message-ID: <200212031940.NAA28093@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: InstCount.cpp updated: 1.2 -> 1.3 --- Log message: Simplify code --- Diffs of the changes: Index: llvm/lib/Analysis/InstCount.cpp diff -u llvm/lib/Analysis/InstCount.cpp:1.2 llvm/lib/Analysis/InstCount.cpp:1.3 --- llvm/lib/Analysis/InstCount.cpp:1.2 Sun Nov 17 16:15:40 2002 +++ llvm/lib/Analysis/InstCount.cpp Tue Dec 3 13:40:16 2002 @@ -2,88 +2,28 @@ // // This pass collects the count of all instructions and reports them // -// //===----------------------------------------------------------------------===// #include "llvm/Pass.h" #include "llvm/Module.h" -#include "llvm/iMemory.h" -#include "llvm/iTerminators.h" -#include "llvm/iPHINode.h" -#include "llvm/iOther.h" -#include "llvm/iOperators.h" #include "llvm/Support/InstVisitor.h" -#include "llvm/Support/InstIterator.h" -#include "llvm/Support/InstIterator.h" #include "Support/Statistic.h" -#include namespace { - static Statistic<> NumReturnInst("instcount","Number of ReturnInsts"); - static Statistic<> NumBranchInst("instcount", "Number of BranchInsts"); - static Statistic<> NumPHINode("instcount", "Number of PHINodes"); - static Statistic<> NumCastInst("instcount", "Number of CastInsts"); - static Statistic<> NumCallInst("instcount", "Number of CallInsts"); - static Statistic<> NumMallocInst("instcount", "Number of MallocInsts"); - static Statistic<> NumAllocaInst("instcount", "Number of AllocaInsts"); - static Statistic<> NumFreeInst("instcount", "Number of FreeInsts"); - static Statistic<> NumLoadInst("instcount", "Number of LoadInsts"); - static Statistic<> NumStoreInst("instcount", "Number of StoreInsts"); - static Statistic<> NumGetElementPtrInst("instcount", - "Number of GetElementPtrInsts"); - - static Statistic<> NumSwitchInst("instcount", "Number of SwitchInsts"); - static Statistic<> NumInvokeInst("instcount", "Number of InvokeInsts"); - static Statistic<> NumBinaryOperator("instcount", - "Total Number of BinaryOperators"); - - static Statistic<> NumShiftInst("instcount", " Total Number of ShiftInsts"); - static Statistic<> NumShlInst("instcount", "Number of Left ShiftInsts"); - - static Statistic<> NumShrInst("instcount", "Number of Right ShiftInsts"); - - - static Statistic<> NumAddInst("instcount", "Number of AddInsts"); - static Statistic<> NumSubInst("instcount", "Number of SubInsts"); - static Statistic<> NumMulInst("instcount", "Number of MulInsts"); - static Statistic<> NumDivInst("instcount", "Number of DivInsts"); - static Statistic<> NumRemInst("instcount", "Number of RemInsts"); - static Statistic<> NumAndInst("instcount", "Number of AndInsts"); - static Statistic<> NumOrInst("instcount", "Number of OrInsts"); - static Statistic<> NumXorInst("instcount", "Number of XorInsts"); - static Statistic<> NumSetCondInst("instcount", "Total Number of SetCondInsts"); - static Statistic<> NumSetEQInst("instcount", "Number of SetEQInsts"); - static Statistic<> NumSetNEInst("instcount", "Number of SetNEInsts"); - static Statistic<> NumSetLEInst("instcount", "Number of SetLEInsts"); - static Statistic<> NumSetGEInst("instcount", "Number of SetGEInsts"); - static Statistic<> NumSetLTInst("instcount", "Number of SetLTInsts"); - static Statistic<> NumSetGTInst("instcount", "Number of SetGTInsts"); - +#define HANDLE_INST(N, OPCODE, CLASS) \ + Statistic<> Num##OPCODE##Inst("instcount", "Number of " #OPCODE " insts"); + +#include "llvm/Instruction.def" + class InstCount : public Pass, public InstVisitor { - private: - friend class InstVisitor; + friend class InstVisitor; +#define HANDLE_INST(N, OPCODE, CLASS) \ + void visit##OPCODE(CLASS &) { Num##OPCODE##Inst++; } - void visitBinaryOperator(BinaryOperator &I); - void visitShiftInst(ShiftInst &I); - void visitSetCondInst(SetCondInst &I); - - inline void visitSwitchInst(SwitchInst &I) { NumSwitchInst++; } - inline void visitInvokeInst(InvokeInst &I) { NumInvokeInst++; } - inline void visitReturnInst(ReturnInst &I) { NumReturnInst++; } - inline void visitBranchInst(BranchInst &I) { NumBranchInst++; } - inline void visitPHINode(PHINode &I) { NumPHINode++; } - inline void visitCastInst (CastInst &I) { NumCastInst++; } - inline void visitCallInst (CallInst &I) { NumCallInst++; } - inline void visitMallocInst(MallocInst &I) { NumMallocInst++; } - inline void visitAllocaInst(AllocaInst &I) { NumAllocaInst++; } - inline void visitFreeInst (FreeInst &I) { NumFreeInst++; } - inline void visitLoadInst (LoadInst &I) { NumLoadInst++; } - inline void visitStoreInst (StoreInst &I) { NumStoreInst++; } - inline void visitGetElementPtrInst(GetElementPtrInst &I) { - NumGetElementPtrInst++; } +#include "llvm/Instruction.def" - inline void visitInstruction(Instruction &I) { + void visitInstruction(Instruction &I) { std::cerr << "Instruction Count does not know about " << I; abort(); } @@ -93,63 +33,18 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } + virtual void print(std::ostream &O, Module *M) const {} + }; RegisterAnalysis X("instcount", - "Counts the various types of Instructions"); - + "Counts the various types of Instructions"); } -// createInstCountPass - The public interface to this file... -Pass *createInstCountPass() { return new InstCount(); } - - // InstCount::run - This is the main Analysis entry point for a // function. // bool InstCount::run(Module &M) { - for (Module::iterator mI = M.begin(), mE = M.end(); mI != mE; ++mI) - for (inst_iterator I = inst_begin(*mI), E = inst_end(*mI); I != E; ++I) - visit(*I); + visit(M); return false; -} - - - -void InstCount::visitBinaryOperator(BinaryOperator &I) { - NumBinaryOperator++; - switch (I.getOpcode()) { - case Instruction::Add: NumAddInst++; break; - case Instruction::Sub: NumSubInst++; break; - case Instruction::Mul: NumMulInst++; break; - case Instruction::Div: NumDivInst++; break; - case Instruction::Rem: NumRemInst++; break; - case Instruction::And: NumAndInst++; break; - case Instruction::Or: NumOrInst++; break; - case Instruction::Xor: NumXorInst++; break; - default : std::cerr<< " Wrong binary operator \n"; - } -} - -void InstCount::visitSetCondInst(SetCondInst &I) { - NumBinaryOperator++; - NumSetCondInst++; - switch (I.getOpcode()) { - case Instruction::SetEQ: NumSetEQInst++; break; - case Instruction::SetNE: NumSetNEInst++; break; - case Instruction::SetLE: NumSetLEInst++; break; - case Instruction::SetGE: NumSetGEInst++; break; - case Instruction::SetLT: NumSetLTInst++; break; - case Instruction::SetGT: NumSetGTInst++; break; - default : std::cerr<< " Wrong SetCond Inst \n"; - } -} - -void InstCount::visitShiftInst(ShiftInst &I) { - NumShiftInst++; - switch (I.getOpcode()) { - case Instruction::Shl: NumShlInst++; break; - case Instruction::Shr: NumShrInst++; break; - default : std::cerr<< " Wrong ShiftInst \n"; - } } From lattner at cs.uiuc.edu Tue Dec 3 13:43:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 13:43:01 2002 Subject: [llvm-commits] CVS: llvm/tools/analyze/analyze.cpp Message-ID: <200212031942.NAA31013@apoc.cs.uiuc.edu> Changes in directory llvm/tools/analyze: analyze.cpp updated: 1.48 -> 1.49 --- Log message: Disable timing of bytecode loader --- Diffs of the changes: Index: llvm/tools/analyze/analyze.cpp diff -u llvm/tools/analyze/analyze.cpp:1.48 llvm/tools/analyze/analyze.cpp:1.49 --- llvm/tools/analyze/analyze.cpp:1.48 Sun Nov 10 00:55:02 2002 +++ llvm/tools/analyze/analyze.cpp Tue Dec 3 13:42:26 2002 @@ -109,7 +109,9 @@ Module *CurMod = 0; try { +#if 0 TimeRegion RegionTimer(BytecodeLoadTimer); +#endif CurMod = ParseBytecodeFile(InputFilename); if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){ std::cerr << argv[0] << ": input file didn't read correctly.\n"; From lattner at cs.uiuc.edu Tue Dec 3 14:02:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 14:02:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/TableGen.cpp Message-ID: <200212032001.OAA01132@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: TableGen.cpp updated: 1.2 -> 1.3 --- Log message: Add code that can be used for debugging --- Diffs of the changes: Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.2 llvm/utils/TableGen/TableGen.cpp:1.3 --- llvm/utils/TableGen/TableGen.cpp:1.2 Mon Dec 2 11:43:43 2002 +++ llvm/utils/TableGen/TableGen.cpp Tue Dec 3 14:01:04 2002 @@ -201,6 +201,14 @@ abort(); } +#if 0 + std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit + << ": [" << RangeEnd-RangeBegin << "] - "; + for (int i = LastFixedBit-1; i >= (int)FirstVaryingBit; --i) + std::cerr << (int)((BitInit*)getBit(*RangeBegin, i))->getValue() << " "; + std::cerr << "\n"; +#endif + if (Record *R = ParseMachineCode(RangeBegin, RangeEnd, M)) { if (Match) { std::cerr << "Error: Multiple matches found:\n"; @@ -281,7 +289,8 @@ } static void ParseMachineCode() { - unsigned char Buffer[] = { 0x55, // push EBP + unsigned char Buffer[] = { + 0x55, // push EBP 0x89, 0xE5, // mov EBP, ESP //0x83, 0xEC, 0x08, // sub ESP, 0x8 0xE8, 1, 2, 3, 4, // call +0x04030201 @@ -291,10 +300,10 @@ 0x90, // nop 0xC9, // leave 0x89, 0xF6, // mov ESI, ESI - 0xB8, 1, 2, 3, 4, // mov EAX, 0x04030201 0x68, 1, 2, 3, 4, // push 0x04030201 0x5e, // pop ESI 0xFF, 0xD0, // call EAX + 0xB8, 1, 2, 3, 4, // mov EAX, 0x04030201 0x85, 0xC0, // test EAX, EAX 0xF4, // hlt }; From lattner at cs.uiuc.edu Tue Dec 3 14:26:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 14:26:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/hello.ll Message-ID: <200212032025.OAA02392@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: hello.ll added (r1.1) --- Log message: Standard hello-world test --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Dec 3 14:31:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 14:31:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/test-call.ll Message-ID: <200212032030.OAA02484@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: test-call.ll added (r1.1) --- Log message: Testcase for call instruction --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Dec 3 14:31:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 14:31:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212032030.OAA02491@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.44 -> 1.45 --- Log message: Fix instsel for calls --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.44 llvm/lib/Target/X86/InstSelectSimple.cpp:1.45 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.44 Tue Dec 3 12:15:59 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Dec 3 14:30:12 2002 @@ -389,10 +389,9 @@ { // Push the arguments on the stack in reverse order, as specified by // the ABI. - for (unsigned i = CI.getNumOperands (); i >= 1; --i) + for (unsigned i = CI.getNumOperands()-1; i >= 1; --i) { Value *v = CI.getOperand (i); - unsigned argReg = getReg (v); switch (getClass (v->getType ())) { case cByte: @@ -404,7 +403,7 @@ break; case cInt: case cFloat: - BuildMI (BB, X86::PUSHr32, 1).addReg (argReg); + BuildMI (BB, X86::PUSHr32, 1).addReg(getReg(v)); break; default: // FIXME: long/ulong/double args not handled. From lattner at cs.uiuc.edu Tue Dec 3 14:57:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 14:57:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineCodeEmitter.h Message-ID: <200212032056.OAA02715@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineCodeEmitter.h updated: 1.3 -> 1.4 --- Log message: Add virtual dtor, expose a debug impl --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineCodeEmitter.h diff -u llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.3 llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.4 --- llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.3 Mon Dec 2 15:56:28 2002 +++ llvm/include/llvm/CodeGen/MachineCodeEmitter.h Tue Dec 3 14:56:20 2002 @@ -15,6 +15,7 @@ class Value; struct MachineCodeEmitter { + virtual ~MachineCodeEmitter() {} /// startFunction - This callback is invoked when the specified function is /// about to be code generated. @@ -41,6 +42,13 @@ /// and jump instructions typically. /// virtual void emitPCRelativeDisp(Value *V) {} + + + /// createDebugMachineCodeEmitter - Return a dynamically allocated machine + /// code emitter, which just prints the opcodes and fields out the cout. This + /// can be used for debugging users of the MachineCodeEmitter interface. + /// + static MachineCodeEmitter *createDebugMachineCodeEmitter(); }; #endif From lattner at cs.uiuc.edu Tue Dec 3 14:57:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 14:57:03 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineCodeEmitter.cpp Message-ID: <200212032056.OAA02724@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineCodeEmitter.cpp added (r1.1) --- Log message: Checkin debug implementation of MCE --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Dec 3 16:50:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 16:50:01 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/Emitter.cpp VM.cpp VM.h jello.cpp Message-ID: <200212032249.QAA03852@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: Emitter.cpp added (r1.1) VM.cpp added (r1.1) VM.h added (r1.1) jello.cpp updated: 1.7 -> 1.8 --- Log message: Initial checkin of virtual machine implementation. We can now run very trivial test cases --- Diffs of the changes: Index: llvm/tools/jello/jello.cpp diff -u llvm/tools/jello/jello.cpp:1.7 llvm/tools/jello/jello.cpp:1.8 --- llvm/tools/jello/jello.cpp:1.7 Tue Dec 3 00:33:30 2002 +++ llvm/tools/jello/jello.cpp Tue Dec 3 16:48:59 2002 @@ -3,42 +3,14 @@ // This tool implements a just-in-time compiler for LLVM, allowing direct // execution of LLVM bytecode in an efficient manner. // -// FIXME: This code will get more object oriented as we get the call back -// intercept stuff implemented. -// //===----------------------------------------------------------------------===// #include "llvm/Module.h" -#include "llvm/PassManager.h" #include "llvm/Bytecode/Reader.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachineImpls.h" #include "Support/CommandLine.h" -#include "Support/Statistic.h" - - -#include "llvm/CodeGen/MachineCodeEmitter.h" -#include "llvm/CodeGen/MachineFunction.h" -struct JelloMachineCodeEmitter : public MachineCodeEmitter { - void startFunction(MachineFunction &F) { - std::cout << "\n**** Writing machine code for function: " - << F.getFunction()->getName() << "\n"; - } - void finishFunction(MachineFunction &F) { - std::cout << "\n"; - } - void startBasicBlock(MachineBasicBlock &BB) { - std::cout << "\n--- Basic Block: " << BB.getBasicBlock()->getName() << "\n"; - } - - void emitByte(unsigned char B) { - std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " "; - } - void emitPCRelativeDisp(Value *V) { - std::cout << "<" << V->getName() << ": 0x00 0x00 0x00 0x00> "; - } -}; - +#include "VM.h" namespace { cl::opt @@ -57,10 +29,8 @@ // Allocate a target... in the future this will be controllable on the // command line. - std::auto_ptr target(allocateX86TargetMachine()); - assert(target.get() && "Could not allocate target machine!"); - - TargetMachine &Target = *target.get(); + std::auto_ptr Target(allocateX86TargetMachine()); + assert(Target.get() && "Could not allocate target machine!"); // Parse the input bytecode file... std::string ErrorMsg; @@ -71,29 +41,15 @@ return 1; } - PassManager Passes; + // Create the virtual machine object... + VM TheVM(argv[0], *M.get(), *Target.get()); - // Compile LLVM Code down to machine code in the intermediate representation - if (Target.addPassesToJITCompile(Passes)) { - std::cerr << argv[0] << ": target '" << Target.getName() - << "' doesn't support JIT compilation!\n"; + Function *F = M.get()->getNamedFunction(MainFunction); + if (F == 0) { + std::cerr << "Could not find function '" << MainFunction <<"' in module!\n"; return 1; } - // Turn the machine code intermediate representation into bytes in memory that - // may be executed. - // - JelloMachineCodeEmitter MCE; - if (Target.addPassesToEmitMachineCode(Passes, MCE)) { - std::cerr << argv[0] << ": target '" << Target.getName() - << "' doesn't support machine code emission!\n"; - return 1; - } - - // JIT all of the methods in the module. Eventually this will JIT functions - // on demand. - Passes.run(*M.get()); - - return 0; + // Run the virtual machine... + return TheVM.run(F); } - From lattner at cs.uiuc.edu Tue Dec 3 16:51:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 16:51:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200212032250.QAA03874@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def updated: 1.30 -> 1.31 --- Log message: Fix broken ret opcode, grr... --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.30 llvm/lib/Target/X86/X86InstrInfo.def:1.31 --- llvm/lib/Target/X86/X86InstrInfo.def:1.30 Mon Dec 2 23:42:53 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Tue Dec 3 16:50:02 2002 @@ -58,7 +58,7 @@ I(NOOP , "nop", 0x90, 0, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // nop // Flow control instructions -I(RET , "ret", 0xCB, M_RET_FLAG, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // ret +I(RET , "ret", 0xC3, M_RET_FLAG, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // ret I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // jmp foo I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void, NoImpRegs, NoImpRegs) I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void, NoImpRegs, NoImpRegs) From brukman at cs.uiuc.edu Tue Dec 3 17:11:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Dec 3 17:11:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200212032310.RAA06261@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.3 -> 1.4 --- Log message: RegisterInfo now supports handing out caller- and callee-save registers, as well as building a map from a physical register to its register class. --- Diffs of the changes: Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.3 llvm/include/llvm/Target/MRegisterInfo.h:1.4 --- llvm/include/llvm/Target/MRegisterInfo.h:1.3 Fri Nov 22 16:41:23 2002 +++ llvm/include/llvm/Target/MRegisterInfo.h Tue Dec 3 17:09:53 2002 @@ -10,6 +10,7 @@ #define LLVM_TARGET_MREGISTERINFO_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include #include class Type; @@ -60,6 +61,15 @@ virtual unsigned getDataSize() const { return 0; } + virtual void + buildReg2RegClassMap(std::map& + Reg2RegClassMap) const + { + for (unsigned i=0; i < getNumRegs(); ++i) { + Reg2RegClassMap[getRegister(i)] = this; + } + } + //const std::vector &getRegsInClass(void) { return Regs; } //void getAliases(void); }; @@ -119,6 +129,9 @@ unsigned DestReg, unsigned SrcReg, unsigned ImmOffset, unsigned dataSize) const = 0; + virtual const unsigned* getCalleeSaveRegs() const = 0; + virtual const unsigned* getCallerSaveRegs() const = 0; + virtual unsigned getFramePointer() const = 0; virtual unsigned getStackPointer() const = 0; @@ -130,6 +143,10 @@ virtual unsigned getNumRegClasses() const = 0; virtual const TargetRegisterClass* getRegClassForType(const Type* Ty) const=0; + + virtual void + buildReg2RegClassMap(std::map& + Reg2RegClassMap) const=0; }; #endif From brukman at cs.uiuc.edu Tue Dec 3 17:12:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Dec 3 17:12:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86RegisterInfo.h Message-ID: <200212032311.RAA06393@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.5 -> 1.6 X86RegisterInfo.h updated: 1.3 -> 1.4 --- Log message: Added support for callee- and caller-save registers. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.5 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.6 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.5 Mon Dec 2 15:10:35 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Tue Dec 3 17:11:21 2002 @@ -56,3 +56,28 @@ unsigned X86RegisterInfo::getStackPointer() const { return X86::ESP; } + +const unsigned* X86RegisterInfo::getCalleeSaveRegs() const { + static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX, X86::EBP, + MRegisterInfo::NoRegister }; + return CalleeSaveRegs; +} + + +const unsigned* X86RegisterInfo::getCallerSaveRegs() const { + static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX, + MRegisterInfo::NoRegister }; + return CallerSaveRegs; +} + +void +X86RegisterInfo::buildReg2RegClassMap +(std::map& Reg2RegClassMap) const +{ + for (MRegisterInfo::const_iterator I = const_regclass_begin(), + E = const_regclass_end(); I != E; ++I) + { + I->buildReg2RegClassMap(Reg2RegClassMap); + } +} Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.3 llvm/lib/Target/X86/X86RegisterInfo.h:1.4 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.3 Fri Nov 22 16:43:47 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.h Tue Dec 3 17:11:21 2002 @@ -32,6 +32,9 @@ unsigned getFramePointer() const; unsigned getStackPointer() const; + const unsigned* getCalleeSaveRegs() const; + const unsigned* getCallerSaveRegs() const; + /// Returns register class appropriate for input SSA register /// const TargetRegisterClass *getClassForReg(unsigned Reg) const; @@ -40,6 +43,8 @@ unsigned getNumRegClasses() const; + void buildReg2RegClassMap(std::map& + Reg2RegClassMap) const; }; From brukman at cs.uiuc.edu Tue Dec 3 17:16:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Dec 3 17:16:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocSimple.cpp Message-ID: <200212032315.RAA06528@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocSimple.cpp updated: 1.2 -> 1.3 --- Log message: This should fix the bug seen with some registers not being allocated correctly: skipping instructions by incorrectly incrementing the pointer. Also adds support for building a reg-to-regclass map, and splits the function for saving register to stack into two, one suitable for virtual registers (which also assigns it a physical register) and one for simply storing back physical registers. --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocSimple.cpp diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.2 llvm/lib/CodeGen/RegAllocSimple.cpp:1.3 --- llvm/lib/CodeGen/RegAllocSimple.cpp:1.2 Mon Dec 2 15:11:58 2002 +++ llvm/lib/CodeGen/RegAllocSimple.cpp Tue Dec 3 17:15:19 2002 @@ -29,10 +29,13 @@ unsigned NumBytesAllocated, ByteAlignment; // Maps SSA Regs => offsets on the stack where these values are stored - std::map RegMap; // FIXME: change name to OffsetMap + std::map RegMap; // FIXME: change name to VirtReg2OffsetMap // Maps SSA Regs => physical regs std::map SSA2PhysRegMap; + + // Maps physical register to their register classes + std::map PhysReg2RegClassMap; // Maps RegClass => which index we can take a register from. Since this is a // simple register allocator, when we need a register of a certain class, we @@ -44,6 +47,9 @@ RegInfo(tm.getRegisterInfo()), NumBytesAllocated(0), ByteAlignment(4) { + // build reverse mapping for physReg -> register class + RegInfo->buildReg2RegClassMap(PhysReg2RegClassMap); + RegsUsed[RegInfo->getFramePointer()] = 1; RegsUsed[RegInfo->getStackPointer()] = 1; } @@ -73,8 +79,11 @@ /// Saves reg value on the stack (maps virtual register to stack value) MachineBasicBlock::iterator - saveRegToStack (MachineBasicBlock::iterator I, unsigned VirtReg, - unsigned PhysReg); + saveVirtRegToStack (MachineBasicBlock::iterator I, unsigned VirtReg, + unsigned PhysReg); + + MachineBasicBlock::iterator + savePhysRegToStack (MachineBasicBlock::iterator I, unsigned PhysReg); /// runOnFunction - Top level implementation of instruction selection for /// the entire function. @@ -144,8 +153,8 @@ } MachineBasicBlock::iterator -RegAllocSimple::saveRegToStack (MachineBasicBlock::iterator I, - unsigned VirtReg, unsigned PhysReg) +RegAllocSimple::saveVirtRegToStack (MachineBasicBlock::iterator I, + unsigned VirtReg, unsigned PhysReg) { const TargetRegisterClass* regClass = MF->getRegClass(VirtReg); assert(regClass); @@ -158,12 +167,38 @@ offset, regClass->getDataSize()); } +MachineBasicBlock::iterator +RegAllocSimple::savePhysRegToStack (MachineBasicBlock::iterator I, + unsigned PhysReg) +{ + const TargetRegisterClass* regClass = MF->getRegClass(PhysReg); + assert(regClass); + + unsigned offset = allocateStackSpaceFor(PhysReg, regClass); + + // Add move instruction(s) + return RegInfo->storeReg2RegOffset(CurrMBB, I, PhysReg, + RegInfo->getFramePointer(), + offset, regClass->getDataSize()); +} + bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) { RegMap.clear(); unsigned virtualReg, physReg; DEBUG(std::cerr << "Machine Function " << "\n"); MF = &Fn; + +#if 0 // FIXME: add prolog. we should preserve callee-save registers... + MachineFunction::iterator Fi = Fn.begin(); + MachineBasicBlock &MBB = *Fi; + MachineBasicBlock::iterator MBBi = MBB.begin() + const unsigned* calleeSaveRegs = tm.getCalleeSaveRegs(); + while (*calleeSaveRegs) { + //MBBi = saveRegToStack(MBBi, *calleeSaveRegs, + ++calleeSaveRegs; + } +#endif for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); MBB != MBBe; ++MBB) @@ -178,6 +213,10 @@ DEBUG(std::cerr << "instr: "; MI->print(std::cerr, TM)); + // FIXME: add a preliminary pass that will invalidate any registers that + // are used by the instruction (including implicit uses) + + // Loop over each instruction: // uses, move from memory into registers for (int i = MI->getNumOperands() - 1; i >= 0; --i) { @@ -196,7 +235,7 @@ if (op.opIsDef()) { physReg = getFreeReg(virtualReg); MachineBasicBlock::iterator J = I; - I = saveRegToStack(++J, virtualReg, physReg); + I = saveVirtRegToStack(J, virtualReg, physReg); } else { I = moveUseToReg(I, virtualReg, physReg); } From lattner at cs.uiuc.edu Tue Dec 3 22:48:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 22:48:01 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/Emitter.cpp VM.cpp VM.h Message-ID: <200212040447.WAA11596@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: Emitter.cpp updated: 1.1 -> 1.2 VM.cpp updated: 1.1 -> 1.2 VM.h updated: 1.1 -> 1.2 --- Log message: Implement lazy resolution of function calls --- Diffs of the changes: Index: llvm/tools/jello/Emitter.cpp diff -u llvm/tools/jello/Emitter.cpp:1.1 llvm/tools/jello/Emitter.cpp:1.2 --- llvm/tools/jello/Emitter.cpp:1.1 Tue Dec 3 16:48:59 2002 +++ llvm/tools/jello/Emitter.cpp Tue Dec 3 22:47:34 2002 @@ -68,7 +68,9 @@ // resolved on demand. Keep track of these markers. // void Emitter::emitPCRelativeDisp(Value *V) { - unsigned ZeroAddr = -(unsigned)CurByte; // Calculate displacement to null + TheVM.addFunctionRef(CurByte, cast(V)); + + unsigned ZeroAddr = -(unsigned)CurByte-4; // Calculate displacement to null *(unsigned*)CurByte = ZeroAddr; // 4 byte offset CurByte += 4; } Index: llvm/tools/jello/VM.cpp diff -u llvm/tools/jello/VM.cpp:1.1 llvm/tools/jello/VM.cpp:1.2 --- llvm/tools/jello/VM.cpp:1.1 Tue Dec 3 16:48:59 2002 +++ llvm/tools/jello/VM.cpp Tue Dec 3 22:47:34 2002 @@ -43,6 +43,21 @@ return PF(); } +void *VM::resolveFunctionReference(void *RefAddr) { + Function *F = FunctionRefs[RefAddr]; + assert(F && "Reference address not known!"); + + void *Addr = getPointerToFunction(F); + assert(Addr && "Pointer to function unknown!"); + + FunctionRefs.erase(RefAddr); + return Addr; +} + +const std::string &VM::getFunctionReferencedName(void *RefAddr) { + return FunctionRefs[RefAddr]->getName(); +} + /// getPointerToFunction - This method is used to get the address of the /// specified function, compiling it if neccesary. Index: llvm/tools/jello/VM.h diff -u llvm/tools/jello/VM.h:1.1 llvm/tools/jello/VM.h:1.2 --- llvm/tools/jello/VM.h:1.1 Tue Dec 3 16:48:59 2002 +++ llvm/tools/jello/VM.h Tue Dec 3 22:47:34 2002 @@ -10,6 +10,7 @@ #include "llvm/PassManager.h" #include #include +#include class TargetMachine; class Function; @@ -23,12 +24,21 @@ PassManager PM; // Passes to compile a function MachineCodeEmitter *MCE; // MCE object + // GlobalAddress - A mapping between LLVM values and their native code + // generated versions... std::map GlobalAddress; + + // FunctionRefs - A mapping between addresses that refer to unresolved + // functions and the LLVM function object itself. This is used by the fault + // handler to lazily patch up references... + // + std::map FunctionRefs; public: VM(const std::string &name, Module &m, TargetMachine &tm) : ExeName(name), M(m), TM(tm) { MCE = createEmitter(*this); // Initialize MCE setupPassManager(); + registerCallback(); } ~VM(); @@ -41,10 +51,19 @@ CurVal = Addr; } + void addFunctionRef(void *Ref, Function *F) { + FunctionRefs[Ref] = F; + } + + const std::string &getFunctionReferencedName(void *RefAddr); + + void *resolveFunctionReference(void *RefAddr); + private: static MachineCodeEmitter *createEmitter(VM &V); void setupPassManager(); void *getPointerToFunction(Function *F); + void registerCallback(); }; #endif From lattner at cs.uiuc.edu Tue Dec 3 23:06:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 23:06:00 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/Callback.cpp Message-ID: <200212040505.XAA11662@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: Callback.cpp added (r1.1) --- Log message: Initial checkin of Unresolved function fault handler --- Diffs of the changes: From lattner at cs.uiuc.edu Tue Dec 3 23:21:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Dec 3 23:21:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetMachine.h Message-ID: <200212040520.XAA11708@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetMachine.h updated: 1.23 -> 1.24 --- Log message: Expose target data through a method for uniformity --- Diffs of the changes: Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.23 llvm/include/llvm/Target/TargetMachine.h:1.24 --- llvm/include/llvm/Target/TargetMachine.h:1.23 Mon Dec 2 15:15:42 2002 +++ llvm/include/llvm/Target/TargetMachine.h Tue Dec 3 23:20:12 2002 @@ -67,6 +67,7 @@ virtual const MachineFrameInfo& getFrameInfo() const = 0; virtual const MachineCacheInfo& getCacheInfo() const = 0; virtual const MachineOptInfo& getOptInfo() const = 0; + const TargetData &getTargetData() const { return DataLayout; } /// getRegisterInfo - If register information is available, return it. If /// not, return null. This is kept separate from RegInfo until RegInfo gets From lattner at cs.uiuc.edu Wed Dec 4 00:05:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 00:05:01 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/VM.cpp Message-ID: <200212040604.AAA12025@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: VM.cpp updated: 1.2 -> 1.3 --- Log message: Implement external function support --- Diffs of the changes: Index: llvm/tools/jello/VM.cpp diff -u llvm/tools/jello/VM.cpp:1.2 llvm/tools/jello/VM.cpp:1.3 --- llvm/tools/jello/VM.cpp:1.2 Tue Dec 3 22:47:34 2002 +++ llvm/tools/jello/VM.cpp Wed Dec 4 00:04:07 2002 @@ -10,6 +10,7 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/Function.h" #include +#include // dlsym access VM::~VM() { @@ -58,6 +59,7 @@ return FunctionRefs[RefAddr]->getName(); } +static void NoopFn() {} /// getPointerToFunction - This method is used to get the address of the /// specified function, compiling it if neccesary. @@ -67,7 +69,15 @@ if (Addr) return Addr; if (F->isExternal()) { - assert(0 && "VM::getPointerToFunction: Doesn't handle external fn's yet!"); + // If it's an external function, look it up in the process image... + void *Ptr = dlsym(0, F->getName().c_str()); + if (Ptr == 0) { + std::cerr << "WARNING: Cannot resolve fn '" << F->getName() + << "' using a dummy noop function instead!\n"; + Ptr = (void*)NoopFn; + } + + return Addr = Ptr; } // JIT all of the functions in the module. Eventually this will JIT functions From lattner at cs.uiuc.edu Wed Dec 4 00:05:08 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 00:05:08 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/VM.h Message-ID: <200212040604.AAA12032@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: VM.h updated: 1.2 -> 1.3 --- Log message: Implement simple global variable support --- Diffs of the changes: Index: llvm/tools/jello/VM.h diff -u llvm/tools/jello/VM.h:1.2 llvm/tools/jello/VM.h:1.3 --- llvm/tools/jello/VM.h:1.2 Tue Dec 3 22:47:34 2002 +++ llvm/tools/jello/VM.h Wed Dec 4 00:04:17 2002 @@ -12,9 +12,10 @@ #include #include -class TargetMachine; class Function; class GlobalValue; +class Constant; +class TargetMachine; class MachineCodeEmitter; class VM { @@ -39,6 +40,7 @@ MCE = createEmitter(*this); // Initialize MCE setupPassManager(); registerCallback(); + emitGlobals(); } ~VM(); @@ -64,6 +66,8 @@ void setupPassManager(); void *getPointerToFunction(Function *F); void registerCallback(); + void emitGlobals(); + void emitConstantToMemory(Constant *Init, void *Addr); }; #endif From lattner at cs.uiuc.edu Wed Dec 4 00:10:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 00:10:02 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/GlobalVars.cpp Message-ID: <200212040609.AAA12060@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: GlobalVars.cpp added (r1.1) --- Log message: Initial checkin of global var support code --- Diffs of the changes: From lattner at cs.uiuc.edu Wed Dec 4 00:45:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 00:45:02 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineCodeEmitter.h Message-ID: <200212040644.AAA12885@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineCodeEmitter.h updated: 1.4 -> 1.5 --- Log message: Add support for direct global references --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/MachineCodeEmitter.h diff -u llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.4 llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.5 --- llvm/include/llvm/CodeGen/MachineCodeEmitter.h:1.4 Tue Dec 3 14:56:20 2002 +++ llvm/include/llvm/CodeGen/MachineCodeEmitter.h Wed Dec 4 00:44:27 2002 @@ -13,6 +13,7 @@ class MachineFunction; class MachineBasicBlock; class Value; +class GlobalValue; struct MachineCodeEmitter { virtual ~MachineCodeEmitter() {} @@ -42,6 +43,12 @@ /// and jump instructions typically. /// virtual void emitPCRelativeDisp(Value *V) {} + + /// emitGlobalAddress - This callback is invoked when we need to write out the + /// address of a global value to machine code. This is important for indirect + /// calls as well as accessing global variables. + /// + virtual void emitGlobalAddress(GlobalValue *V) {} /// createDebugMachineCodeEmitter - Return a dynamically allocated machine From lattner at cs.uiuc.edu Wed Dec 4 00:45:08 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 00:45:08 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/MachineCodeEmitter.cpp Message-ID: <200212040644.AAA12894@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: MachineCodeEmitter.cpp updated: 1.1 -> 1.2 --- Log message: Print out direct global references --- Diffs of the changes: Index: llvm/lib/CodeGen/MachineCodeEmitter.cpp diff -u llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.1 llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.2 --- llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.1 Tue Dec 3 14:56:42 2002 +++ llvm/lib/CodeGen/MachineCodeEmitter.cpp Wed Dec 4 00:44:41 2002 @@ -26,7 +26,10 @@ std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " "; } void emitPCRelativeDisp(Value *V) { - std::cout << "<" << V->getName() << ": 0xXX 0xXX 0xXX 0xXX> "; + std::cout << "getName() << ": 0xXX 0xXX 0xXX 0xXX> "; + } + void emitGlobalAddress(GlobalValue *V) { + std::cout << "getName() << ": 0xXX 0xXX 0xXX 0xXX> "; } }; } From lattner at cs.uiuc.edu Wed Dec 4 00:46:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 00:46:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp MachineCodeEmitter.cpp Printer.cpp Message-ID: <200212040645.AAA12911@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.45 -> 1.46 MachineCodeEmitter.cpp updated: 1.4 -> 1.5 Printer.cpp updated: 1.20 -> 1.21 --- Log message: Add support for referencing global variables/functions --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.45 llvm/lib/Target/X86/InstSelectSimple.cpp:1.46 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.45 Tue Dec 3 14:30:12 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Dec 4 00:45:19 2002 @@ -133,8 +133,14 @@ // If this operand is a constant, emit the code to copy the constant into // the register here... // - if (Constant *C = dyn_cast(V)) + if (Constant *C = dyn_cast(V)) { copyConstantToRegister(C, Reg); + } else if (GlobalValue *GV = dyn_cast(V)) { + // Move the address of the global into the register + BuildMI(BB, X86::MOVir32, 1, Reg).addReg(GV); + } else { + assert(0 && "Don't know how to handle a value of this type!"); + } return Reg; } Index: llvm/lib/Target/X86/MachineCodeEmitter.cpp diff -u llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.4 llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.5 --- llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.4 Tue Dec 3 00:34:06 2002 +++ llvm/lib/Target/X86/MachineCodeEmitter.cpp Wed Dec 4 00:45:19 2002 @@ -11,6 +11,7 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Value.h" namespace { class Emitter : public FunctionPass { @@ -224,7 +225,12 @@ MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg())); if (MI.getNumOperands() == 2) { unsigned Size = 4; - emitConstant(MI.getOperand(1).getImmedValue(), Size); + if (Value *V = MI.getOperand(1).getVRegValue()) { + assert(Size == 4 && "Don't know how to emit non-pointer values!"); + MCE.emitGlobalAddress(cast(V)); + } else { + emitConstant(MI.getOperand(1).getImmedValue(), Size); + } } break; case X86II::MRMDestReg: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.20 llvm/lib/Target/X86/Printer.cpp:1.21 --- llvm/lib/Target/X86/Printer.cpp:1.20 Tue Dec 3 00:34:06 2002 +++ llvm/lib/Target/X86/Printer.cpp Wed Dec 4 00:45:19 2002 @@ -96,6 +96,10 @@ const MRegisterInfo &RI) { switch (MO.getType()) { case MachineOperand::MO_VirtualRegister: + if (Value *V = MO.getVRegValue()) { + O << "<" << V->getName() << ">"; + return; + } case MachineOperand::MO_MachineRegister: if (MO.getReg() < MRegisterInfo::FirstVirtualRegister) O << RI.get(MO.getReg()).Name; @@ -172,11 +176,15 @@ // 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.). + // (move immediate f.e.). Note that this immediate value might be stored as + // an LLVM value, to represent, for example, loading the address of a global + // into a register. // assert(isReg(MI->getOperand(0)) && (MI->getNumOperands() == 1 || - (MI->getNumOperands() == 2 && isImmediate(MI->getOperand(1)))) && + (MI->getNumOperands() == 2 && + (MI->getOperand(1).getVRegValue() || + isImmediate(MI->getOperand(1))))) && "Illegal form for AddRegFrm instruction!"); unsigned Reg = MI->getOperand(0).getReg(); From lattner at cs.uiuc.edu Wed Dec 4 00:46:08 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 00:46:08 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/Emitter.cpp VM.cpp VM.h Message-ID: <200212040645.AAA12926@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: Emitter.cpp updated: 1.2 -> 1.3 VM.cpp updated: 1.3 -> 1.4 VM.h updated: 1.3 -> 1.4 --- Log message: Add support for global value references --- Diffs of the changes: Index: llvm/tools/jello/Emitter.cpp diff -u llvm/tools/jello/Emitter.cpp:1.2 llvm/tools/jello/Emitter.cpp:1.3 --- llvm/tools/jello/Emitter.cpp:1.2 Tue Dec 3 22:47:34 2002 +++ llvm/tools/jello/Emitter.cpp Wed Dec 4 00:45:40 2002 @@ -23,6 +23,7 @@ virtual void startBasicBlock(MachineBasicBlock &BB) {} virtual void emitByte(unsigned char B); virtual void emitPCRelativeDisp(Value *V); + virtual void emitGlobalAddress(GlobalValue *V); }; } @@ -44,6 +45,7 @@ void Emitter::startFunction(MachineFunction &F) { CurBlock = (unsigned char *)getMemory(); CurByte = CurBlock; // Start writing at the beginning of the fn. + TheVM.addGlobalMapping(F.getFunction(), CurBlock); } #include @@ -53,7 +55,6 @@ std::cerr << "Finished Code Generation of Function: " << F.getFunction()->getName() << ": " << CurByte-CurBlock << " bytes of text\n"; - TheVM.addGlobalMapping(F.getFunction(), CurBlock); } @@ -72,5 +73,10 @@ unsigned ZeroAddr = -(unsigned)CurByte-4; // Calculate displacement to null *(unsigned*)CurByte = ZeroAddr; // 4 byte offset + CurByte += 4; +} + +void Emitter::emitGlobalAddress(GlobalValue *V) { + *(void**)CurByte = TheVM.getPointerToGlobal(V); CurByte += 4; } Index: llvm/tools/jello/VM.cpp diff -u llvm/tools/jello/VM.cpp:1.3 llvm/tools/jello/VM.cpp:1.4 --- llvm/tools/jello/VM.cpp:1.3 Wed Dec 4 00:04:07 2002 +++ llvm/tools/jello/VM.cpp Wed Dec 4 00:45:40 2002 @@ -59,6 +59,18 @@ return FunctionRefs[RefAddr]->getName(); } +// getPointerToGlobal - This returns the address of the specified global +// value. This may involve code generation if it's a function. +// +void *VM::getPointerToGlobal(GlobalValue *GV) { + if (Function *F = dyn_cast(GV)) + return getPointerToFunction(F); + + assert(GlobalAddress[GV] && "Global hasn't had an address allocated yet?"); + return GlobalAddress[GV]; +} + + static void NoopFn() {} /// getPointerToFunction - This method is used to get the address of the Index: llvm/tools/jello/VM.h diff -u llvm/tools/jello/VM.h:1.3 llvm/tools/jello/VM.h:1.4 --- llvm/tools/jello/VM.h:1.3 Wed Dec 4 00:04:17 2002 +++ llvm/tools/jello/VM.h Wed Dec 4 00:45:40 2002 @@ -61,6 +61,11 @@ void *resolveFunctionReference(void *RefAddr); + // getPointerToGlobal - This returns the address of the specified global + // value. This may involve code generation if it's a function. + // + void *getPointerToGlobal(GlobalValue *GV); + private: static MachineCodeEmitter *createEmitter(VM &V); void setupPassManager(); From lattner at cs.uiuc.edu Wed Dec 4 00:58:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 00:58:02 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212040657.AAA13007@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.46 -> 1.47 --- Log message: Fix a bug I introduced in a previous change --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.46 llvm/lib/Target/X86/InstSelectSimple.cpp:1.47 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.46 Wed Dec 4 00:45:19 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Dec 4 00:56:56 2002 @@ -408,9 +408,11 @@ BuildMI (BB, X86::PUSHr32, 1).addReg (X86::EAX); break; case cInt: - case cFloat: - BuildMI (BB, X86::PUSHr32, 1).addReg(getReg(v)); + case cFloat: { + unsigned Reg = getReg(v); + BuildMI (BB, X86::PUSHr32, 1).addReg(Reg); break; + } default: // FIXME: long/ulong/double args not handled. visitInstruction (CI); From lattner at cs.uiuc.edu Wed Dec 4 10:14:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 10:14:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200212041613.KAA14226@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.4 -> 1.5 --- Log message: Add a "Lazy Function Resolution in Jello" section Remove some todo's --- Diffs of the changes: Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.4 llvm/lib/Target/X86/README.txt:1.5 --- llvm/lib/Target/X86/README.txt:1.4 Tue Nov 19 18:56:42 2002 +++ llvm/lib/Target/X86/README.txt Wed Dec 4 10:12:54 2002 @@ -81,9 +81,41 @@ specify a destination register to the BuildMI call. -======================= -III. Source Code Layout -======================= +====================================== +III. Lazy Function Resolution in Jello +====================================== + +Jello is a designed to be a JIT compiler for LLVM code. This implies that call +instructions may be emitted before the function they call is compiled. In order +to support this, Jello currently emits unresolved call instructions to call to a +null pointer. When the call instruction is executed, a segmentation fault will +be generated. + +Jello installs a trap handler for SIGSEGV, in order to trap these events. When +a SIGSEGV occurs, first we check to see if it's due to lazy function resolution, +if so, we look up the return address of the function call (which was pushed onto +the stack by the call instruction). Given the return address of the call, we +consult a map to figure out which function was supposed to be called from that +location. + +If the function has not been code generated yet, it is at this time. Finally, +the EIP of the process is modified to point to the real function address, the +original call instruction is updated, and the SIGSEGV handler returns, causing +execution to start in the called function. Because we update the original call +instruction, we should only get at most one signal for each call site. + +Note that this approach does not work for indirect calls. The problem with +indirect calls is that taking the address of a function would not cause a fault +(it would simply copy null into a register), so we would only find out about the +problem when the indirect call itself was made. At this point we would have no +way of knowing what the intended function destination was. Because of this, we +immediately code generate functions whenever they have their address taken, +side-stepping the problem completely. + + +====================== +IV. Source Code Layout +====================== The LLVM-JIT is composed of source files primarily in the following locations: @@ -128,9 +160,9 @@ bunch of really trivial testcases that we should build up to supporting. -=================================================== -IV. Strange Things, or, Things That Should Be Known -=================================================== +================================================== +V. Strange Things, or, Things That Should Be Known +================================================== Representing memory in MachineInstrs ------------------------------------ @@ -154,7 +186,7 @@ ========================== -V. TODO / Future Projects +VI. TODO / Future Projects ========================== There are a large number of things remaining to do. Here is a partial list: @@ -162,13 +194,7 @@ Critical path: ------------- -0. Finish providing SSA form. This involves keeping track of some information - when instructions are added to the function, but should not affect that API - for creating new MInstructions or adding them to the program. 1. Finish dumb instruction selector -2. Write dumb register allocator -3. Write assembly language emitter -4. Write machine code emitter Next Phase: ----------- @@ -179,7 +205,7 @@ ------------------- 1. Implement lots of nifty runtime optimizations 2. Implement a static compiler backend for x86 (might come almost for free...) -3. Implement new spiffy targets: IA64? X86-64? M68k? Who knows... +3. Implement new targets: IA64? X86-64? M68k? Who knows... Infrastructure Improvements: ---------------------------- From brukman at cs.uiuc.edu Wed Dec 4 10:47:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 10:47:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200212041646.KAA15428@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.4 -> 1.5 --- Log message: Moved buildReg2RegClassMap() into from X86RegisterInfo to MRegisterInfo, since it is target-independent. --- Diffs of the changes: Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.4 llvm/include/llvm/Target/MRegisterInfo.h:1.5 --- llvm/include/llvm/Target/MRegisterInfo.h:1.4 Tue Dec 3 17:09:53 2002 +++ llvm/include/llvm/Target/MRegisterInfo.h Wed Dec 4 10:46:28 2002 @@ -61,7 +61,7 @@ virtual unsigned getDataSize() const { return 0; } - virtual void + void buildReg2RegClassMap(std::map& Reg2RegClassMap) const { @@ -146,7 +146,13 @@ virtual void buildReg2RegClassMap(std::map& - Reg2RegClassMap) const=0; + Reg2RegClassMap) const { + for (MRegisterInfo::const_iterator I = const_regclass_begin(), + E = const_regclass_end(); I != E; ++I) { + I->buildReg2RegClassMap(Reg2RegClassMap); + } + } + }; #endif From brukman at cs.uiuc.edu Wed Dec 4 10:48:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 10:48:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86RegisterInfo.h Message-ID: <200212041647.KAA15444@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.6 -> 1.7 X86RegisterInfo.h updated: 1.4 -> 1.5 --- Log message: Moved buildReg2RegClassMap() into from X86RegisterInfo to MRegisterInfo, since it is target-independent. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.6 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.7 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.6 Tue Dec 3 17:11:21 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Dec 4 10:47:03 2002 @@ -69,15 +69,3 @@ MRegisterInfo::NoRegister }; return CallerSaveRegs; } - -void -X86RegisterInfo::buildReg2RegClassMap -(std::map& Reg2RegClassMap) const -{ - for (MRegisterInfo::const_iterator I = const_regclass_begin(), - E = const_regclass_end(); I != E; ++I) - { - I->buildReg2RegClassMap(Reg2RegClassMap); - } -} Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.4 llvm/lib/Target/X86/X86RegisterInfo.h:1.5 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.4 Tue Dec 3 17:11:21 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.h Wed Dec 4 10:47:04 2002 @@ -43,9 +43,6 @@ unsigned getNumRegClasses() const; - void buildReg2RegClassMap(std::map& - Reg2RegClassMap) const; - }; #endif From lattner at cs.uiuc.edu Wed Dec 4 11:01:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 11:01:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/simplesttest.ll Message-ID: <200212041700.LAA16014@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: simplesttest.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: From brukman at cs.uiuc.edu Wed Dec 4 11:09:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 11:09:00 2002 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200212041708.LAA16366@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.68 -> 1.69 --- Log message: On `make clean', kill the core files produced, which are of the form: core.### where ### is the process ID. We use core.[0-9][0-9]* to avoid killing core.c, core.cpp, and core.h files which may be part of benchmarks. --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.68 llvm/Makefile.common:1.69 --- llvm/Makefile.common:1.68 Mon Nov 4 14:50:33 2002 +++ llvm/Makefile.common Wed Dec 4 11:08:15 2002 @@ -470,7 +470,7 @@ # 'make clean' nukes the tree clean:: $(VERB) rm -rf $(BUILD_ROOT)/Debug $(BUILD_ROOT)/Release $(BUILD_ROOT)/Profile $(BUILD_ROOT)/Depend - $(VERB) rm -f core *.o *.d *.so *~ *.flc + $(VERB) rm -f core core.[0-9][0-9]* *.o *.d *.so *~ *.flc # If dependancies were generated for the file that included this file, # include the dependancies now... From brukman at cs.uiuc.edu Wed Dec 4 11:15:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 11:15:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200212041714.LAA17394@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.5 -> 1.6 --- Log message: storeReg2RegOffset() and loadRegOffset2Reg() now take the iterator by value instead of by reference, since they return the modified iterator. --- Diffs of the changes: Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.5 llvm/include/llvm/Target/MRegisterInfo.h:1.6 --- llvm/include/llvm/Target/MRegisterInfo.h:1.5 Wed Dec 4 10:46:28 2002 +++ llvm/include/llvm/Target/MRegisterInfo.h Wed Dec 4 11:14:11 2002 @@ -119,13 +119,13 @@ virtual MachineBasicBlock::iterator storeReg2RegOffset(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, + MachineBasicBlock::iterator MBBI, unsigned SrcReg, unsigned DestReg, unsigned ImmOffset, unsigned dataSize) const = 0; virtual MachineBasicBlock::iterator loadRegOffset2Reg(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, + MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, unsigned ImmOffset, unsigned dataSize) const = 0; From brukman at cs.uiuc.edu Wed Dec 4 11:15:04 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 11:15:04 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86RegisterInfo.h Message-ID: <200212041714.LAA17610@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.7 -> 1.8 X86RegisterInfo.h updated: 1.5 -> 1.6 --- Log message: storeReg2RegOffset() and loadRegOffset2Reg() now take the iterator by value instead of by reference, since they return the modified iterator. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.7 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.8 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.7 Wed Dec 4 10:47:03 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Dec 4 11:14:13 2002 @@ -26,7 +26,7 @@ MachineBasicBlock::iterator X86RegisterInfo::storeReg2RegOffset(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, + MachineBasicBlock::iterator MBBI, unsigned SrcReg, unsigned DestReg, unsigned ImmOffset, unsigned dataSize) const @@ -38,7 +38,7 @@ MachineBasicBlock::iterator X86RegisterInfo::loadRegOffset2Reg(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, + MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, unsigned ImmOffset, unsigned dataSize) const Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.5 llvm/lib/Target/X86/X86RegisterInfo.h:1.6 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.5 Wed Dec 4 10:47:04 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.h Wed Dec 4 11:14:13 2002 @@ -19,13 +19,13 @@ MachineBasicBlock::iterator storeReg2RegOffset(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, + MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, unsigned ImmOffset, unsigned dataSize) const; MachineBasicBlock::iterator loadRegOffset2Reg(MachineBasicBlock *MBB, - MachineBasicBlock::iterator &MBBI, + MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, unsigned ImmOffset, unsigned dataSize) const; From lattner at cs.uiuc.edu Wed Dec 4 11:16:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 11:16:00 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/test-arith.ll test-branch.ll test-call.ll test-loadstore.ll test-logical.ll test-ret.ll Message-ID: <200212041715.LAA17925@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: test-arith.ll updated: 1.3 -> 1.4 test-branch.ll updated: 1.2 -> 1.3 test-call.ll updated: 1.1 -> 1.2 test-loadstore.ll updated: 1.1 -> 1.2 test-logical.ll updated: 1.1 -> 1.2 test-ret.ll updated: 1.1 -> 1.2 --- Log message: Add main functions to benchmarks --- Diffs of the changes: Index: llvm/test/Regression/Jello/test-arith.ll diff -u llvm/test/Regression/Jello/test-arith.ll:1.3 llvm/test/Regression/Jello/test-arith.ll:1.4 --- llvm/test/Regression/Jello/test-arith.ll:1.3 Sat Nov 2 14:54:11 2002 +++ llvm/test/Regression/Jello/test-arith.ll Wed Dec 4 11:15:07 2002 @@ -1,5 +1,5 @@ -void %test() { +void %main() { %A = add sbyte 0, 12 %B = sub sbyte %A, %A %C = mul sbyte %B, %B Index: llvm/test/Regression/Jello/test-branch.ll diff -u llvm/test/Regression/Jello/test-branch.ll:1.2 llvm/test/Regression/Jello/test-branch.ll:1.3 --- llvm/test/Regression/Jello/test-branch.ll:1.2 Thu Nov 21 17:30:08 2002 +++ llvm/test/Regression/Jello/test-branch.ll Wed Dec 4 11:15:07 2002 @@ -2,7 +2,7 @@ void %main() { br label %Test Test: - %X = seteq int 0, 4 + %X = setne int 0, 4 br bool %X, label %Test, label %Label Label: ret void Index: llvm/test/Regression/Jello/test-call.ll diff -u llvm/test/Regression/Jello/test-call.ll:1.1 llvm/test/Regression/Jello/test-call.ll:1.2 --- llvm/test/Regression/Jello/test-call.ll:1.1 Tue Dec 3 14:30:03 2002 +++ llvm/test/Regression/Jello/test-call.ll Wed Dec 4 11:15:07 2002 @@ -1,7 +1,7 @@ -declare void %foo() +declare void %exit(int) -void %test1() { - call void %foo() +void %main() { + call void %exit(int 1) ret void } Index: llvm/test/Regression/Jello/test-loadstore.ll diff -u llvm/test/Regression/Jello/test-loadstore.ll:1.1 llvm/test/Regression/Jello/test-loadstore.ll:1.2 --- llvm/test/Regression/Jello/test-loadstore.ll:1.1 Sun Nov 17 15:06:13 2002 +++ llvm/test/Regression/Jello/test-loadstore.ll Wed Dec 4 11:15:07 2002 @@ -10,3 +10,11 @@ store int %V, int* %P ret void } + +void %main() { + %A = alloca sbyte + %B = alloca short + %C = alloca int + call void %test(sbyte* %A, short* %B, int* %C) + ret void +} Index: llvm/test/Regression/Jello/test-logical.ll diff -u llvm/test/Regression/Jello/test-logical.ll:1.1 llvm/test/Regression/Jello/test-logical.ll:1.2 --- llvm/test/Regression/Jello/test-logical.ll:1.1 Sat Nov 2 14:04:02 2002 +++ llvm/test/Regression/Jello/test-logical.ll Wed Dec 4 11:15:07 2002 @@ -1,5 +1,5 @@ -void %test() { +void %main() { %A = and sbyte 4, 8 %B = or sbyte %A, 7 %C = xor sbyte %B, %A Index: llvm/test/Regression/Jello/test-ret.ll diff -u llvm/test/Regression/Jello/test-ret.ll:1.1 llvm/test/Regression/Jello/test-ret.ll:1.2 --- llvm/test/Regression/Jello/test-ret.ll:1.1 Thu Nov 21 11:18:37 2002 +++ llvm/test/Regression/Jello/test-ret.ll Wed Dec 4 11:15:07 2002 @@ -5,7 +5,7 @@ ubyte %test() { ret ubyte 1 } short %test() { ret short -1 } ushort %test() { ret ushort 65535 } -int %test() { ret int -1 } +int %main() { ret int -1 } uint %test() { ret uint 4 } ;long %test() { ret void } ;ulong %test() { ret void } From lattner at cs.uiuc.edu Wed Dec 4 11:16:03 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 11:16:03 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212041715.LAA17978@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.47 -> 1.48 --- Log message: Avoid crashing on Arguments, just silently miscompile --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.47 llvm/lib/Target/X86/InstSelectSimple.cpp:1.48 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.47 Wed Dec 4 00:56:56 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Dec 4 11:15:34 2002 @@ -138,6 +138,8 @@ } else if (GlobalValue *GV = dyn_cast(V)) { // Move the address of the global into the register BuildMI(BB, X86::MOVir32, 1, Reg).addReg(GV); + } else if (Argument *A = dyn_cast(V)) { + std::cerr << "ERROR: Arguments not implemented in SimpleInstSel\n"; } else { assert(0 && "Don't know how to handle a value of this type!"); } From lattner at cs.uiuc.edu Wed Dec 4 11:19:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 11:19:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212041718.LAA18418@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.48 -> 1.49 --- Log message: Remove think-o assertion --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.48 llvm/lib/Target/X86/InstSelectSimple.cpp:1.49 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.48 Wed Dec 4 11:15:34 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Dec 4 11:18:30 2002 @@ -140,8 +140,6 @@ BuildMI(BB, X86::MOVir32, 1, Reg).addReg(GV); } else if (Argument *A = dyn_cast(V)) { std::cerr << "ERROR: Arguments not implemented in SimpleInstSel\n"; - } else { - assert(0 && "Don't know how to handle a value of this type!"); } return Reg; From lattner at cs.uiuc.edu Wed Dec 4 11:29:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 11:29:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp Message-ID: <200212041728.LAA20617@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.21 -> 1.22 --- Log message: Avoid bad assertion --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.21 llvm/lib/Target/X86/Printer.cpp:1.22 --- llvm/lib/Target/X86/Printer.cpp:1.21 Wed Dec 4 00:45:19 2002 +++ llvm/lib/Target/X86/Printer.cpp Wed Dec 4 11:28:40 2002 @@ -183,7 +183,7 @@ assert(isReg(MI->getOperand(0)) && (MI->getNumOperands() == 1 || (MI->getNumOperands() == 2 && - (MI->getOperand(1).getVRegValue() || + (MI->getOperand(1).getVRegValueOrNull() || isImmediate(MI->getOperand(1))))) && "Illegal form for AddRegFrm instruction!"); From lattner at cs.uiuc.edu Wed Dec 4 11:34:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 11:34:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/MachineCodeEmitter.cpp Printer.cpp Message-ID: <200212041733.LAA21221@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: MachineCodeEmitter.cpp updated: 1.5 -> 1.6 Printer.cpp updated: 1.22 -> 1.23 --- Log message: Fix bogus assertion failures --- Diffs of the changes: Index: llvm/lib/Target/X86/MachineCodeEmitter.cpp diff -u llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.5 llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.6 --- llvm/lib/Target/X86/MachineCodeEmitter.cpp:1.5 Wed Dec 4 00:45:19 2002 +++ llvm/lib/Target/X86/MachineCodeEmitter.cpp Wed Dec 4 11:32:52 2002 @@ -225,7 +225,7 @@ MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg())); if (MI.getNumOperands() == 2) { unsigned Size = 4; - if (Value *V = MI.getOperand(1).getVRegValue()) { + if (Value *V = MI.getOperand(1).getVRegValueOrNull()) { assert(Size == 4 && "Don't know how to emit non-pointer values!"); MCE.emitGlobalAddress(cast(V)); } else { Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.22 llvm/lib/Target/X86/Printer.cpp:1.23 --- llvm/lib/Target/X86/Printer.cpp:1.22 Wed Dec 4 11:28:40 2002 +++ llvm/lib/Target/X86/Printer.cpp Wed Dec 4 11:32:52 2002 @@ -96,7 +96,7 @@ const MRegisterInfo &RI) { switch (MO.getType()) { case MachineOperand::MO_VirtualRegister: - if (Value *V = MO.getVRegValue()) { + if (Value *V = MO.getVRegValueOrNull()) { O << "<" << V->getName() << ">"; return; } From lattner at cs.uiuc.edu Wed Dec 4 11:36:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 11:36:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/simpletest.ll Message-ID: <200212041735.LAA21638@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: simpletest.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: From brukman at cs.uiuc.edu Wed Dec 4 13:16:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 13:16:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200212041915.NAA24504@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def updated: 1.31 -> 1.32 --- Log message: Added instructions to add/subtract imm32 to/from a reg32. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.31 llvm/lib/Target/X86/X86InstrInfo.def:1.32 --- llvm/lib/Target/X86/X86InstrInfo.def:1.31 Tue Dec 3 16:50:02 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Wed Dec 4 13:15:22 2002 @@ -88,9 +88,11 @@ I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 += R8 I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 += R16 I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 += R32 +I(ADDri32 , "add", 0x81, 0, X86II::MRMS0r, NoImpRegs, NoImpRegs) // R32 += imm32 I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 -= R8 I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 -= R16 I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 -= R32 +I(SUBri32 , "sub", 0x81, 0, X86II::MRMS5r, NoImpRegs, NoImpRegs) // R32 -= imm32 I(MULrr8 , "mulb", 0xF6, 0, X86II::MRMS4r | X86II::Void, O_AL, O_AX) // AX = AL*R8 I(MULrr16 , "mulw", 0xF7, 0, X86II::MRMS4r | X86II::Void | // DX:AX= AX*R16 X86II::OpSize, O_AX, T_AXDX) From brukman at cs.uiuc.edu Wed Dec 4 13:24:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 13:24:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212041923.NAA25517@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.49 -> 1.50 --- Log message: Adjust the stack pointer after a function call, proportional to the number of arguments pushed onto the stack. --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.49 llvm/lib/Target/X86/InstSelectSimple.cpp:1.50 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.49 Wed Dec 4 11:18:30 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Dec 4 13:22:53 2002 @@ -393,6 +393,9 @@ void ISel::visitCallInst (CallInst & CI) { + // keep a counter of how many bytes we pushed on the stack + unsigned bytesPushed = 0; + // Push the arguments on the stack in reverse order, as specified by // the ABI. for (unsigned i = CI.getNumOperands()-1; i >= 1; --i) @@ -406,11 +409,13 @@ // then push EAX. promote32 (X86::EAX, v); BuildMI (BB, X86::PUSHr32, 1).addReg (X86::EAX); + bytesPushed += 4; break; case cInt: case cFloat: { unsigned Reg = getReg(v); BuildMI (BB, X86::PUSHr32, 1).addReg(Reg); + bytesPushed += 4; break; } default: @@ -421,6 +426,10 @@ } // Emit a CALL instruction with PC-relative displacement. BuildMI (BB, X86::CALLpcrel32, 1).addPCDisp (CI.getCalledValue ()); + + // Adjust the stack by `bytesPushed' amount if non-zero + if (bytesPushed > 0) + BuildMI (BB, X86::ADDri32, 2).addReg(X86::ESP).addZImm(bytesPushed); } /// visitSimpleBinary - Implement simple binary operators for integral types... From brukman at cs.uiuc.edu Wed Dec 4 13:25:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 13:25:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocSimple.cpp Message-ID: <200212041924.NAA25551@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocSimple.cpp updated: 1.3 -> 1.4 --- Log message: Fun arithmetic with iterators aimed at fixing a bug: inserting instructions after the *current* instruction while keeping the iterator in the same 'logical' place. --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocSimple.cpp diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.3 llvm/lib/CodeGen/RegAllocSimple.cpp:1.4 --- llvm/lib/CodeGen/RegAllocSimple.cpp:1.3 Tue Dec 3 17:15:19 2002 +++ llvm/lib/CodeGen/RegAllocSimple.cpp Wed Dec 4 13:24:45 2002 @@ -29,7 +29,8 @@ unsigned NumBytesAllocated, ByteAlignment; // Maps SSA Regs => offsets on the stack where these values are stored - std::map RegMap; // FIXME: change name to VirtReg2OffsetMap + // FIXME: change name to VirtReg2OffsetMap + std::map RegMap; // Maps SSA Regs => physical regs std::map SSA2PhysRegMap; @@ -235,7 +236,8 @@ if (op.opIsDef()) { physReg = getFreeReg(virtualReg); MachineBasicBlock::iterator J = I; - I = saveVirtRegToStack(J, virtualReg, physReg); + J = saveVirtRegToStack(++J, virtualReg, physReg); + I = --J; } else { I = moveUseToReg(I, virtualReg, physReg); } From lattner at cs.uiuc.edu Wed Dec 4 17:46:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 17:46:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212042345.RAA03826@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.50 -> 1.51 --- Log message: Implement initial support for return values from call instructions --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.50 llvm/lib/Target/X86/InstSelectSimple.cpp:1.51 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.50 Wed Dec 4 13:22:53 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Dec 4 17:45:28 2002 @@ -430,6 +430,20 @@ // Adjust the stack by `bytesPushed' amount if non-zero if (bytesPushed > 0) BuildMI (BB, X86::ADDri32, 2).addReg(X86::ESP).addZImm(bytesPushed); + + // If there is a return value, scavenge the result from the location the call + // leaves it in... + // + switch (getClass(CI.getType())) { + case cInt: + BuildMI(BB, X86::MOVrr32, 1, getReg(CI)).addReg(X86::EAX); + break; + + default: + std::cerr << "Cannot get return value for call of type '" + << *CI.getType() << "'\n"; + visitInstruction(CI); + } } /// visitSimpleBinary - Implement simple binary operators for integral types... From lattner at cs.uiuc.edu Wed Dec 4 17:51:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 17:51:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212042350.RAA04459@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.51 -> 1.52 --- Log message: Fix handling of function calls that return void --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.51 llvm/lib/Target/X86/InstSelectSimple.cpp:1.52 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.51 Wed Dec 4 17:45:28 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Dec 4 17:50:28 2002 @@ -434,15 +434,17 @@ // If there is a return value, scavenge the result from the location the call // leaves it in... // - switch (getClass(CI.getType())) { - case cInt: - BuildMI(BB, X86::MOVrr32, 1, getReg(CI)).addReg(X86::EAX); - break; - - default: - std::cerr << "Cannot get return value for call of type '" - << *CI.getType() << "'\n"; - visitInstruction(CI); + if (CI.getType() != Type::VoidTy) { + switch (getClass(CI.getType())) { + case cInt: + BuildMI(BB, X86::MOVrr32, 1, getReg(CI)).addReg(X86::EAX); + break; + + default: + std::cerr << "Cannot get return value for call of type '" + << *CI.getType() << "'\n"; + visitInstruction(CI); + } } } From lattner at cs.uiuc.edu Wed Dec 4 17:52:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Dec 4 17:52:00 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/simplesttest.ll Message-ID: <200212042351.RAA04710@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: simplesttest.ll updated: 1.1 -> 1.2 --- Log message: Fix testcase --- Diffs of the changes: Index: llvm/test/Regression/Jello/simplesttest.ll diff -u llvm/test/Regression/Jello/simplesttest.ll:1.1 llvm/test/Regression/Jello/simplesttest.ll:1.2 --- llvm/test/Regression/Jello/simplesttest.ll:1.1 Wed Dec 4 11:00:25 2002 +++ llvm/test/Regression/Jello/simplesttest.ll Wed Dec 4 17:51:44 2002 @@ -1,6 +1,6 @@ %X = global int 7 -%msg = internal global [13 x sbyte] c"Hello World\0D\00" +%msg = internal global [13 x sbyte] c"Hello World\0A\00" implementation From brukman at cs.uiuc.edu Wed Dec 4 17:57:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 17:57:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200212042356.RAA05088@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.6 -> 1.7 --- Log message: Added prototypes for emitting prologue and epilogue for function code generation. --- Diffs of the changes: Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.6 llvm/include/llvm/Target/MRegisterInfo.h:1.7 --- llvm/include/llvm/Target/MRegisterInfo.h:1.6 Wed Dec 4 11:14:11 2002 +++ llvm/include/llvm/Target/MRegisterInfo.h Wed Dec 4 17:55:56 2002 @@ -129,6 +129,16 @@ unsigned DestReg, unsigned SrcReg, unsigned ImmOffset, unsigned dataSize) const = 0; + virtual MachineBasicBlock::iterator + emitPrologue(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned numBytes) const = 0; + + virtual MachineBasicBlock::iterator + emitEpilogue(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned numBytes) const = 0; + virtual const unsigned* getCalleeSaveRegs() const = 0; virtual const unsigned* getCallerSaveRegs() const = 0; From brukman at cs.uiuc.edu Wed Dec 4 17:57:04 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 17:57:04 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.def Message-ID: <200212042356.RAA05103@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.def updated: 1.32 -> 1.33 --- Log message: Added push and pop instructions. --- Diffs of the changes: Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.32 llvm/lib/Target/X86/X86InstrInfo.def:1.33 --- llvm/lib/Target/X86/X86InstrInfo.def:1.32 Wed Dec 4 13:15:22 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Wed Dec 4 17:56:26 2002 @@ -82,7 +82,8 @@ X86II::OpSize, NoImpRegs, NoImpRegs) I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void, NoImpRegs, NoImpRegs) // [mem] = R32 -I(PUSHr32 , "pushl", 0x50, 0, X86II::AddRegFrm | X86II::Void, NoImpRegs, NoImpRegs) +I(PUSHr32 , "pushl", 0x50, 0, X86II::AddRegFrm | X86II::Void, NoImpRegs, NoImpRegs) +I(POPr32 , "popl", 0x58, 0, X86II::AddRegFrm, NoImpRegs, NoImpRegs) // Arithmetic instructions I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 += R8 From brukman at cs.uiuc.edu Wed Dec 4 17:58:00 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 17:58:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp X86RegisterInfo.h Message-ID: <200212042357.RAA05117@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.8 -> 1.9 X86RegisterInfo.h updated: 1.6 -> 1.7 --- Log message: Implemented functions for emitting prologues and epilogues; removed EBP from the list of callee-saved registers (it isn't one). --- Diffs of the changes: Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.8 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.9 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.8 Wed Dec 4 11:14:13 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Dec 4 17:57:03 2002 @@ -58,7 +58,7 @@ } const unsigned* X86RegisterInfo::getCalleeSaveRegs() const { - static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX, X86::EBP, + static const unsigned CalleeSaveRegs[] = { X86::ESI, X86::EDI, X86::EBX, MRegisterInfo::NoRegister }; return CalleeSaveRegs; } @@ -68,4 +68,57 @@ static const unsigned CallerSaveRegs[] = { X86::EAX, X86::ECX, X86::EDX, MRegisterInfo::NoRegister }; return CallerSaveRegs; +} + +MachineBasicBlock::iterator +X86RegisterInfo::emitPrologue(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned numBytes) const +{ + MachineInstr *MI; + + // PUSH ebp + MI = BuildMI (X86::PUSHr32, 1).addReg(X86::EBP); + MBBI = ++(MBB->insert(MBBI, MI)); + + // MOV ebp, esp + MI = BuildMI (X86::MOVrr32, 2).addReg(X86::EBP).addReg(X86::ESP); + MBBI = ++(MBB->insert(MBBI, MI)); + + // adjust stack pointer + MI = BuildMI(X86::SUBri32, 2).addReg(X86::ESP).addZImm(numBytes); + MBBI = ++(MBB->insert(MBBI, MI)); + + // PUSH all callee-save registers + const unsigned* regs = getCalleeSaveRegs(); + while (*regs) { + MI = BuildMI(X86::PUSHr32, 1).addReg(*regs); + MBBI = ++(MBB->insert(MBBI, MI)); + ++regs; + } + + return MBBI; +} + +MachineBasicBlock::iterator +X86RegisterInfo::emitEpilogue(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned numBytes) const +{ + MachineInstr *MI; + + // POP all callee-save registers in REVERSE ORDER + static const unsigned regs[] = { X86::EBX, X86::EDI, X86::ESI, + MRegisterInfo::NoRegister }; + unsigned idx = 0; + while (regs[idx]) { + MI = BuildMI(X86::POPr32, 1).addReg(regs[idx++]); + MBBI = ++(MBB->insert(MBBI, MI)); + } + + // insert LEAVE + MI = BuildMI(X86::LEAVE, 0); + MBBI = ++(MBB->insert(MBBI, MI)); + + return MBBI; } Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.6 llvm/lib/Target/X86/X86RegisterInfo.h:1.7 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.6 Wed Dec 4 11:14:13 2002 +++ llvm/lib/Target/X86/X86RegisterInfo.h Wed Dec 4 17:57:03 2002 @@ -35,6 +35,14 @@ const unsigned* getCalleeSaveRegs() const; const unsigned* getCallerSaveRegs() const; + MachineBasicBlock::iterator emitPrologue(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned numBytes) const; + + MachineBasicBlock::iterator emitEpilogue(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned numBytes) const; + /// Returns register class appropriate for input SSA register /// const TargetRegisterClass *getClassForReg(unsigned Reg) const; From brukman at cs.uiuc.edu Wed Dec 4 17:59:01 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 17:59:01 2002 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/RegAllocSimple.cpp Message-ID: <200212042358.RAA05130@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: RegAllocSimple.cpp updated: 1.4 -> 1.5 --- Log message: Added code generation for function prologues and epilogues. --- Diffs of the changes: Index: llvm/lib/CodeGen/RegAllocSimple.cpp diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.4 llvm/lib/CodeGen/RegAllocSimple.cpp:1.5 --- llvm/lib/CodeGen/RegAllocSimple.cpp:1.4 Wed Dec 4 13:24:45 2002 +++ llvm/lib/CodeGen/RegAllocSimple.cpp Wed Dec 4 17:58:08 2002 @@ -12,6 +12,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/Target/MachineInstrInfo.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/MachineRegInfo.h" #include "llvm/Target/TargetMachine.h" @@ -73,6 +74,12 @@ RegClassIdx.clear(); } + void cleanupAfterFunction() { + RegMap.clear(); + SSA2PhysRegMap.clear(); + NumBytesAllocated = 0; + } + /// Moves value from memory into that register MachineBasicBlock::iterator moveUseToReg (MachineBasicBlock::iterator I, unsigned VirtReg, @@ -150,7 +157,7 @@ // Add move instruction(s) return RegInfo->loadRegOffset2Reg(CurrMBB, I, PhysReg, RegInfo->getFramePointer(), - stackOffset, regClass->getDataSize()); + -stackOffset, regClass->getDataSize()); } MachineBasicBlock::iterator @@ -160,12 +167,12 @@ const TargetRegisterClass* regClass = MF->getRegClass(VirtReg); assert(regClass); - unsigned offset = allocateStackSpaceFor(VirtReg, regClass); + unsigned stackOffset = allocateStackSpaceFor(VirtReg, regClass); // Add move instruction(s) return RegInfo->storeReg2RegOffset(CurrMBB, I, PhysReg, RegInfo->getFramePointer(), - offset, regClass->getDataSize()); + -stackOffset, regClass->getDataSize()); } MachineBasicBlock::iterator @@ -184,23 +191,12 @@ } bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) { - RegMap.clear(); + cleanupAfterFunction(); + unsigned virtualReg, physReg; DEBUG(std::cerr << "Machine Function " << "\n"); MF = &Fn; -#if 0 - // FIXME: add prolog. we should preserve callee-save registers... - MachineFunction::iterator Fi = Fn.begin(); - MachineBasicBlock &MBB = *Fi; - MachineBasicBlock::iterator MBBi = MBB.begin() - const unsigned* calleeSaveRegs = tm.getCalleeSaveRegs(); - while (*calleeSaveRegs) { - //MBBi = saveRegToStack(MBBi, *calleeSaveRegs, - ++calleeSaveRegs; - } -#endif - for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); MBB != MBBe; ++MBB) { @@ -252,7 +248,26 @@ } - // FIXME: add epilog. we should preserve callee-save registers... + // add prologue we should preserve callee-save registers... + MachineFunction::iterator Fi = Fn.begin(); + MachineBasicBlock *MBB = Fi; + MachineBasicBlock::iterator MBBi = MBB->begin(); + RegInfo->emitPrologue(MBB, MBBi, NumBytesAllocated); + + // add epilogue to restore the callee-save registers + // loop over the basic block + for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); + MBB != MBBe; ++MBB) + { + // check if last instruction is a RET + MachineBasicBlock::iterator I = (*MBB).end(); + MachineInstr *MI = *(--I); + const MachineInstrInfo &MII = TM.getInstrInfo(); + if (MII.isReturn(MI->getOpcode())) { + // this block has a return instruction, add epilogue + RegInfo->emitEpilogue(MBB, I, NumBytesAllocated); + } + } return false; // We never modify the LLVM itself. } From brukman at cs.uiuc.edu Wed Dec 4 17:59:04 2002 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Dec 4 17:59:04 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Jello/simplesttest.ll Message-ID: <200212042358.RAA05142@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Jello: simplesttest.ll updated: 1.2 -> 1.3 --- Log message: Return 0 to make it into a fully-functioning "Hello, World!" test case. --- Diffs of the changes: Index: llvm/test/Regression/Jello/simplesttest.ll diff -u llvm/test/Regression/Jello/simplesttest.ll:1.2 llvm/test/Regression/Jello/simplesttest.ll:1.3 --- llvm/test/Regression/Jello/simplesttest.ll:1.2 Wed Dec 4 17:51:44 2002 +++ llvm/test/Regression/Jello/simplesttest.ll Wed Dec 4 17:58:41 2002 @@ -12,8 +12,8 @@ ret void } -void %main() { +int %main() { call void %bar() - ret void + ret int 0 } From lattner at cs.uiuc.edu Thu Dec 5 02:31:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 02:31:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp X86InstrInfo.def X86InstrInfo.h Message-ID: <200212050830.CAA06095@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.23 -> 1.24 X86InstrInfo.def updated: 1.33 -> 1.34 X86InstrInfo.h updated: 1.15 -> 1.16 --- Log message: Target/X86/Printer.cpp: Add sizePtr function, and use it instead of " PTR " string when emitting assembly. Target/X86/X86InstrInfo.def: Tidy up a bit: Squashed everything down to 118 chars wide, wrapping lines so that comment is at the same point on each line. Rename "NoImpRegs" as "NoIR". (most instructions have NoImpRegs twice on a line, so this saves 10 columns). Also, annotate various instructions with flags for size of memory operand. (MemArg16, MemArg32, MemArg64, etc.) Target/X86/X86InstrInfo.h: Define flags for size of memory operand. (MemArg16, MemArg32, MemArg64, etc.) --- Diffs of the changes: Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.23 llvm/lib/Target/X86/Printer.cpp:1.24 --- llvm/lib/Target/X86/Printer.cpp:1.23 Wed Dec 4 11:32:52 2002 +++ llvm/lib/Target/X86/Printer.cpp Thu Dec 5 02:30:40 2002 @@ -119,6 +119,18 @@ } } +static const std::string sizePtr (const MachineInstrDescriptor &Desc) { + switch (Desc.TSFlags & X86II::MemArgMask) { + case X86II::MemArg8: return "BYTE PTR"; + case X86II::MemArg16: return "WORD PTR"; + case X86II::MemArg32: return "DWORD PTR"; + case X86II::MemArg64: return "QWORD PTR"; + case X86II::MemArg80: return "XWORD PTR"; + case X86II::MemArg128: return "128BIT PTR"; // dunno what the real one is + default: return " PTR"; // crack being smoked + } +} + static void printMemReference(std::ostream &O, const MachineInstr *MI, unsigned Op, const MRegisterInfo &RI) { assert(isMem(MI, Op) && "Invalid memory reference!"); @@ -233,7 +245,7 @@ assert(isMem(MI, 0) && MI->getNumOperands() == 4+1 && isReg(MI->getOperand(4)) && "Bad format for MRMDestMem!"); - O << getName(MI->getOpCode()) << " PTR "; + O << getName(MI->getOpCode()) << " " << sizePtr (Desc) << " "; printMemReference(O, MI, 0, RI); O << ", "; printOp(O, MI->getOperand(4), RI); @@ -283,7 +295,7 @@ O << getName(MI->getOpCode()) << " "; printOp(O, MI->getOperand(0), RI); - O << ", PTR "; + O << ", " << sizePtr (Desc) << " "; printMemReference(O, MI, MI->getNumOperands()-4, RI); O << "\n"; return; Index: llvm/lib/Target/X86/X86InstrInfo.def diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.33 llvm/lib/Target/X86/X86InstrInfo.def:1.34 --- llvm/lib/Target/X86/X86InstrInfo.def:1.33 Wed Dec 4 17:56:26 2002 +++ llvm/lib/Target/X86/X86InstrInfo.def Thu Dec 5 02:30:40 2002 @@ -23,17 +23,18 @@ #endif // Implicit register usage info: O_ is for one register, T_ is for two registers -IMPREGSLIST(NoImpRegs, 0) -IMPREGSLIST(O_AL , X86::AL , 0) -IMPREGSLIST(O_AH , X86::AH , 0) -IMPREGSLIST(O_CL , X86::CL , 0) -IMPREGSLIST(O_AX , X86::AX , 0) -IMPREGSLIST(O_DX , X86::DX , 0) -IMPREGSLIST(O_EAX , X86::EAX, 0) -IMPREGSLIST(O_EDX , X86::EDX, 0) -IMPREGSLIST(O_EBP , X86::EBP, 0) -IMPREGSLIST(T_AXDX , X86::AX , X86::DX , 0) -IMPREGSLIST(T_EAXEDX , X86::EAX, X86::EDX, 0) +// NoIR means the instruction does not use implicit registers, in this form. +IMPREGSLIST(NoIR , 0) +IMPREGSLIST(O_AL , X86::AL , 0) +IMPREGSLIST(O_AH , X86::AH , 0) +IMPREGSLIST(O_CL , X86::CL , 0) +IMPREGSLIST(O_AX , X86::AX , 0) +IMPREGSLIST(O_DX , X86::DX , 0) +IMPREGSLIST(O_EAX, X86::EAX, 0) +IMPREGSLIST(O_EDX, X86::EDX, 0) +IMPREGSLIST(O_EBP, X86::EBP, 0) +IMPREGSLIST(T_AXDX , X86::AX , X86::DX , 0) +IMPREGSLIST(T_EAXEDX, X86::EAX, X86::EDX, 0) #undef IMPREGSLIST @@ -52,137 +53,145 @@ // // The first instruction must always be the PHI instruction: -I(PHI , "phi", 0, 0, 0, NoImpRegs, NoImpRegs) +I(PHI , "phi", 0, 0, 0, NoIR, NoIR) // The second instruction must always be the noop instruction: -I(NOOP , "nop", 0x90, 0, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // nop +I(NOOP , "nop", 0x90, 0, X86II::RawFrm | X86II::Void, NoIR, NoIR) // nop // Flow control instructions -I(RET , "ret", 0xC3, M_RET_FLAG, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // ret -I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::RawFrm | X86II::Void, NoImpRegs, NoImpRegs) // jmp foo -I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void, NoImpRegs, NoImpRegs) -I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void, NoImpRegs, NoImpRegs) -I(CALLpcrel32 , "call", 0xE8, M_BRANCH_FLAG, X86II::Void, NoImpRegs, NoImpRegs) +I(RET , "ret", 0xC3, M_RET_FLAG, X86II::RawFrm | X86II::Void, NoIR, NoIR) // ret +I(JMP , "jmp", 0xE9, M_BRANCH_FLAG, X86II::RawFrm | X86II::Void, NoIR, NoIR) // jmp foo +I(JNE , "jne", 0x85, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void, NoIR, + NoIR) // jne foo +I(JE , "je", 0x84, M_BRANCH_FLAG, X86II::RawFrm | X86II::TB | X86II::Void, NoIR, + NoIR) // je foo +I(CALLpcrel32 , "call", 0xE8, M_BRANCH_FLAG, X86II::Void, NoIR, NoIR) // call pc+42 // Misc instructions -I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm, O_EBP, O_EBP) // leave +I(LEAVE , "leave", 0xC9, 0, X86II::RawFrm, O_EBP, O_EBP) // leave // Move instructions -I(MOVrr8 , "movb", 0x88, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 = R8 -I(MOVrr16 , "movw", 0x89, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 = R16 -I(MOVrr32 , "movl", 0x89, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 = R32 -I(MOVir8 , "movb", 0xB0, 0, X86II::AddRegFrm, NoImpRegs, NoImpRegs) // R8 = imm8 -I(MOVir16 , "movw", 0xB8, 0, X86II::AddRegFrm | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 = imm16 -I(MOVir32 , "movl", 0xB8, 0, X86II::AddRegFrm, NoImpRegs, NoImpRegs) // R32 = imm32 -I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem, NoImpRegs, NoImpRegs) // R8 = [mem] -I(MOVmr16 , "movw", 0x8B, 0, X86II::MRMSrcMem | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 = [mem] -I(MOVmr32 , "movl", 0x8B, 0, X86II::MRMSrcMem, NoImpRegs, NoImpRegs) // R32 = [mem] -I(MOVrm8 , "movb", 0x88, 0, X86II::MRMDestMem | X86II::Void, NoImpRegs, NoImpRegs) // [mem] = R8 -I(MOVrm16 , "movw", 0x89, 0, X86II::MRMDestMem | X86II::Void | // [mem] = R16 - X86II::OpSize, NoImpRegs, NoImpRegs) -I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void, NoImpRegs, NoImpRegs) // [mem] = R32 +I(MOVrr8 , "movb", 0x88, 0, X86II::MRMDestReg, NoIR, NoIR) // R8 = R8 +I(MOVrr16 , "movw", 0x89, 0, X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // R16 = R16 +I(MOVrr32 , "movl", 0x89, 0, X86II::MRMDestReg, NoIR, NoIR) // R32 = R32 +I(MOVir8 , "movb", 0xB0, 0, X86II::AddRegFrm, NoIR, NoIR) // R8 = imm8 +I(MOVir16 , "movw", 0xB8, 0, X86II::AddRegFrm | X86II::OpSize, NoIR, NoIR) // R16 = imm16 +I(MOVir32 , "movl", 0xB8, 0, X86II::AddRegFrm, NoIR, NoIR) // R32 = imm32 +I(MOVmr8 , "movb", 0x8A, 0, X86II::MRMSrcMem | X86II::MemArg8, NoIR, NoIR) // R8 = [mem] +I(MOVmr16 , "movw", 0x8B, 0, X86II::MRMSrcMem | X86II::OpSize | + X86II::MemArg16, NoIR, NoIR) // R16 = [mem] +I(MOVmr32 , "movl", 0x8B, 0, X86II::MRMSrcMem | X86II::MemArg32, NoIR, + NoIR) // R32 = [mem] +I(MOVrm8 , "movb", 0x88, 0, X86II::MRMDestMem | X86II::Void | + X86II::MemArg8, NoIR, NoIR) // [mem] = R8 +I(MOVrm16 , "movw", 0x89, 0, X86II::MRMDestMem | X86II::Void | + X86II::OpSize | X86II::MemArg16, NoIR, NoIR) // [mem] = R16 +I(MOVrm32 , "movl", 0x89, 0, X86II::MRMDestMem | X86II::Void | + X86II::MemArg32, NoIR, NoIR) // [mem] = R32 -I(PUSHr32 , "pushl", 0x50, 0, X86II::AddRegFrm | X86II::Void, NoImpRegs, NoImpRegs) -I(POPr32 , "popl", 0x58, 0, X86II::AddRegFrm, NoImpRegs, NoImpRegs) +I(PUSHr32 , "pushl", 0x50, 0, X86II::AddRegFrm | X86II::Void, NoIR, NoIR) +I(POPr32 , "popl", 0x58, 0, X86II::AddRegFrm, NoIR, NoIR) // Arithmetic instructions -I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 += R8 -I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 += R16 -I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 += R32 -I(ADDri32 , "add", 0x81, 0, X86II::MRMS0r, NoImpRegs, NoImpRegs) // R32 += imm32 -I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 -= R8 -I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 -= R16 -I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 -= R32 -I(SUBri32 , "sub", 0x81, 0, X86II::MRMS5r, NoImpRegs, NoImpRegs) // R32 -= imm32 -I(MULrr8 , "mulb", 0xF6, 0, X86II::MRMS4r | X86II::Void, O_AL, O_AX) // AX = AL*R8 -I(MULrr16 , "mulw", 0xF7, 0, X86II::MRMS4r | X86II::Void | // DX:AX= AX*R16 +I(ADDrr8 , "addb", 0x00, 0, X86II::MRMDestReg, NoIR, NoIR) // R8 += R8 +I(ADDrr16 , "addw", 0x01, 0, X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // R16 += R16 +I(ADDrr32 , "addl", 0x01, 0, X86II::MRMDestReg, NoIR, NoIR) // R32 += R32 +I(ADDri32 , "add", 0x81, 0, X86II::MRMS0r, NoIR, NoIR) // R32 += imm32 +I(SUBrr8 , "subb", 0x2A, 0, X86II::MRMDestReg, NoIR, NoIR) // R8 -= R8 +I(SUBrr16 , "subw", 0x2B, 0, X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // R16 -= R16 +I(SUBrr32 , "subl", 0x2B, 0, X86II::MRMDestReg, NoIR, NoIR) // R32 -= R32 +I(SUBri32 , "sub", 0x81, 0, X86II::MRMS5r, NoIR, NoIR) // R32 -= imm32 +I(MULrr8 , "mulb", 0xF6, 0, X86II::MRMS4r | X86II::Void, O_AL, O_AX) // AX = AL*R8 +I(MULrr16 , "mulw", 0xF7, 0, X86II::MRMS4r | X86II::Void | // DX:AX= AX*R16 X86II::OpSize, O_AX, T_AXDX) -I(MULrr32 , "mull", 0xF7, 0, X86II::MRMS4r | X86II::Void, O_EAX, T_EAXEDX) // ED:EA= EA*R32 +I(MULrr32 , "mull", 0xF7, 0, X86II::MRMS4r | X86II::Void, O_EAX, T_EAXEDX) // ED:EA= EA*R32 // unsigned division/remainder -I(DIVrr8 , "divb", 0xF6, 0, X86II::MRMS6r | X86II::Void, O_AX, O_AX) // AX/r8= AL&AH -I(DIVrr16 , "divw", 0xF7, 0, X86II::MRMS6r | X86II::Void | // EDXEAX/r16=AX&DX +I(DIVrr8 , "divb", 0xF6, 0, X86II::MRMS6r | X86II::Void, O_AX, O_AX) // AX/r8= AL&AH +I(DIVrr16 , "divw", 0xF7, 0, X86II::MRMS6r | X86II::Void | // ED:EA/r16=AX&DX X86II::OpSize, T_AXDX, T_AXDX) -I(DIVrr32 , "divl", 0xF7, 0, X86II::MRMS6r | X86II::Void, T_EAXEDX, T_EAXEDX) // EDXEAX/r32=EAX&EDX +I(DIVrr32 , "divl", 0xF7, 0, X86II::MRMS6r | X86II::Void, T_EAXEDX, + T_EAXEDX) // ED:EA/r32=EA&ED // signed division/remainder -I(IDIVrr8 , "idivb", 0xF6, 0, X86II::MRMS7r | X86II::Void, O_AX, O_AX) // AX/r8= AL&AH -I(IDIVrr16 , "idivw", 0xF7, 0, X86II::MRMS7r | X86II::Void | // DA/r16=AX&DX +I(IDIVrr8 , "idivb", 0xF6, 0, X86II::MRMS7r | X86II::Void, O_AX, O_AX) // AX/r8= AL&AH +I(IDIVrr16 , "idivw", 0xF7, 0, X86II::MRMS7r | X86II::Void | // DA/r16=AX&DX X86II::OpSize, T_AXDX, T_AXDX) -I(IDIVrr32 , "idivl", 0xF7, 0, X86II::MRMS7r | X86II::Void, T_EAXEDX, T_EAXEDX) // DA/r32=EAX&DX +I(IDIVrr32 , "idivl", 0xF7, 0, X86II::MRMS7r | X86II::Void, T_EAXEDX, + T_EAXEDX) // DA/r32=EAX&DX // Logical operators -I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 &= R8 -I(ANDrr16 , "andw", 0x21, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 &= R16 -I(ANDrr32 , "andl", 0x21, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 &= R32 -I(ORrr8 , "orb", 0x08, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 |= R8 -I(ORrr16 , "orw", 0x09, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 |= R16 -I(ORrr32 , "orl", 0x09, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 |= R32 -I(XORrr8 , "xorb", 0x30, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R8 ^= R8 -I(XORrr16 , "xorw", 0x31, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 ^= R16 -I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // R32 ^= R32 +I(ANDrr8 , "andb", 0x20, 0, X86II::MRMDestReg, NoIR, NoIR) // R8 &= R8 +I(ANDrr16 , "andw", 0x21, 0, X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // R16 &= R16 +I(ANDrr32 , "andl", 0x21, 0, X86II::MRMDestReg, NoIR, NoIR) // R32 &= R32 +I(ORrr8 , "orb", 0x08, 0, X86II::MRMDestReg, NoIR, NoIR) // R8 |= R8 +I(ORrr16 , "orw", 0x09, 0, X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // R16 |= R16 +I(ORrr32 , "orl", 0x09, 0, X86II::MRMDestReg, NoIR, NoIR) // R32 |= R32 +I(XORrr8 , "xorb", 0x30, 0, X86II::MRMDestReg, NoIR, NoIR) // R8 ^= R8 +I(XORrr16 , "xorw", 0x31, 0, X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // R16 ^= R16 +I(XORrr32 , "xorl", 0x31, 0, X86II::MRMDestReg, NoIR, NoIR) // R32 ^= R32 // Shift instructions -I(SHLrr8 , "shlb", 0xD2, 0, X86II::MRMS4r, O_CL, NoImpRegs) // R8 <<= cl D2/4 -I(SHLrr16 , "shlw", 0xD3, 0, X86II::MRMS4r | X86II::OpSize, O_CL, NoImpRegs) // R16 <<= cl D3/4 -I(SHLrr32 , "shll", 0xD3, 0, X86II::MRMS4r, O_CL, NoImpRegs) // R32 <<= cl D3/4 -I(SHLir8 , "shlb", 0xC0, 0, X86II::MRMS4r, NoImpRegs, NoImpRegs) // R8 <<= imm8 C0/4 ib -I(SHLir16 , "shlw", 0xC1, 0, X86II::MRMS4r | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 <<= imm8 C1/4 ib -I(SHLir32 , "shll", 0xC1, 0, X86II::MRMS4r, NoImpRegs, NoImpRegs) // R32 <<= imm8 C1/4 ib -I(SHRrr8 , "shrb", 0xD2, 0, X86II::MRMS5r, O_CL, NoImpRegs) // R8 >>>= cl D2/5 -I(SHRrr16 , "shrw", 0xD3, 0, X86II::MRMS5r | X86II::OpSize, O_CL, NoImpRegs) // R16 >>>= cl D3/5 -I(SHRrr32 , "shrl", 0xD3, 0, X86II::MRMS5r, O_CL, NoImpRegs) // R32 >>>= cl D3/5 -I(SHRir8 , "shrb", 0xC0, 0, X86II::MRMS5r, NoImpRegs, NoImpRegs) // R8 >>>= imm8 C0/5 ib -I(SHRir16 , "shrw", 0xC1, 0, X86II::MRMS5r | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 >>>= imm8 C1/5 ib -I(SHRir32 , "shrl", 0xC1, 0, X86II::MRMS5r, NoImpRegs, NoImpRegs) // R32 >>>= imm8 C1/5 ib -I(SARrr8 , "sarb", 0xD2, 0, X86II::MRMS7r, O_CL, NoImpRegs) // R8 >>= cl D2/7 -I(SARrr16 , "sarw", 0xD3, 0, X86II::MRMS7r | X86II::OpSize, O_CL, NoImpRegs) // R16 >>= cl D3/7 -I(SARrr32 , "sarl", 0xD3, 0, X86II::MRMS7r, O_CL, NoImpRegs) // R32 >>= cl D3/7 -I(SARir8 , "sarb", 0xC0, 0, X86II::MRMS7r, NoImpRegs, NoImpRegs) // R8 >>= imm8 C0/7 ib -I(SARir16 , "sarw", 0xC1, 0, X86II::MRMS7r | X86II::OpSize, NoImpRegs, NoImpRegs) // R16 >>= imm8 C1/7 ib -I(SARir32 , "sarl", 0xC1, 0, X86II::MRMS7r, NoImpRegs, NoImpRegs) // R32 >>= imm8 C1/7 ib +I(SHLrr8 , "shlb", 0xD2, 0, X86II::MRMS4r, O_CL, NoIR) // R8 <<= cl +I(SHLrr16 , "shlw", 0xD3, 0, X86II::MRMS4r | X86II::OpSize, O_CL, NoIR) // R16 <<= cl +I(SHLrr32 , "shll", 0xD3, 0, X86II::MRMS4r, O_CL, NoIR) // R32 <<= cl +I(SHLir8 , "shlb", 0xC0, 0, X86II::MRMS4r, NoIR, NoIR) // R8 <<= imm8 +I(SHLir16 , "shlw", 0xC1, 0, X86II::MRMS4r | X86II::OpSize, NoIR, NoIR) // R16 <<= imm8 +I(SHLir32 , "shll", 0xC1, 0, X86II::MRMS4r, NoIR, NoIR) // R32 <<= imm8 +I(SHRrr8 , "shrb", 0xD2, 0, X86II::MRMS5r, O_CL, NoIR) // R8 >>>= cl +I(SHRrr16 , "shrw", 0xD3, 0, X86II::MRMS5r | X86II::OpSize, O_CL, NoIR) // R16 >>>= cl +I(SHRrr32 , "shrl", 0xD3, 0, X86II::MRMS5r, O_CL, NoIR) // R32 >>>= cl +I(SHRir8 , "shrb", 0xC0, 0, X86II::MRMS5r, NoIR, NoIR) // R8 >>>= imm8 +I(SHRir16 , "shrw", 0xC1, 0, X86II::MRMS5r | X86II::OpSize, NoIR, NoIR) // R16 >>>= imm8 +I(SHRir32 , "shrl", 0xC1, 0, X86II::MRMS5r, NoIR, NoIR) // R32 >>>= imm8 +I(SARrr8 , "sarb", 0xD2, 0, X86II::MRMS7r, O_CL, NoIR) // R8 >>= cl +I(SARrr16 , "sarw", 0xD3, 0, X86II::MRMS7r | X86II::OpSize, O_CL, NoIR) // R16 >>= cl +I(SARrr32 , "sarl", 0xD3, 0, X86II::MRMS7r, O_CL, NoIR) // R32 >>= cl +I(SARir8 , "sarb", 0xC0, 0, X86II::MRMS7r, NoIR, NoIR) // R8 >>= imm8 +I(SARir16 , "sarw", 0xC1, 0, X86II::MRMS7r | X86II::OpSize, NoIR, NoIR) // R16 >>= imm8 +I(SARir32 , "sarl", 0xC1, 0, X86II::MRMS7r, NoIR, NoIR) // R32 >>= imm8 // Floating point loads -I(FLDr4 , "flds", 0xD9, 0, X86II::MRMS0m, NoImpRegs, NoImpRegs) // push float D9/0 -I(FLDr8 , "fldl ", 0xDD, 0, X86II::MRMS0m, NoImpRegs, NoImpRegs) // push double DD/0 +I(FLDr4 , "flds", 0xD9, 0, X86II::MRMS0m, NoIR, NoIR) // push float +I(FLDr8 , "fldl ", 0xDD, 0, X86II::MRMS0m, NoIR, NoIR) // push double // Floating point compares -I(FUCOMPP , "fucompp", 0xDA, 0, X86II::Void, NoImpRegs, NoImpRegs) // compare+pop2x DA E9 +I(FUCOMPP , "fucompp", 0xDA, 0, X86II::Void, NoIR, NoIR) // compare+pop2x // Floating point flag ops -I(FNSTSWr8 , "fnstsw", 0xDF, 0, X86II::Void, NoImpRegs, O_AX) // AX = fp flags DF E0 +I(FNSTSWr8 , "fnstsw", 0xDF, 0, X86II::Void, NoIR, O_AX) // AX = fp flags // Condition code ops, incl. set if equal/not equal/... -I(SAHF , "sahf", 0x9E, 0, X86II::RawFrm, O_AH, NoImpRegs) // flags = AH -I(SETBr , "setb", 0x92, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = < unsign -I(SETAEr , "setae", 0x93, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = >=unsign -I(SETEr , "sete", 0x94, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = == -I(SETNEr , "setne", 0x95, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = != -I(SETBEr , "setbe", 0x96, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = <=unsign -I(SETAr , "seta", 0x97, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = > unsign -I(SETLr , "setl", 0x9C, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = < signed -I(SETGEr , "setge", 0x9D, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = >=signed -I(SETLEr , "setle", 0x9E, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = <=signed -I(SETGr , "setg", 0x9F, 0, X86II::TB | X86II::MRMS0r, NoImpRegs, NoImpRegs) // R8 = > signed +I(SAHF , "sahf", 0x9E, 0, X86II::RawFrm, O_AH, NoIR) // flags = AH +I(SETBr , "setb", 0x92, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = < unsign +I(SETAEr , "setae", 0x93, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = >=unsign +I(SETEr , "sete", 0x94, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = == +I(SETNEr , "setne", 0x95, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = != +I(SETBEr , "setbe", 0x96, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = <=unsign +I(SETAr , "seta", 0x97, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = > unsign +I(SETLr , "setl", 0x9C, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = < signed +I(SETGEr , "setge", 0x9D, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = >=signed +I(SETLEr , "setle", 0x9E, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = <=signed +I(SETGr , "setg", 0x9F, 0, X86II::TB | X86II::MRMS0r, NoIR, NoIR) // R8 = > signed // Integer comparisons -I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // compare R8,R8 -I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg | X86II::OpSize, NoImpRegs, NoImpRegs) // compare R16,R16 -I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg, NoImpRegs, NoImpRegs) // compare R32,R32 -I(CMPri8 , "cmp", 0x80, 0, X86II::MRMS7r, NoImpRegs, NoImpRegs) // compare R8, imm8 +I(CMPrr8 , "cmpb", 0x38, 0, X86II::MRMDestReg, NoIR, NoIR) // compare R8,R8 +I(CMPrr16 , "cmpw", 0x39, 0, X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // compare R16,R16 +I(CMPrr32 , "cmpl", 0x39, 0, X86II::MRMDestReg, NoIR, NoIR) // compare R32,R32 +I(CMPri8 , "cmp", 0x80, 0, X86II::MRMS7r, NoIR, NoIR) // compare R8, imm8 // Sign extenders (first 3 are good for DIV/IDIV; the others are more general) -I(CBW , "cbw", 0x98, 0, X86II::RawFrm, O_AL, O_AX) // AX = signext(AL) -I(CWD , "cwd", 0x99, 0, X86II::RawFrm, O_AX, O_DX) // DX:AX = signext(AX) -I(CDQ , "cdq", 0x99, 0, X86II::RawFrm, O_EAX, O_EDX) // EDX:EAX = signext(EAX) -I(MOVSXr16r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB | // R16 = signext(R8) - X86II::OpSize, NoImpRegs, NoImpRegs) -I(MOVSXr32r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB, NoImpRegs, NoImpRegs) // R32 = signext(R8) -I(MOVSXr32r16 , "movsx", 0xBF, 0, X86II::MRMSrcReg | X86II::TB, NoImpRegs, NoImpRegs) // R32 = signext(R16) -I(MOVZXr16r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB | // R16 = zeroext(R8) - X86II::OpSize, NoImpRegs, NoImpRegs) -I(MOVZXr32r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB, NoImpRegs, NoImpRegs) // R32 = zeroext(R8) -I(MOVZXr32r16 , "movzx", 0xB7, 0, X86II::MRMSrcReg | X86II::TB, NoImpRegs, NoImpRegs) // R32 = zeroext(R16) +I(CBW , "cbw", 0x98, 0, X86II::RawFrm, O_AL, O_AX) // AX = signext(AL) +I(CWD , "cwd", 0x99, 0, X86II::RawFrm, O_AX, O_DX) // DX:AX = signext(AX) +I(CDQ , "cdq", 0x99, 0, X86II::RawFrm, O_EAX, O_EDX) // EDX:EAX = signext(EAX) +I(MOVSXr16r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB | // R16 = signext(R8) + X86II::OpSize, NoIR, NoIR) +I(MOVSXr32r8 , "movsx", 0xBE, 0, X86II::MRMSrcReg | X86II::TB, NoIR, NoIR) // R32 = signext(R8) +I(MOVSXr32r16 , "movsx", 0xBF, 0, X86II::MRMSrcReg | X86II::TB, NoIR, NoIR) // R32 = signext(R16) +I(MOVZXr16r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB | // R16 = zeroext(R8) + X86II::OpSize, NoIR, NoIR) +I(MOVZXr32r8 , "movzx", 0xB6, 0, X86II::MRMSrcReg | X86II::TB, NoIR, NoIR) // R32 = zeroext(R8) +I(MOVZXr32r16 , "movzx", 0xB7, 0, X86II::MRMSrcReg | X86II::TB, NoIR, NoIR) // R32 = zeroext(R16) // At this point, I is dead, so undefine the macro #undef I Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.15 llvm/lib/Target/X86/X86InstrInfo.h:1.16 --- llvm/lib/Target/X86/X86InstrInfo.h:1.15 Mon Dec 2 15:40:58 2002 +++ llvm/lib/Target/X86/X86InstrInfo.h Thu Dec 5 02:30:40 2002 @@ -80,6 +80,17 @@ // which most often indicates that the instruction operates on 16 bit data // instead of 32 bit data. OpSize = 1 << 7, + + // This three-bit field describes the size of a memory operand. + // I'm just being paranoid not using the zero value; there's + // probably no reason you couldn't use it. + MemArg8 = 0x1 << 8, + MemArg16 = 0x2 << 8, + MemArg32 = 0x3 << 8, + MemArg64 = 0x4 << 8, + MemArg80 = 0x5 << 8, + MemArg128 = 0x6 << 8, + MemArgMask = 0x7 << 8, }; } From vadve at cs.uiuc.edu Thu Dec 5 11:18:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Thu Dec 5 11:18:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200212051717.LAA07923@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.70 -> 1.71 --- Log message: Cute bug fix: when moving links from N to this, some links could have been missed if node *this got merged away due to recursive merging! Also, links were not moved correctly if a node is collapsed. --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.70 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.71 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.70 Wed Nov 27 11:41:13 2002 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Thu Dec 5 11:17:26 2002 @@ -470,37 +470,46 @@ } assert((NodeType & DSNode::DEAD) == 0); - // Make all of the outgoing links of N now be outgoing links of this. This - // can cause recursive merging! + // Make all of the outgoing links of N now be outgoing links of + // this. This can cause recursive merging! Note that such merging may + // cause the current node to be merged into some other node, and so go away. + // To make sure we can find the resulting node, we use a level of + // indirection through DSNodeHandle Temp. This handle will always + // point to the node that resulting from any potential merge. // + DSNodeHandle Temp = this; for (unsigned i = 0; i < NSize; i += DS::PointerSize) { DSNodeHandle &Link = N->getLink(i); if (Link.getNode()) { - addEdgeTo((i+NOffset) % getSize(), Link); + DSNode *TempNode = Temp.getNode(); // get current version of "this" node - // It's possible that after adding the new edge that some recursive - // 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; // Node is now dead - if (Size == 1) - break; // Node got collapsed + // Compute the offset into the current node at which to + // merge this link. In the common case, this is a linear + // relation to the offset in the original node (with + // wrapping), but if the current node gets collapsed due to + // recursive merging, we must make sure to merge in all remaining + // links at offset zero. + unsigned MergeOffset = 0; + if (TempNode->Size != 1) + MergeOffset = (i+NOffset) % TempNode->getSize(); + TempNode->addEdgeTo(MergeOffset, Link); } } + DSNode *TempNode = Temp.getNode(); + // Now that there are no outgoing edges, all of the Links are dead. N->Links.clear(); N->Size = 0; N->Ty = Type::VoidTy; // Merge the node types - NodeType |= N->NodeType; + TempNode->NodeType |= N->NodeType; N->NodeType = DEAD; // N is now a dead node. // Merge the globals list... if (!N->Globals.empty()) { - MergeSortedVectors(Globals, N->Globals); + MergeSortedVectors(TempNode->Globals, N->Globals); // Delete the globals from the old node... N->Globals.clear(); From lattner at cs.uiuc.edu Thu Dec 5 16:26:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 16:26:01 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/2002-12-05-MissedConstProp.ll Message-ID: <200212052225.QAA20338@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: 2002-12-05-MissedConstProp.ll added (r1.1) --- Log message: New testcase pointed out by Casey Carter --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Dec 5 16:43:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 16:43:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200212052242.QAA21111@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.66 -> 1.67 --- Log message: Fix bug: 2002-12-05-MissedConstProp.ll pointed out by Casey Carter --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.66 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.67 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.66 Fri Nov 8 18:49:43 2002 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Dec 5 16:41:53 2002 @@ -792,7 +792,8 @@ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (Instruction *Op = dyn_cast(I->getOperand(i))) WorkList.push_back(Op); - I->replaceAllUsesWith(C); + ReplaceInstUsesWith(*I, C); + ++NumConstProp; BasicBlock::iterator BBI = I; if (dceInstruction(BBI)) { From lattner at cs.uiuc.edu Thu Dec 5 21:46:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 21:46:01 2002 Subject: [llvm-commits] CVS: llvm/Makefile.Linux Makefile.SunOS Message-ID: <200212060345.VAA27433@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.Linux updated: 1.5 -> 1.6 Makefile.SunOS updated: 1.5 -> 1.6 --- Log message: Export a new ARCH variable indicating what platform is being compiled --- Diffs of the changes: Index: llvm/Makefile.Linux diff -u llvm/Makefile.Linux:1.5 llvm/Makefile.Linux:1.6 --- llvm/Makefile.Linux:1.5 Mon Nov 4 14:50:33 2002 +++ llvm/Makefile.Linux Thu Dec 5 21:45:20 2002 @@ -5,6 +5,9 @@ # #===-----------------------------------------------------------------------====# +# Set the architecture so that x86 platform dependant code is compmiled +ARCH := x86 + # MakeSharedObjectOption - This option is passed to the linker by # Makefile.common when compiling a shared object. # Index: llvm/Makefile.SunOS diff -u llvm/Makefile.SunOS:1.5 llvm/Makefile.SunOS:1.6 --- llvm/Makefile.SunOS:1.5 Mon Nov 4 15:03:13 2002 +++ llvm/Makefile.SunOS Thu Dec 5 21:45:20 2002 @@ -5,6 +5,9 @@ # #===-----------------------------------------------------------------------====# +# Set the architecture so that Sparc platform dependant code is compmiled +ARCH := Sparc + # MakeSharedObjectOption - This option is passed to the linker by # Makefile.common when compiling a shared object. # From lattner at cs.uiuc.edu Thu Dec 5 21:54:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 21:54:01 2002 Subject: [llvm-commits] CVS: llvm/tools/jello/Callback.cpp Message-ID: <200212060353.VAA27854@apoc.cs.uiuc.edu> Changes in directory llvm/tools/jello: Callback.cpp updated: 1.1 -> 1.2 --- Log message: Fix to make jello compile on Sparc even though it won't run. --- Diffs of the changes: Index: llvm/tools/jello/Callback.cpp diff -u llvm/tools/jello/Callback.cpp:1.1 llvm/tools/jello/Callback.cpp:1.2 --- llvm/tools/jello/Callback.cpp:1.1 Tue Dec 3 23:05:26 2002 +++ llvm/tools/jello/Callback.cpp Thu Dec 5 21:52:51 2002 @@ -15,6 +15,7 @@ static void TrapHandler(int TN, siginfo_t *SI, ucontext_t *ucp) { assert(TN == SIGSEGV && "Should be SIGSEGV!"); +#ifdef REG_EIP /* this code does not compile on Sparc! */ if (SI->si_code != SEGV_MAPERR || SI->si_addr != 0 || ucp->uc_mcontext.gregs[REG_EIP] != 0) { std::cerr << "Bad SEGV encountered!\n"; @@ -41,6 +42,8 @@ // Change the instruction pointer to be the real target of the call... ucp->uc_mcontext.gregs[REG_EIP] = NewVal; + +#endif } From lattner at cs.uiuc.edu Thu Dec 5 21:54:05 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 21:54:05 2002 Subject: [llvm-commits] CVS: llvm/tools/Makefile Message-ID: <200212060353.VAA27870@apoc.cs.uiuc.edu> Changes in directory llvm/tools: Makefile updated: 1.16 -> 1.17 --- Log message: Only build jello when compiling on X86 --- Diffs of the changes: Index: llvm/tools/Makefile diff -u llvm/tools/Makefile:1.16 llvm/tools/Makefile:1.17 --- llvm/tools/Makefile:1.16 Wed Nov 20 16:28:18 2002 +++ llvm/tools/Makefile Thu Dec 5 21:53:40 2002 @@ -1,5 +1,14 @@ -LEVEL = .. -PARALLEL_DIRS = as dis opt gccas llc link lli gccld analyze extract jello bugpoint +LEVEL := .. +PARALLEL_DIRS := as dis opt gccas llc link lli gccld analyze extract bugpoint include $(LEVEL)/Makefile.common + +ifeq ($(ARCH),x86) +# Only build jello when we are on X86 +all :: jello/.makeall +install :: jello/.makeinstall +clean :: jello/.makeclean +endif + + From lattner at cs.uiuc.edu Thu Dec 5 21:56:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 21:56:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Record.cpp Record.h Message-ID: <200212060355.VAA27954@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.2 -> 1.3 Record.cpp updated: 1.5 -> 1.6 Record.h updated: 1.7 -> 1.8 --- Log message: Tighten up assertion checking --- Diffs of the changes: Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.2 llvm/utils/TableGen/FileParser.y:1.3 --- llvm/utils/TableGen/FileParser.y:1.2 Mon Dec 2 10:43:43 2002 +++ llvm/utils/TableGen/FileParser.y Thu Dec 5 21:55:39 2002 @@ -89,14 +89,21 @@ BitsInit *NewVal = new BitsInit(CurVal->getNumBits()); - for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) - NewVal->setBit(i, CurVal->getBit(i)); - - // Loop over bits, assigning values as appopriate... + // Loop over bits, assigning values as appropriate... for (unsigned i = 0, e = BitList->size(); i != e; ++i) { unsigned Bit = (*BitList)[i]; + if (NewVal->getBit(i)) { + err() << "Cannot set bit #" << i << " of value '" << ValName + << "' more than once!\n"; + abort(); + } NewVal->setBit(Bit, BInit->getBit(i)); } + + for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) + if (NewVal->getBit(i) == 0) + NewVal->setBit(i, CurVal->getBit(i)); + V = NewVal; } Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.5 llvm/utils/TableGen/Record.cpp:1.6 --- llvm/utils/TableGen/Record.cpp:1.5 Tue Dec 3 00:00:33 2002 +++ llvm/utils/TableGen/Record.cpp Thu Dec 5 21:55:39 2002 @@ -211,12 +211,14 @@ for (unsigned i = 0, e = Bits.size(); i != e; ++i) { Init *B; - New->setBit(i, getBit(i)); + Init *CurBit = getBit(i); + do { - B = New->getBit(i); - New->setBit(i, B->resolveReferences(R)); - Changed |= B != New->getBit(i); - } while (B != New->getBit(i)); + B = CurBit; + CurBit = CurBit->resolveReferences(R); + Changed |= B != CurBit; + } while (B != CurBit); + New->setBit(i, CurBit); } if (Changed) Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.7 llvm/utils/TableGen/Record.h:1.8 --- llvm/utils/TableGen/Record.h:1.7 Tue Dec 3 00:00:33 2002 +++ llvm/utils/TableGen/Record.h Thu Dec 5 21:55:39 2002 @@ -245,6 +245,7 @@ } void setBit(unsigned Bit, Init *V) { assert(Bit < Bits.size() && "Bit index out of range!"); + assert(Bits[Bit] == 0 && "Bit already set!"); Bits[Bit] = V; } From lattner at cs.uiuc.edu Thu Dec 5 22:03:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 22:03:00 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Message-ID: <200212060402.WAA28041@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.6 -> 1.7 --- Log message: Don't delete values that may still be referenced! --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.6 llvm/utils/TableGen/Record.cpp:1.7 --- llvm/utils/TableGen/Record.cpp:1.6 Thu Dec 5 21:55:39 2002 +++ llvm/utils/TableGen/Record.cpp Thu Dec 5 22:02:48 2002 @@ -19,7 +19,6 @@ Init *BitRecTy::convertValue(IntInit *II) { int Val = II->getValue(); if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit! - delete II; return new BitInit(Val != 0); } @@ -50,7 +49,6 @@ // Init *BitsRecTy::convertValue(IntInit *II) { int Value = II->getValue(); - delete II; BitsInit *Ret = new BitsInit(Size); for (unsigned i = 0; i != Size; ++i) From lattner at cs.uiuc.edu Thu Dec 5 22:43:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 22:43:01 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.cpp Message-ID: <200212060442.WAA28271@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.cpp updated: 1.7 -> 1.8 --- Log message: Allow printing partially constructed bitsets --- Diffs of the changes: Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.7 llvm/utils/TableGen/Record.cpp:1.8 --- llvm/utils/TableGen/Record.cpp:1.7 Thu Dec 5 22:02:48 2002 +++ llvm/utils/TableGen/Record.cpp Thu Dec 5 22:42:10 2002 @@ -153,7 +153,10 @@ OS << "{ "; for (unsigned i = 0, e = getNumBits(); i != e; ++i) { if (i) OS << ", "; - getBit(e-i-1)->print(OS); + if (Init *Bit = getBit(e-i-1)) + Bit->print(OS); + else + OS << "*"; } OS << " }"; } From lattner at cs.uiuc.edu Thu Dec 5 22:43:07 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Dec 5 22:43:07 2002 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Message-ID: <200212060442.WAA28278@apoc.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.3 -> 1.4 --- Log message: Fix bug --- Diffs of the changes: Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.3 llvm/utils/TableGen/FileParser.y:1.4 --- llvm/utils/TableGen/FileParser.y:1.3 Thu Dec 5 21:55:39 2002 +++ llvm/utils/TableGen/FileParser.y Thu Dec 5 22:42:16 2002 @@ -92,8 +92,8 @@ // Loop over bits, assigning values as appropriate... for (unsigned i = 0, e = BitList->size(); i != e; ++i) { unsigned Bit = (*BitList)[i]; - if (NewVal->getBit(i)) { - err() << "Cannot set bit #" << i << " of value '" << ValName + if (NewVal->getBit(Bit)) { + err() << "Cannot set bit #" << Bit << " of value '" << ValName << "' more than once!\n"; abort(); } From lattner at cs.uiuc.edu Fri Dec 6 00:41:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 6 00:41:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/CallGraph.h Message-ID: <200212060640.AAA29103@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: CallGraph.h updated: 1.25 -> 1.26 --- Log message: Make sure to print indirect node again --- Diffs of the changes: Index: llvm/include/llvm/Analysis/CallGraph.h diff -u llvm/include/llvm/Analysis/CallGraph.h:1.25 llvm/include/llvm/Analysis/CallGraph.h:1.26 --- llvm/include/llvm/Analysis/CallGraph.h:1.25 Sun Nov 17 17:10:27 2002 +++ llvm/include/llvm/Analysis/CallGraph.h Fri Dec 6 00:40:00 2002 @@ -253,9 +253,7 @@ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph typedef mapped_iterator nodes_iterator; static nodes_iterator nodes_begin(CallGraph *CG) { - CallGraph::iterator I = CG->begin(); - ++I; - return map_iterator(I, DerefFun(CGdereference)); + return map_iterator(CG->begin(), DerefFun(CGdereference)); } static nodes_iterator nodes_end (CallGraph *CG) { return map_iterator(CG->end(), DerefFun(CGdereference)); From lattner at cs.uiuc.edu Fri Dec 6 04:50:00 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 6 04:50:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200212061049.EAA13050@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.52 -> 1.53 --- Log message: Implement a lot of cast functionality (no FP or 64) --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.52 llvm/lib/Target/X86/InstSelectSimple.cpp:1.53 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.52 Wed Dec 4 17:50:28 2002 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Fri Dec 6 04:49:33 2002 @@ -665,45 +665,73 @@ void ISel::visitCastInst (CastInst &CI) { -//> cast larger int to smaller int --> copy least significant byte/word w/ mov? -// -//I'm not really sure what to do with this. We could insert a pseudo-op -//that says take the low X bits of a Y bit register, but for now we can just -//force the value into, say, EAX, then rip out AL or AX. The advantage of -//the former is that the register allocator could use any register it wants, -//but for now this obviously doesn't matter. :) - const Type *targetType = CI.getType (); Value *operand = CI.getOperand (0); unsigned int operandReg = getReg (operand); const Type *sourceType = operand->getType (); unsigned int destReg = getReg (CI); - - // cast to bool: - if (targetType == Type::BoolTy) { - // Emit Compare - BuildMI (BB, X86::CMPri8, 2).addReg (operandReg).addZImm (0); - // Emit Set-if-not-zero - BuildMI (BB, X86::SETNEr, 1, destReg); - return; - } - -// if size of target type == size of source type -// Emit Mov reg(target) <- reg(source) - -// if size of target type > size of source type -// if both types are integer types -// if source type is signed -// sbyte to short, ushort: Emit movsx 8->16 -// sbyte to int, uint: Emit movsx 8->32 -// short to int, uint: Emit movsx 16->32 -// else if source type is unsigned -// ubyte to short, ushort: Emit movzx 8->16 -// ubyte to int, uint: Emit movzx 8->32 -// ushort to int, uint: Emit movzx 16->32 -// if both types are fp types -// float to double: Emit fstp, fld (???) - + // + // Currently we handle: + // + // 1) cast * to bool + // + // 2) cast {sbyte, ubyte} to {sbyte, ubyte} + // cast {short, ushort} to {ushort, short} + // cast {int, uint, ptr} to {int, uint, ptr} + // + // 3) cast {sbyte, ubyte} to {ushort, short} + // cast {sbyte, ubyte} to {int, uint, ptr} + // cast {short, ushort} to {int, uint, ptr} + // + // 4) cast {int, uint, ptr} to {short, ushort} + // cast {int, uint, ptr} to {sbyte, ubyte} + // cast {short, ushort} to {sbyte, ubyte} + // + // 1) Implement casts to bool by using compare on the operand followed + // by set if not zero on the result. + if (targetType == Type::BoolTy) + { + BuildMI (BB, X86::CMPri8, 2).addReg (operandReg).addZImm (0); + BuildMI (BB, X86::SETNEr, 1, destReg); + return; + } + // 2) Implement casts between values of the same type class (as determined + // by getClass) by using a register-to-register move. + unsigned int srcClass = getClass (sourceType); + unsigned int targClass = getClass (targetType); + static const unsigned regRegMove[] = { + X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 + }; + if ((srcClass < 3) && (targClass < 3) && (srcClass == targClass)) + { + BuildMI (BB, regRegMove[srcClass], 1, destReg).addReg (operandReg); + return; + } + // 3) Handle cast of SMALLER int to LARGER int using a move with sign + // extension or zero extension, depending on whether the source type + // was signed. + if ((srcClass < 3) && (targClass < 3) && (srcClass < targClass)) + { + static const unsigned ops[] = { + X86::MOVSXr16r8, X86::MOVSXr32r8, X86::MOVSXr32r16, + X86::MOVZXr16r8, X86::MOVZXr32r8, X86::MOVZXr32r16 + }; + unsigned srcSigned = sourceType->isSigned (); + BuildMI (BB, ops[3 * srcSigned + srcClass + targClass - 1], 1, + destReg).addReg (operandReg); + return; + } + // 4) Handle cast of LARGER int to SMALLER int using a move to EAX + // followed by a move out of AX or AL. + if ((srcClass < 3) && (targClass < 3) && (srcClass > targClass)) + { + static const unsigned AReg[] = { X86::AL, X86::AX, X86::EAX }; + BuildMI (BB, regRegMove[srcClass], 1, + AReg[srcClass]).addReg (operandReg); + BuildMI (BB, regRegMove[targClass], 1, destReg).addReg (AReg[srcClass]); + return; + } + // Anything we haven't handled already, we can't (yet) handle at all. visitInstruction (CI); } From vadve at cs.uiuc.edu Fri Dec 6 09:03:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Dec 6 09:03:01 2002 Subject: [llvm-commits] CVS: llvm/include/Support/TarjanSCCIterator.h Message-ID: <200212061502.JAA20479@psmith.cs.uiuc.edu> Changes in directory llvm/include/Support: TarjanSCCIterator.h updated: 1.3 -> 1.4 --- Log message: Bug fix in operator==() and in method fini(). --- Diffs of the changes: Index: llvm/include/Support/TarjanSCCIterator.h diff -u llvm/include/Support/TarjanSCCIterator.h:1.3 llvm/include/Support/TarjanSCCIterator.h:1.4 --- llvm/include/Support/TarjanSCCIterator.h:1.3 Fri Nov 15 12:04:16 2002 +++ llvm/include/Support/TarjanSCCIterator.h Fri Dec 6 09:02:22 2002 @@ -176,11 +176,12 @@ // Direct loop termination test (I.fini() is more efficient than I == end()) inline bool fini() const { - return VisitStack.empty(); + assert(!CurrentSCC.empty() || VisitStack.empty()); + return CurrentSCC.empty(); } inline bool operator==(const _Self& x) const { - return VisitStack == x.VisitStack; + return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC; } inline bool operator!=(const _Self& x) const { return !operator==(x); } @@ -195,11 +196,11 @@ // Retrieve a pointer to the current SCC. Returns NULL when done. inline const SccTy* operator*() const { - assert(!CurrentSCC.empty() || fini()); + assert(!CurrentSCC.empty() || VisitStack.empty()); return CurrentSCC.empty()? NULL : &CurrentSCC; } inline SccTy* operator*() { - assert(!CurrentSCC.empty() || fini()); + assert(!CurrentSCC.empty() || VisitStack.empty()); return CurrentSCC.empty()? NULL : &CurrentSCC; } }; From vadve at cs.uiuc.edu Fri Dec 6 15:11:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Dec 6 15:11:00 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSNode.h Message-ID: <200212062110.PAA24423@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSNode.h updated: 1.15 -> 1.16 --- Log message: Added static helper method MergeNodes(). See DataStructure.cpp for more. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSNode.h diff -u llvm/include/llvm/Analysis/DSNode.h:1.15 llvm/include/llvm/Analysis/DSNode.h:1.16 --- llvm/include/llvm/Analysis/DSNode.h:1.15 Mon Nov 18 15:45:30 2002 +++ llvm/include/llvm/Analysis/DSNode.h Fri Dec 6 15:10:17 2002 @@ -220,9 +220,13 @@ private: friend class DSNodeHandle; + // addReferrer - Keep the referrer set up to date... void addReferrer(DSNodeHandle *H) { Referrers.push_back(H); } void removeReferrer(DSNodeHandle *H); + + // static mergeNodes - Helper for mergeWith() + static void MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH); }; From vadve at cs.uiuc.edu Fri Dec 6 15:16:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Dec 6 15:16:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200212062115.PAA24450@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.71 -> 1.72 --- Log message: Fix several related bugs in DSNode::mergeWith() caused by the fact that the incoming nodes may be merged away at intermediate steps. Use an extra level of indirection via DSNodeHandles to track the nodes being merged. All this now happens in a static helper function MergeNodes(). --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.71 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.72 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.71 Thu Dec 5 11:17:26 2002 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Fri Dec 6 15:15:21 2002 @@ -380,109 +380,77 @@ } -// mergeWith - Merge this node and the specified node, moving all links to and -// from the argument node into the current node, deleting the node argument. -// Offset indicates what offset the specified node is to be merged into the -// current node. -// -// The specified node may be a null pointer (in which case, nothing happens). +// MergeNodes() - Helper function for DSNode::mergeWith(). +// This function does the hard work of merging two nodes, CurNodeH +// and NH after filtering out trivial cases and making sure that +// CurNodeH.offset >= NH.offset. +// +// ***WARNING*** +// Since merging may cause either node to go away, we must always +// use the node-handles to refer to the nodes. These node handles are +// automatically updated during merging, so will always provide access +// to the correct node after a merge. // -void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) { - DSNode *N = NH.getNode(); - if (N == 0 || (N == this && NH.getOffset() == Offset)) - return; // Noop - - assert((N->NodeType & DSNode::DEAD) == 0); - assert((NodeType & DSNode::DEAD) == 0); - assert(!hasNoReferrers() && "Should not try to fold a useless node!"); - - if (N == this) { - // We cannot merge two pieces of the same node together, collapse the node - // completely. - DEBUG(std::cerr << "Attempting to merge two chunks of" - << " the same node together!\n"); - foldNodeCompletely(); - return; - } - - // If both nodes are not at offset 0, make sure that we are merging the node - // at an later offset into the node with the zero offset. - // - if (Offset < NH.getOffset()) { - N->mergeWith(DSNodeHandle(this, Offset), NH.getOffset()); - return; - } else if (Offset == NH.getOffset() && getSize() < N->getSize()) { - // If the offsets are the same, merge the smaller node into the bigger node - N->mergeWith(DSNodeHandle(this, Offset), NH.getOffset()); - return; - } +void DSNode::MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH) { + assert(CurNodeH.getOffset() >= NH.getOffset() && + "This should have been enforced in the caller."); // Now we know that Offset >= NH.Offset, so convert it so our "Offset" (with // respect to NH.Offset) is now zero. NOffset is the distance from the base // of our object that N starts from. // - unsigned NOffset = Offset-NH.getOffset(); - unsigned NSize = N->getSize(); + unsigned NOffset = CurNodeH.getOffset()-NH.getOffset(); + unsigned NSize = NH.getNode()->getSize(); // Merge the type entries of the two nodes together... - if (N->Ty != Type::VoidTy) { - mergeTypeInfo(N->Ty, NOffset); - - // mergeTypeInfo can cause collapsing, which can cause this node to become - // dead. - if (hasNoReferrers()) return; + if (NH.getNode()->Ty != Type::VoidTy) { + CurNodeH.getNode()->mergeTypeInfo(NH.getNode()->Ty, NOffset); } - assert((NodeType & DSNode::DEAD) == 0); + assert((CurNodeH.getNode()->NodeType & DSNode::DEAD) == 0); // If we are merging a node with a completely folded node, then both nodes are // now completely folded. // - if (isNodeCompletelyFolded()) { - if (!N->isNodeCompletelyFolded()) { - N->foldNodeCompletely(); - if (hasNoReferrers()) return; - NSize = N->getSize(); + if (CurNodeH.getNode()->isNodeCompletelyFolded()) { + if (!NH.getNode()->isNodeCompletelyFolded()) { + NH.getNode()->foldNodeCompletely(); + assert(NH.getOffset()==0 && "folding did not make offset 0?"); + NOffset = NH.getOffset(); + NSize = NH.getNode()->getSize(); + assert(NOffset == 0 && NSize == 1); } - } else if (N->isNodeCompletelyFolded()) { - foldNodeCompletely(); - if (hasNoReferrers()) return; - Offset = 0; + } else if (NH.getNode()->isNodeCompletelyFolded()) { + CurNodeH.getNode()->foldNodeCompletely(); + assert(CurNodeH.getOffset()==0 && "folding did not make offset 0?"); NOffset = NH.getOffset(); - NSize = N->getSize(); + NSize = NH.getNode()->getSize(); + assert(NOffset == 0 && NSize == 1); } - N = NH.getNode(); - if (this == N || N == 0) return; - assert((NodeType & DSNode::DEAD) == 0); -#if 0 - std::cerr << "\n\nMerging:\n"; - N->print(std::cerr, 0); - std::cerr << " and:\n"; - print(std::cerr, 0); -#endif + if (CurNodeH.getNode() == NH.getNode() || NH.getNode() == 0) return; + assert((CurNodeH.getNode()->NodeType & DSNode::DEAD) == 0); // Remove all edges pointing at N, causing them to point to 'this' instead. // Make sure to adjust their offset, not just the node pointer. - // + // Also, be careful to use the DSNode* rather than NH since NH is one of + // the referrers and once NH refers to CurNodeH.getNode() this will + // become an infinite loop. + DSNode* N = NH.getNode(); + unsigned OldNHOffset = NH.getOffset(); while (!N->Referrers.empty()) { DSNodeHandle &Ref = *N->Referrers.back(); - Ref = DSNodeHandle(this, NOffset+Ref.getOffset()); + Ref = DSNodeHandle(CurNodeH.getNode(), NOffset+Ref.getOffset()); } - assert((NodeType & DSNode::DEAD) == 0); + NH = DSNodeHandle(N, OldNHOffset); // reset NH to point back to where it was - // Make all of the outgoing links of N now be outgoing links of - // this. This can cause recursive merging! Note that such merging may - // cause the current node to be merged into some other node, and so go away. - // To make sure we can find the resulting node, we use a level of - // indirection through DSNodeHandle Temp. This handle will always - // point to the node that resulting from any potential merge. - // - DSNodeHandle Temp = this; + assert((CurNodeH.getNode()->NodeType & DSNode::DEAD) == 0); + + // Make all of the outgoing links of *NH now be outgoing links of + // this. This can cause recursive merging! + // for (unsigned i = 0; i < NSize; i += DS::PointerSize) { - DSNodeHandle &Link = N->getLink(i); + DSNodeHandle &Link = NH.getNode()->getLink(i); if (Link.getNode()) { - DSNode *TempNode = Temp.getNode(); // get current version of "this" node - // Compute the offset into the current node at which to // merge this link. In the common case, this is a linear // relation to the offset in the original node (with @@ -490,32 +458,75 @@ // recursive merging, we must make sure to merge in all remaining // links at offset zero. unsigned MergeOffset = 0; - if (TempNode->Size != 1) - MergeOffset = (i+NOffset) % TempNode->getSize(); - TempNode->addEdgeTo(MergeOffset, Link); + if (CurNodeH.getNode()->Size != 1) + MergeOffset = (i+NOffset) % CurNodeH.getNode()->getSize(); + CurNodeH.getNode()->addEdgeTo(MergeOffset, Link); } } - DSNode *TempNode = Temp.getNode(); - // Now that there are no outgoing edges, all of the Links are dead. - N->Links.clear(); - N->Size = 0; - N->Ty = Type::VoidTy; + NH.getNode()->Links.clear(); + NH.getNode()->Size = 0; + NH.getNode()->Ty = Type::VoidTy; // Merge the node types - TempNode->NodeType |= N->NodeType; - N->NodeType = DEAD; // N is now a dead node. + CurNodeH.getNode()->NodeType |= NH.getNode()->NodeType; + NH.getNode()->NodeType = DEAD; // NH is now a dead node. // Merge the globals list... - if (!N->Globals.empty()) { - MergeSortedVectors(TempNode->Globals, N->Globals); + if (!NH.getNode()->Globals.empty()) { + MergeSortedVectors(CurNodeH.getNode()->Globals, NH.getNode()->Globals); // Delete the globals from the old node... - N->Globals.clear(); + NH.getNode()->Globals.clear(); } } + +// mergeWith - Merge this node and the specified node, moving all links to and +// from the argument node into the current node, deleting the node argument. +// Offset indicates what offset the specified node is to be merged into the +// current node. +// +// The specified node may be a null pointer (in which case, nothing happens). +// +void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) { + DSNode *N = NH.getNode(); + if (N == 0 || (N == this && NH.getOffset() == Offset)) + return; // Noop + + assert((N->NodeType & DSNode::DEAD) == 0); + assert((NodeType & DSNode::DEAD) == 0); + assert(!hasNoReferrers() && "Should not try to fold a useless node!"); + + if (N == this) { + // We cannot merge two pieces of the same node together, collapse the node + // completely. + DEBUG(std::cerr << "Attempting to merge two chunks of" + << " the same node together!\n"); + foldNodeCompletely(); + return; + } + + // If both nodes are not at offset 0, make sure that we are merging the node + // at an later offset into the node with the zero offset. + // + if (Offset < NH.getOffset()) { + N->mergeWith(DSNodeHandle(this, Offset), NH.getOffset()); + return; + } else if (Offset == NH.getOffset() && getSize() < N->getSize()) { + // If the offsets are the same, merge the smaller node into the bigger node + N->mergeWith(DSNodeHandle(this, Offset), NH.getOffset()); + return; + } + + // Ok, now we can merge the two nodes. Use a static helper that works with + // two node handles, since "this" may get merged away at intermediate steps. + DSNodeHandle CurNodeH(this, Offset); + DSNodeHandle NHCopy(NH); + DSNode::MergeNodes(CurNodeH, NHCopy); +} + //===----------------------------------------------------------------------===// // DSCallSite Implementation //===----------------------------------------------------------------------===// @@ -689,6 +700,7 @@ // Resolve all of the function arguments... Function &F = Graph.getFunction(); Function::aiterator AI = F.abegin(); + for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i, ++AI) { // Advance the argument iterator to the first pointer argument... while (!isPointerType(AI->getType())) { From vadve at cs.uiuc.edu Fri Dec 6 15:18:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Dec 6 15:18:00 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200212062117.PAA24471@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.39 -> 1.40 --- Log message: Two bug fixes: (1) Make entries for Constant values in the ScalarMap. (2) Set MOD bit for the node pointed to by the argument of a free instruction. --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.39 llvm/lib/Analysis/DataStructure/Local.cpp:1.40 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.39 Mon Nov 18 15:44:19 2002 +++ llvm/lib/Analysis/DataStructure/Local.cpp Fri Dec 6 15:17:10 2002 @@ -92,7 +92,7 @@ void visitStoreInst(StoreInst &SI); void visitCallInst(CallInst &CI); void visitSetCondInst(SetCondInst &SCI) {} // SetEQ & friends are ignored - void visitFreeInst(FreeInst &FI) {} // Ignore free instructions + void visitFreeInst(FreeInst &FI); void visitCastInst(CastInst &CI); void visitInstruction(Instruction &I) {} @@ -154,34 +154,35 @@ if (V == Constant::getNullValue(V->getType())) return 0; // Null doesn't point to anything, don't add to ScalarMap! + DSNodeHandle &NH = ScalarMap[V]; + if (NH.getNode()) + return NH; // Already have a node? Just return it... + + // Otherwise we need to create a new node to point to. + // Check first for constant expressions that must be traversed to + // extract the actual value. if (Constant *C = dyn_cast(V)) if (ConstantPointerRef *CPR = dyn_cast(C)) { - return getValueDest(*CPR->getValue()); + return NH = getValueDest(*CPR->getValue()); } else if (ConstantExpr *CE = dyn_cast(C)) { if (CE->getOpcode() == Instruction::Cast) - return getValueDest(*CE->getOperand(0)); + return NH = getValueDest(*CE->getOperand(0)); if (CE->getOpcode() == Instruction::GetElementPtr) { visitGetElementPtrInst(*CE); std::map::iterator I = ScalarMap.find(CE); assert(I != ScalarMap.end() && "GEP didn't get processed right?"); - DSNodeHandle NH = I->second; - ScalarMap.erase(I); // Remove constant from scalarmap - return NH; + return NH = I->second; } // This returns a conservative unknown node for any unhandled ConstExpr - return createNode(DSNode::UnknownNode); + return NH = createNode(DSNode::UnknownNode); } else if (ConstantIntegral *CI = dyn_cast(C)) { // Random constants are unknown mem - return createNode(DSNode::UnknownNode); + return NH = createNode(DSNode::UnknownNode); } else { assert(0 && "Unknown constant type!"); } - DSNodeHandle &NH = ScalarMap[V]; - if (NH.getNode()) - return NH; // Already have a node? Just return it... - // Otherwise we need to create a new node to point to... DSNode *N; if (GlobalValue *GV = dyn_cast(V)) { @@ -355,7 +356,7 @@ DSNodeHandle Dest = getValueDest(*SI.getOperand(1)); if (Dest.getNode() == 0) return; - // Make that the node is written to... + // Mark that the node is written to... Dest.getNode()->NodeType |= DSNode::Modified; // Ensure a typerecord exists... @@ -389,6 +390,14 @@ // Add a new function call entry... FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args)); +} + +void GraphBuilder::visitFreeInst(FreeInst &FI) { + DSNodeHandle Dest = getValueDest(*FI.getOperand(0)); + if (Dest.getNode() == 0) return; + + // Mark that the node is written to... + Dest.getNode()->NodeType |= DSNode::Modified; } /// Handle casts... From vadve at cs.uiuc.edu Fri Dec 6 15:20:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Fri Dec 6 15:20:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/IPModRef.h Message-ID: <200212062119.PAA24493@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: IPModRef.h updated: 1.7 -> 1.8 --- Log message: Stronger assertion in getNodeId(): node id must exist in the map. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/IPModRef.h diff -u llvm/include/llvm/Analysis/IPModRef.h:1.7 llvm/include/llvm/Analysis/IPModRef.h:1.8 --- llvm/include/llvm/Analysis/IPModRef.h:1.7 Wed Nov 27 11:38:56 2002 +++ llvm/include/llvm/Analysis/IPModRef.h Fri Dec 6 15:19:07 2002 @@ -153,8 +153,8 @@ // unsigned getNodeId (const DSNode* node) const { std::map::const_iterator iter = NodeIds.find(node); - assert(iter == NodeIds.end() || iter->second < funcModRefInfo.getSize()); - return (iter == NodeIds.end())? funcModRefInfo.getSize() : iter->second; + assert(iter != NodeIds.end() && iter->second < funcModRefInfo.getSize()); + return iter->second; } unsigned getNodeId (const Value* value) const; From lattner at cs.uiuc.edu Fri Dec 6 22:42:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Dec 6 22:42:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/PassNameParser.h Message-ID: <200212070441.WAA09988@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: PassNameParser.h updated: 1.3 -> 1.4 --- Log message: Give better error message if two passes of the same argument are registered --- Diffs of the changes: Index: llvm/include/llvm/Support/PassNameParser.h diff -u llvm/include/llvm/Support/PassNameParser.h:1.3 llvm/include/llvm/Support/PassNameParser.h:1.4 --- llvm/include/llvm/Support/PassNameParser.h:1.3 Tue Nov 19 11:10:14 2002 +++ llvm/include/llvm/Support/PassNameParser.h Fri Dec 6 22:41:22 2002 @@ -19,6 +19,7 @@ #include "Support/CommandLine.h" #include "llvm/Pass.h" #include +#include //===----------------------------------------------------------------------===// // PassNameParser class - Make use of the pass registration mechanism to @@ -56,8 +57,11 @@ // virtual void passRegistered(const PassInfo *P) { if (ignorablePass(P) || !Opt) return; - assert(findOption(P->getPassArgument()) == getNumOptions() && - "Two passes with the same argument attempted to be registered!"); + if (findOption(P->getPassArgument()) != getNumOptions()) { + std::cerr << "Two passes with the same argument (-" + << P->getPassArgument() << ") attempted to be registered!\n"; + abort(); + } addLiteralOption(P->getPassArgument(), P, P->getPassName()); Opt->addArgument(P->getPassArgument()); } From lattner at cs.uiuc.edu Sat Dec 7 11:09:02 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Dec 7 11:09:02 2002 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2002-11-07-Redefinition.c Message-ID: <200212071708.LAA21151@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2002-11-07-Redefinition.c added (r1.1) --- Log message: Check in an old testcase --- Diffs of the changes: From lattner at cs.uiuc.edu Sat Dec 7 12:43:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Dec 7 12:43:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GCSE.cpp Message-ID: <200212071842.MAA02904@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GCSE.cpp updated: 1.25 -> 1.26 --- Log message: Remove dead code --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/GCSE.cpp diff -u llvm/lib/Transforms/Scalar/GCSE.cpp:1.25 llvm/lib/Transforms/Scalar/GCSE.cpp:1.26 --- llvm/lib/Transforms/Scalar/GCSE.cpp:1.25 Mon Oct 21 15:00:26 2002 +++ llvm/lib/Transforms/Scalar/GCSE.cpp Sat Dec 7 12:42:13 2002 @@ -25,9 +25,6 @@ class GCSE : public FunctionPass { std::set WorkList; DominatorSet *DomSetInfo; -#if 0 - ImmediateDominators *ImmDominator; -#endif ValueNumbering *VN; public: virtual bool runOnFunction(Function &F); @@ -61,9 +58,6 @@ // Get pointers to the analysis results that we will be using... DomSetInfo = &getAnalysis(); -#if 0 - ImmDominator = &getAnalysis(); -#endif VN = &getAnalysis(); // Step #1: Add all instructions in the function to the worklist for @@ -254,32 +248,6 @@ // PRE than GCSE. // return 0; - -#if 0 - // Handle the most general case now. In this case, neither I dom Other nor - // Other dom I. Because we are in SSA form, we are guaranteed that the - // operands of the two instructions both dominate the uses, so we _know_ - // that there must exist a block that dominates both instructions (if the - // operands of the instructions are globals or constants, worst case we - // would get the entry node of the function). Search for this block now. - // - - // Search up the immediate dominator chain of BB1 for the shared dominator - BasicBlock *SharedDom = (*ImmDominator)[BB1]; - while (!DomSetInfo->dominates(SharedDom, BB2)) - SharedDom = (*ImmDominator)[SharedDom]; - - // At this point, shared dom must dominate BOTH BB1 and BB2... - assert(SharedDom && DomSetInfo->dominates(SharedDom, BB1) && - DomSetInfo->dominates(SharedDom, BB2) && "Dominators broken!"); - - // Rip 'I' out of BB1, and move it to the end of SharedDom. - BB1->getInstList().remove(I); - SharedDom->getInstList().insert(--SharedDom->end(), I); - - // Eliminate 'Other' now. - ReplaceInstWithInst(I, Other); -#endif } if (isa(Ret)) From lattner at cs.uiuc.edu Sat Dec 7 15:28:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Dec 7 15:28:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/ValueMapper.cpp Message-ID: <200212072127.PAA05284@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: ValueMapper.cpp updated: 1.1 -> 1.2 --- Log message: Fix bug that was bugging bugpoint --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/ValueMapper.cpp diff -u llvm/lib/Transforms/Utils/ValueMapper.cpp:1.1 llvm/lib/Transforms/Utils/ValueMapper.cpp:1.2 --- llvm/lib/Transforms/Utils/ValueMapper.cpp:1.1 Wed Nov 20 14:47:41 2002 +++ llvm/lib/Transforms/Utils/ValueMapper.cpp Sat Dec 7 15:27:16 2002 @@ -33,7 +33,7 @@ for (unsigned j = 0; j != i; ++j) Values.push_back(cast(Vals[j])); Values.push_back(cast(MV)); - for (; i != e; ++i) + for (++i; i != e; ++i) Values.push_back(cast(MapValue(Vals[i], VM))); return VMSlot = ConstantArray::get(CA->getType(), Values); } @@ -53,7 +53,7 @@ for (unsigned j = 0; j != i; ++j) Values.push_back(cast(Vals[j])); Values.push_back(cast(MV)); - for (; i != e; ++i) + for (++i; i != e; ++i) Values.push_back(cast(MapValue(Vals[i], VM))); return VMSlot = ConstantStruct::get(CS->getType(), Values); } From lattner at cs.uiuc.edu Sat Dec 7 17:25:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Dec 7 17:25:01 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/InstCount.cpp Message-ID: <200212072324.RAA10180@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: InstCount.cpp updated: 1.3 -> 1.4 --- Log message: Add total instruction, bb, & function counts --- Diffs of the changes: Index: llvm/lib/Analysis/InstCount.cpp diff -u llvm/lib/Analysis/InstCount.cpp:1.3 llvm/lib/Analysis/InstCount.cpp:1.4 --- llvm/lib/Analysis/InstCount.cpp:1.3 Tue Dec 3 13:40:16 2002 +++ llvm/lib/Analysis/InstCount.cpp Sat Dec 7 17:24:24 2002 @@ -10,6 +10,10 @@ #include "Support/Statistic.h" namespace { + Statistic<> TotalInsts ("instcount", "Number of instructions (of all types)"); + Statistic<> TotalBlocks("instcount", "Number of basic blocks"); + Statistic<> TotalFuncs ("instcount", "Number of non-external functions"); + #define HANDLE_INST(N, OPCODE, CLASS) \ Statistic<> Num##OPCODE##Inst("instcount", "Number of " #OPCODE " insts"); @@ -18,8 +22,11 @@ class InstCount : public Pass, public InstVisitor { friend class InstVisitor; + void visitFunction (Function &F) { ++TotalFuncs; } + void visitBasicBlock(BasicBlock &BB) { ++TotalBlocks; } + #define HANDLE_INST(N, OPCODE, CLASS) \ - void visit##OPCODE(CLASS &) { Num##OPCODE##Inst++; } + void visit##OPCODE(CLASS &) { ++Num##OPCODE##Inst; ++TotalInsts; } #include "llvm/Instruction.def" @@ -33,7 +40,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } - virtual void print(std::ostream &O, Module *M) const {} + virtual void print(std::ostream &O, const Module *M) const {} }; From lattner at cs.uiuc.edu Sat Dec 7 23:52:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Dec 7 23:52:01 2002 Subject: [llvm-commits] CVS: llvm/tools/lli/Execution.cpp lli.cpp Message-ID: <200212080551.XAA19998@apoc.cs.uiuc.edu> Changes in directory llvm/tools/lli: Execution.cpp updated: 1.71 -> 1.72 lli.cpp updated: 1.12 -> 1.13 --- Log message: Add support to count the number of dynamic instructions executed by LLI --- Diffs of the changes: Index: llvm/tools/lli/Execution.cpp diff -u llvm/tools/lli/Execution.cpp:1.71 llvm/tools/lli/Execution.cpp:1.72 --- llvm/tools/lli/Execution.cpp:1.71 Thu Nov 7 13:29:31 2002 +++ llvm/tools/lli/Execution.cpp Sat Dec 7 23:51:08 2002 @@ -15,6 +15,7 @@ #include "llvm/Assembly/Writer.h" #include "llvm/Target/TargetData.h" #include "Support/CommandLine.h" +#include "Support/Statistic.h" #include // For fmod #include #include @@ -22,6 +23,10 @@ using std::cout; using std::cerr; +namespace { + Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed"); +} + static cl::opt QuietMode("quiet", cl::desc("Do not emit any non-program output")); @@ -1250,6 +1255,9 @@ if (Trace) CW << "Run:" << I; + + // Track the number of dynamic instructions executed. + ++NumDynamicInsts; // Set a sigsetjmp buffer so that we can recover if an error happens during // instruction execution... Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.12 llvm/tools/lli/lli.cpp:1.13 --- llvm/tools/lli/lli.cpp:1.12 Thu Jul 25 11:39:56 2002 +++ llvm/tools/lli/lli.cpp Sat Dec 7 23:51:08 2002 @@ -21,10 +21,7 @@ cl::value_desc("function name")); static cl::opt -DebugMode("debug", cl::desc("Start program in debugger")); - -static cl::alias -DebugModeA("d", cl::desc("Alias for -debug"), cl::aliasopt(DebugMode)); +DebugMode("d", cl::desc("Start program in debugger")); static cl::opt TraceMode("trace", cl::desc("Enable Tracing")); From lattner at cs.uiuc.edu Sun Dec 8 00:02:01 2002 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Dec 8 00:02:01 2002 Subject: [llvm-commits] CVS: llvm/tools/lli/Execution.cpp Message-ID: <200212080601.AAA20110@apoc.cs.uiuc.edu> Changes in directory llvm/tools/lli: Execution.cpp updated: 1.72 -> 1.73 --- Log message: Namespacify more --- Diffs of the changes: Index: llvm/tools/lli/Execution.cpp diff -u llvm/tools/lli/Execution.cpp:1.72 llvm/tools/lli/Execution.cpp:1.73 --- llvm/tools/lli/Execution.cpp:1.72 Sat Dec 7 23:51:08 2002 +++ llvm/tools/lli/Execution.cpp Sun Dec 8 00:01:34 2002 @@ -25,20 +25,20 @@ namespace { Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed"); -} -static cl::opt -QuietMode("quiet", cl::desc("Do not emit any non-program output")); + cl::opt + QuietMode("quiet", cl::desc("Do not emit any non-program output")); -static cl::alias -QuietModeA("q", cl::desc("Alias for -quiet"), cl::aliasopt(QuietMode)); + cl::alias + QuietModeA("q", cl::desc("Alias for -quiet"), cl::aliasopt(QuietMode)); -static cl::opt -ArrayChecksEnabled("array-checks", cl::desc("Enable array bound checks")); + cl::opt + ArrayChecksEnabled("array-checks", cl::desc("Enable array bound checks")); -static cl::opt -AbortOnExceptions("abort-on-exception", - cl::desc("Halt execution on a machine exception")); + cl::opt + AbortOnExceptions("abort-on-exception", + cl::desc("Halt execution on a machine exception")); +} // Create a TargetData structure to handle memory addressing and size/alignment // computations From vadve at cs.uiuc.edu Sun Dec 8 07:27:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Dec 8 07:27:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DependenceGraph.h MemoryDepAnalysis.h Message-ID: <200212081326.HAA04255@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DependenceGraph.h added (r1.1) MemoryDepAnalysis.h added (r1.1) --- Log message: An explicit representation of dependence graphs, and a pass that computes a dependence graph for data dependences on memory locations using interprocedural Mod/Ref information. --- Diffs of the changes: From vadve at cs.uiuc.edu Sun Dec 8 07:27:05 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Dec 8 07:27:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DependenceGraph.cpp MemoryDepAnalysis.cpp Message-ID: <200212081326.HAA04268@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: DependenceGraph.cpp added (r1.1) MemoryDepAnalysis.cpp added (r1.1) --- Log message: An explicit representation of dependence graphs, and a pass that computes a dependence graph for data dependences on memory locations using interprocedural Mod/Ref information. --- Diffs of the changes: From vadve at cs.uiuc.edu Sun Dec 8 08:14:01 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Dec 8 08:14:01 2002 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/PgmDependenceGraph.h Message-ID: <200212081413.IAA04473@psmith.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: PgmDependenceGraph.h added (r1.1) --- Log message: Iterator that enumerates the ProgramDependenceGraph (PDG) for a function, i.e., enumerates all data and control dependences for the function. --- Diffs of the changes: From vadve at cs.uiuc.edu Sun Dec 8 08:14:05 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Dec 8 08:14:05 2002 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PgmDependenceGraph.cpp Message-ID: <200212081413.IAA04481@psmith.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PgmDependenceGraph.cpp added (r1.1) --- Log message: Iterator that enumerates the ProgramDependenceGraph (PDG) for a function, i.e., enumerates all data and control dependences for the function. --- Diffs of the changes: From vadve at cs.uiuc.edu Sun Dec 8 22:47:00 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Dec 8 22:47:00 2002 Subject: [llvm-commits] CVS: llvm/tools/opt/Makefile Message-ID: <200212090446.WAA14845@psmith.cs.uiuc.edu> Changes in directory llvm/tools/opt: Makefile updated: 1.36 -> 1.37 --- Log message: Repeat ipa.a. Since IPModRef is currently only used in analysis.o, it was causing linking errors. --- Diffs of the changes: Index: llvm/tools/opt/Makefile diff -u llvm/tools/opt/Makefile:1.36 llvm/tools/opt/Makefile:1.37 --- llvm/tools/opt/Makefile:1.36 Tue Nov 19 10:59:41 2002 +++ llvm/tools/opt/Makefile Sun Dec 8 22:46:25 2002 @@ -5,7 +5,7 @@ sparc mapping regalloc.a sched select codegen preopts \ postopts.a \ livevar scalaropts \ - ipo ipa.a datastructure transforms target.a analysis \ + ipo ipa.a datastructure transforms target.a analysis ipa.a \ transformutils vmcore support TOOLLINKOPTS = -ldl From vadve at cs.uiuc.edu Sun Dec 8 23:54:02 2002 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sun Dec 8 23:54:02 2002 Subject: [llvm-commits] CVS: llvm/tools/llc/Makefile Message-ID: <200212090553.XAA14969@psmith.cs.uiuc.edu> Changes in directory llvm/tools/llc: Makefile updated: 1.32 -> 1.33 --- Log message: Fix link errors due to new IPModRef pass. --- Diffs of the changes: Index: llvm/tools/llc/Makefile diff -u llvm/tools/llc/Makefile:1.32 llvm/tools/llc/Makefile:1.33 --- llvm/tools/llc/Makefile:1.32 Wed Nov 6 10:10:57 2002 +++ llvm/tools/llc/Makefile Sun Dec 8 23:53:11 2002 @@ -14,15 +14,17 @@ bcreader \ bcwriter \ ipo \ - ipa.a \ - datastructure.a \ scalaropts \ transforms \ analysis \ + ipa \ + datastructure \ transformutils \ vmcore \ support TOOLLINKOPTS = -ldl + +KEEP_SYMBOLS = 1 include $(LEVEL)/Makefile.common