diff options
-rw-r--r-- | tools/llvm-upgrade/ParserInternals.h | 173 | ||||
-rw-r--r-- | tools/llvm-upgrade/UpgradeLexer.l | 4 | ||||
-rw-r--r-- | tools/llvm-upgrade/UpgradeParser.y | 699 |
3 files changed, 563 insertions, 313 deletions
diff --git a/tools/llvm-upgrade/ParserInternals.h b/tools/llvm-upgrade/ParserInternals.h index 85182c5..9de3588 100644 --- a/tools/llvm-upgrade/ParserInternals.h +++ b/tools/llvm-upgrade/ParserInternals.h @@ -15,9 +15,11 @@ #ifndef PARSER_INTERNALS_H #define PARSER_INTERNALS_H +#include <llvm/ADT/StringExtras.h> #include <string> #include <istream> #include <vector> +#include <cassert> // Global variables exported from the lexer... @@ -26,11 +28,15 @@ extern std::string Textin; extern int Upgradelineno; extern std::istream* LexInput; +struct TypeInfo; +typedef std::vector<TypeInfo*> TypeList; void UpgradeAssembly( const std::string & infile, std::istream& in, std::ostream &out, bool debug, bool addAttrs); +TypeInfo* ResolveType(TypeInfo*& Ty); + // Globals exported by the parser... extern char* Upgradetext; extern int Upgradeleng; @@ -47,6 +53,17 @@ enum Types { OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, NumericTy }; +/// This type is used to keep track of the signedness of values. Instead +/// of creating llvm::Value directly, the parser will create ValueInfo which +/// associates a Value* with a Signedness indication. +struct ValueInfo { + std::string* val; + TypeInfo* type; + bool constant; + bool isConstant() const { return constant; } + inline void destroy(); +}; + /// This type is used to keep track of the signedness of the obsolete /// integer types. Instead of creating an llvm::Type directly, the Lexer will /// create instances of TypeInfo which retains the signedness indication so @@ -55,20 +72,89 @@ enum Types { /// to "int32" and the "second" field will be set to "isUnsigned". If the /// type is not obsolete then "second" will be set to "isSignless". struct TypeInfo { - std::string* newTy; - Types oldTy; - Types elemTy; + TypeInfo() + : newTy(0), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0), + nelems(0) { + } + + TypeInfo(const char * newType, Types oldType) + : newTy(0), oldTy(oldType), elemTy(0), resultTy(0), elements(0), nelems(0) { + newTy = new std::string(newType); + } + + TypeInfo(std::string *newType, Types oldType, TypeInfo* eTy = 0, + TypeInfo *rTy = 0) + : newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(rTy), elements(0), + nelems(0) { + } + + TypeInfo(std::string *newType, Types oldType, TypeInfo *eTy, uint64_t elems) + : newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(0), elements(0), + nelems(elems) { + } + + TypeInfo(std::string *newType, Types oldType, TypeList* TL) + : newTy(newType), oldTy(oldType), elemTy(0), resultTy(0), elements(TL), + nelems(0) { + } + + TypeInfo(std::string *newType, TypeInfo* resTy, TypeList* TL) + : newTy(newType), oldTy(FunctionTy), elemTy(0), resultTy(resTy), + elements(TL), nelems(0) { + } + + TypeInfo(const TypeInfo& that) + : newTy(0), oldTy(that.oldTy), elemTy(0), resultTy(0), elements(0), + nelems(0) { + *this = that; + } + + TypeInfo& operator=(const TypeInfo& that) { + oldTy = that.oldTy; + nelems = that.nelems; + if (that.newTy) + newTy = new std::string(*that.newTy); + if (that.elemTy) + elemTy = that.elemTy->clone(); + if (that.resultTy) + resultTy = that.resultTy->clone(); + if (that.elements) { + elements = new std::vector<TypeInfo*>(that.elements->size()); + *elements = *that.elements; + } + return *this; + } - void destroy() const { delete newTy; } + ~TypeInfo() { + delete newTy; delete elemTy; delete resultTy; delete elements; + } - TypeInfo clone() const { - TypeInfo result = *this; - result.newTy = new std::string(*newTy); - return result; + TypeInfo* clone() const { + return new TypeInfo(*this); } - Types getElementType() const { return elemTy; } + Types getElementTy() const { + if (elemTy) { + return elemTy->oldTy; + } + return UnresolvedTy; + } + + const std::string& getNewTy() const { return *newTy; } + void setOldTy(Types Ty) { oldTy = Ty; } + + TypeInfo* getResultType() const { return resultTy; } + TypeInfo* getElementType() const { return elemTy; } + TypeInfo* getPointerType() const { + std::string* ty = new std::string(*newTy + "*"); + return new TypeInfo(ty, PointerTy, this->clone(), (TypeInfo*)0); + } + + bool isUnresolved() const { return oldTy == UnresolvedTy; } + bool isNumeric() const { return oldTy == NumericTy; } + bool isVoid() const { return oldTy == VoidTy; } + bool isBool() const { return oldTy == BoolTy; } bool isSigned() const { return oldTy == SByteTy || oldTy == ShortTy || oldTy == IntTy || oldTy == LongTy; @@ -79,9 +165,6 @@ struct TypeInfo { oldTy == UIntTy || oldTy == ULongTy; } - bool isBool() const { - return oldTy == BoolTy; - } bool isSignless() const { return !isSigned() && !isUnsigned(); } bool isInteger() const { return isSigned() || isUnsigned(); } @@ -89,8 +172,14 @@ struct TypeInfo { bool isFloatingPoint() const { return oldTy == DoubleTy || oldTy == FloatTy; } bool isPacked() const { return oldTy == PackedTy; } bool isPointer() const { return oldTy == PointerTy; } + bool isStruct() const { return oldTy == StructTy || oldTy == PackedStructTy; } + bool isArray() const { return oldTy == ArrayTy; } bool isOther() const { return !isPacked() && !isPointer() && !isFloatingPoint() && !isIntegral(); } + bool isFunction() const { return oldTy == FunctionTy; } + bool isComposite() const { + return isStruct() || isPointer() || isArray() || isPacked(); + } bool isAttributeCandidate() const { return isIntegral() && getBitWidth() < 32; @@ -98,6 +187,7 @@ struct TypeInfo { unsigned getBitWidth() const { switch (oldTy) { + default: case LabelTy: case VoidTy : return 0; case BoolTy : return 1; @@ -106,32 +196,61 @@ struct TypeInfo { case IntTy: case UIntTy: case FloatTy: return 32; case LongTy: case ULongTy: case DoubleTy : return 64; case PointerTy: return SizeOfPointer; // global var - default: - return 128; /// Struct/Packed/Array --> doesn't matter - + case PackedTy: + case ArrayTy: + return nelems * elemTy->getBitWidth(); + case StructTy: + case PackedStructTy: { + uint64_t size = 0; + for (unsigned i = 0; i < elements->size(); i++) { + ResolveType((*elements)[i]); + size += (*elements)[i]->getBitWidth(); + } + return size; + } } } -}; -/// This type is used to keep track of the signedness of values. Instead -/// of creating llvm::Value directly, the parser will create ValueInfo which -/// associates a Value* with a Signedness indication. -struct ValueInfo { - std::string* val; - TypeInfo type; - bool constant; - bool isConstant() const { return constant; } - void destroy() { delete val; type.destroy(); } + TypeInfo* getIndexedType(const ValueInfo& VI) { + if (isStruct()) { + if (VI.isConstant() && VI.type->isInteger()) { + size_t pos = VI.val->find(' ') + 1; + if (pos < VI.val->size()) { + uint64_t idx = atoi(VI.val->substr(pos).c_str()); + return (*elements)[idx]; + } else { + yyerror("Invalid value for constant integer"); + return 0; + } + } else { + yyerror("Structure requires constant index"); + return 0; + } + } + if (isArray() || isPacked() || isPointer()) + return elemTy; + yyerror("Invalid type for getIndexedType"); + return 0; + } + +private: + std::string* newTy; + Types oldTy; + TypeInfo *elemTy; + TypeInfo *resultTy; + TypeList *elements; + uint64_t nelems; }; /// This type is used to keep track of the signedness of constants. struct ConstInfo { std::string *cnst; - TypeInfo type; - void destroy() { delete cnst; type.destroy(); } + TypeInfo *type; + void destroy() { delete cnst; delete type; } }; typedef std::vector<ValueInfo> ValueList; +inline void ValueInfo::destroy() { delete val; delete type; } #endif diff --git a/tools/llvm-upgrade/UpgradeLexer.l b/tools/llvm-upgrade/UpgradeLexer.l index 8ffca76..d9e5d0e 100644 --- a/tools/llvm-upgrade/UpgradeLexer.l +++ b/tools/llvm-upgrade/UpgradeLexer.l @@ -48,9 +48,7 @@ return sym #define RET_TY(sym,OldTY,NewTY,sign) \ - Upgradelval.Type.newTy = new std::string(NewTY); \ - Upgradelval.Type.oldTy = OldTY; \ - Upgradelval.Type.elemTy = VoidTy; \ + Upgradelval.Type = new TypeInfo(NewTY, OldTY); \ return sym #define YY_NEVER_INTERACTIVE 1 diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y index 761bda1..12ad182 100644 --- a/tools/llvm-upgrade/UpgradeParser.y +++ b/tools/llvm-upgrade/UpgradeParser.y @@ -13,12 +13,10 @@ %{ #include "ParserInternals.h" -#include <llvm/ADT/StringExtras.h> #include <algorithm> #include <map> #include <utility> #include <iostream> -#include <cassert> #define YYERROR_VERBOSE 1 #define YYINCLUDED_STDLIB_H @@ -78,71 +76,72 @@ void UpgradeAssembly(const std::string &infile, std::istream& in, } } -static void ResolveType(TypeInfo& Ty) { - if (Ty.oldTy == UnresolvedTy) { - TypeMap::iterator I = NamedTypes.find(*Ty.newTy); +TypeInfo* ResolveType(TypeInfo*& Ty) { + if (Ty->isUnresolved()) { + TypeMap::iterator I = NamedTypes.find(Ty->getNewTy()); if (I != NamedTypes.end()) { - Ty.oldTy = I->second.oldTy; - Ty.elemTy = I->second.elemTy; + Ty = I->second.clone(); + return Ty; } else { - std::string msg("Can't resolve type: "); - msg += *Ty.newTy; + std::string msg("Cannot resolve type: "); + msg += Ty->getNewTy(); yyerror(msg.c_str()); } - } else if (Ty.oldTy == NumericTy) { - unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\' + } else if (Ty->isNumeric()) { + unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // Skip the '\\' if (ref < EnumeratedTypes.size()) { - Ty.oldTy = EnumeratedTypes[ref].oldTy; - Ty.elemTy = EnumeratedTypes[ref].elemTy; + Ty = EnumeratedTypes[ref].clone(); + return Ty; } else { std::string msg("Can't resolve type: "); - msg += *Ty.newTy; + msg += Ty->getNewTy(); yyerror(msg.c_str()); } } // otherwise its already resolved. + return Ty; } static const char* getCastOpcode( - std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy) + std::string& Source, const TypeInfo* SrcTy, const TypeInfo* DstTy) { - unsigned SrcBits = SrcTy.getBitWidth(); - unsigned DstBits = DstTy.getBitWidth(); + unsigned SrcBits = SrcTy->getBitWidth(); + unsigned DstBits = DstTy->getBitWidth(); const char* opcode = "bitcast"; // Run through the possibilities ... - if (DstTy.isIntegral()) { // Casting to integral - if (SrcTy.isIntegral()) { // Casting from integral + if (DstTy->isIntegral()) { // Casting to integral + if (SrcTy->isIntegral()) { // Casting from integral if (DstBits < SrcBits) opcode = "trunc"; else if (DstBits > SrcBits) { // its an extension - if (SrcTy.isSigned()) + if (SrcTy->isSigned()) opcode ="sext"; // signed -> SEXT else opcode = "zext"; // unsigned -> ZEXT } else { opcode = "bitcast"; // Same size, No-op cast } - } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt - if (DstTy.isSigned()) + } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt + if (DstTy->isSigned()) opcode = "fptosi"; // FP -> sint else opcode = "fptoui"; // FP -> uint - } else if (SrcTy.isPacked()) { - assert(DstBits == SrcTy.getBitWidth() && + } else if (SrcTy->isPacked()) { + assert(DstBits == SrcTy->getBitWidth() && "Casting packed to integer of different width"); opcode = "bitcast"; // same size, no-op cast } else { - assert(SrcTy.isPointer() && + assert(SrcTy->isPointer() && "Casting from a value that is not first-class type"); opcode = "ptrtoint"; // ptr -> int } - } else if (DstTy.isFloatingPoint()) { // Casting to floating pt - if (SrcTy.isIntegral()) { // Casting from integral - if (SrcTy.isSigned()) + } else if (DstTy->isFloatingPoint()) { // Casting to floating pt + if (SrcTy->isIntegral()) { // Casting from integral + if (SrcTy->isSigned()) opcode = "sitofp"; // sint -> FP else opcode = "uitofp"; // uint -> FP - } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt + } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt if (DstBits < SrcBits) { opcode = "fptrunc"; // FP -> smaller FP } else if (DstBits > SrcBits) { @@ -150,27 +149,27 @@ static const char* getCastOpcode( } else { opcode ="bitcast"; // same size, no-op cast } - } else if (SrcTy.isPacked()) { - assert(DstBits == SrcTy.getBitWidth() && + } else if (SrcTy->isPacked()) { + assert(DstBits == SrcTy->getBitWidth() && "Casting packed to floating point of different width"); opcode = "bitcast"; // same size, no-op cast } else { assert(0 && "Casting pointer or non-first class to float"); } - } else if (DstTy.isPacked()) { - if (SrcTy.isPacked()) { - assert(DstTy.getBitWidth() == SrcTy.getBitWidth() && + } else if (DstTy->isPacked()) { + if (SrcTy->isPacked()) { + assert(DstTy->getBitWidth() == SrcTy->getBitWidth() && "Casting packed to packed of different widths"); opcode = "bitcast"; // packed -> packed - } else if (DstTy.getBitWidth() == SrcBits) { + } else if (DstTy->getBitWidth() == SrcBits) { opcode = "bitcast"; // float/int -> packed } else { assert(!"Illegal cast to packed (wrong type or size)"); } - } else if (DstTy.isPointer()) { - if (SrcTy.isPointer()) { + } else if (DstTy->isPointer()) { + if (SrcTy->isPointer()) { opcode = "bitcast"; // ptr -> ptr - } else if (SrcTy.isIntegral()) { + } else if (SrcTy->isIntegral()) { opcode = "inttoptr"; // int -> ptr } else { assert(!"Casting invalid type to pointer"); @@ -181,12 +180,12 @@ static const char* getCastOpcode( return opcode; } -static std::string getCastUpgrade( - const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst) +static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy, + TypeInfo* DstTy, bool isConst) { std::string Result; std::string Source = Src; - if (SrcTy.isFloatingPoint() && DstTy.isPointer()) { + if (SrcTy->isFloatingPoint() && DstTy->isPointer()) { // fp -> ptr cast is no longer supported but we must upgrade this // by doing a double cast: fp -> int -> ptr if (isConst) @@ -197,16 +196,16 @@ static std::string getCastUpgrade( Source = "i64 %cast_upgrade" + llvm::utostr(unique); } // Update the SrcTy for the getCastOpcode call below - SrcTy.destroy(); - SrcTy.newTy = new std::string("i64"); - SrcTy.oldTy = ULongTy; - } else if (DstTy.oldTy == BoolTy && SrcTy.oldTy != BoolTy) { - // cast ptr %x to bool was previously defined as setne ptr %x, null - // The ptrtoint semantic is to truncate, not compare so we must retain - // the original intent by replace the cast with a setne - const char* comparator = SrcTy.isPointer() ? ", null" : - (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0"); - const char* compareOp = SrcTy.isFloatingPoint() ? "fcmp one " : "icmp ne "; + delete SrcTy; + SrcTy = new TypeInfo("i64", ULongTy); + } else if (DstTy->isBool()) { + // cast type %x to bool was previously defined as setne type %x, null + // The cast semantic is now to truncate, not compare so we must retain + // the original intent by replacing the cast with a setne + const char* comparator = SrcTy->isPointer() ? ", null" : + (SrcTy->isFloatingPoint() ? ", 0.0" : + (SrcTy->isBool() ? ", false" : ", 0")); + const char* compareOp = SrcTy->isFloatingPoint() ? "fcmp one " : "icmp ne "; if (isConst) { Result = "(" + Source + comparator + ")"; Result = compareOp + Result; @@ -218,33 +217,32 @@ static std::string getCastUpgrade( ResolveType(DstTy); std::string Opcode(getCastOpcode(Source, SrcTy, DstTy)); if (isConst) - Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")"; + Result += Opcode + "( " + Source + " to " + DstTy->getNewTy() + ")"; else - Result += Opcode + " " + Source + " to " + *DstTy.newTy; + Result += Opcode + " " + Source + " to " + DstTy->getNewTy(); return Result; } -const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) { +const char* getDivRemOpcode(const std::string& opcode, TypeInfo* TI) { const char* op = opcode.c_str(); - TypeInfo Ty = TI; - ResolveType(Ty); - if (Ty.isPacked()) - Ty.oldTy = Ty.getElementType(); + const TypeInfo* Ty = ResolveType(TI); + if (Ty->isPacked()) + Ty = Ty->getElementType(); if (opcode == "div") - if (Ty.isFloatingPoint()) + if (Ty->isFloatingPoint()) op = "fdiv"; - else if (Ty.isUnsigned()) + else if (Ty->isUnsigned()) op = "udiv"; - else if (Ty.isSigned()) + else if (Ty->isSigned()) op = "sdiv"; else yyerror("Invalid type for div instruction"); else if (opcode == "rem") - if (Ty.isFloatingPoint()) + if (Ty->isFloatingPoint()) op = "frem"; - else if (Ty.isUnsigned()) + else if (Ty->isUnsigned()) op = "urem"; - else if (Ty.isSigned()) + else if (Ty->isSigned()) op = "srem"; else yyerror("Invalid type for rem instruction"); @@ -252,7 +250,7 @@ const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) { } std::string -getCompareOp(const std::string& setcc, const TypeInfo& TI) { +getCompareOp(const std::string& setcc, const TypeInfo* TI) { assert(setcc.length() == 5); char cc1 = setcc[3]; char cc2 = setcc[4]; @@ -261,20 +259,20 @@ getCompareOp(const std::string& setcc, const TypeInfo& TI) { std::string result("xcmp xxx"); result[6] = cc1; result[7] = cc2; - if (TI.isFloatingPoint()) { + if (TI->isFloatingPoint()) { result[0] = 'f'; result[5] = 'o'; if (cc1 == 'n') result[5] = 'u'; // NE maps to unordered else result[5] = 'o'; // everything else maps to ordered - } else if (TI.isIntegral() || TI.isPointer()) { + } else if (TI->isIntegral() || TI->isPointer()) { result[0] = 'i'; if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e')) result.erase(5,1); - else if (TI.isSigned()) + else if (TI->isSigned()) result[5] = 's'; - else if (TI.isUnsigned() || TI.isPointer() || TI.isBool()) + else if (TI->isUnsigned() || TI->isPointer() || TI->isBool()) result[5] = 'u'; else yyerror("Invalid integral type for setcc"); @@ -282,16 +280,87 @@ getCompareOp(const std::string& setcc, const TypeInfo& TI) { return result; } +static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) { + ResolveType(PFTy); + if (PFTy->isPointer()) { + TypeInfo* ElemTy = PFTy->getElementType(); + ResolveType(ElemTy); + if (ElemTy->isFunction()) + return ElemTy->getResultType()->clone(); + } else if (PFTy->isFunction()) { + return PFTy->getResultType()->clone(); + } + return PFTy->clone(); +} + +static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) { + ResolveType(PTy); + assert(PTy->isPointer() && "GEP Operand is not a pointer?"); + TypeInfo* Result = PTy->getElementType(); // just skip first index + ResolveType(Result); + for (unsigned i = 1; i < idxs->size(); ++i) { + if (Result->isComposite()) { + Result = Result->getIndexedType((*idxs)[i]); + ResolveType(Result); + } else + yyerror("Invalid type for index"); + } + return Result->getPointerType(); +} + +static std::string makeUniqueName(const std::string *Name, bool isSigned) { + const char *suffix = ".u"; + if (isSigned) + suffix = ".s"; + if ((*Name)[Name->size()-1] == '"') { + std::string Result(*Name); + Result.insert(Name->size()-1, suffix); + return Result; + } + return *Name + suffix; +} + +// This function handles appending .u or .s to integer value names that +// were previously unsigned or signed, respectively. This avoids name +// collisions since the unsigned and signed type planes have collapsed +// into a single signless type plane. +static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) { + // If its not a symbolic name, don't modify it, probably a constant val. + if ((*Name)[0] != '%' && (*Name)[0] != '"') + return *Name; + // If its a numeric reference, just leave it alone. + if (isdigit((*Name)[1])) + return *Name; + + // Resolve the type + ResolveType(Ty); + + // Default the result to the current name + std::string Result = *Name; + + if (Ty->isInteger()) { + // If its an integer type, make the name unique + Result = makeUniqueName(Name, Ty->isSigned()); + } else if (Ty->isPointer()) { + while (Ty->isPointer()) + Ty = Ty->getElementType(); + if (Ty->isInteger()) + Result = makeUniqueName(Name, Ty->isSigned()); + } + return Result; +} + %} // %file-prefix="UpgradeParser" %union { std::string* String; - TypeInfo Type; + TypeInfo* Type; ValueInfo Value; ConstInfo Const; ValueList* ValList; + TypeList* TypeVec; } %token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG @@ -322,19 +391,20 @@ getCompareOp(const std::string& setcc, const TypeInfo& TI) { %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute -%type <String> ArgTypeListI ConstExpr DefinitionList +%type <String> ConstExpr DefinitionList %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END -%type <String> Function FunctionProto BasicBlock TypeListI -%type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList -%type <String> OptTailCall InstVal OptVolatile Unwind -%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType +%type <String> Function FunctionProto BasicBlock +%type <String> InstructionList BBTerminatorInst JumpTable Inst +%type <String> OptTailCall OptVolatile Unwind +%type <String> SymbolicValueRef OptSideEffect GlobalType %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock %type <String> Name ConstValueRef ConstVector External %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps %type <String> IPredicates FPredicates %type <ValList> ValueRefList ValueRefListE IndexList +%type <TypeVec> TypeListI ArgTypeListI %type <Type> IntType SIntType UIntType FPType TypesV Types %type <Type> PrimType UpRTypesV UpRTypes @@ -342,7 +412,7 @@ getCompareOp(const std::string& setcc, const TypeInfo& TI) { %type <String> IntVal EInt64Val %type <Const> ConstVal -%type <Value> ValueRef ResolvedVal +%type <Value> ValueRef ResolvedVal InstVal PHIList MemoryInst %start Module @@ -456,68 +526,79 @@ PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ; PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL; UpRTypes : OPAQUE { - $$.newTy = $1; - $$.oldTy = OpaqueTy; + $$ = new TypeInfo($1, OpaqueTy); } | SymbolicValueRef { - $$.newTy = $1; - $$.oldTy = UnresolvedTy; + $$ = new TypeInfo($1, UnresolvedTy); } | PrimType { $$ = $1; } | '\\' EUINT64VAL { // Type UpReference $2->insert(0, "\\"); - $$.newTy = $2; - $$.oldTy = NumericTy; + $$ = new TypeInfo($2, NumericTy); } | UpRTypesV '(' ArgTypeListI ')' { // Function derived type? - *$1.newTy += "( " + *$3 + " )"; - delete $3; - $$.newTy = $1.newTy; - $$.oldTy = FunctionTy; + std::string newTy( $1->getNewTy() + "("); + for (unsigned i = 0; i < $3->size(); ++i) { + if (i != 0) + newTy += ", "; + if ((*$3)[i]->isVoid()) + newTy += "..."; + else + newTy += (*$3)[i]->getNewTy(); + } + newTy += ")"; + $$ = new TypeInfo(new std::string(newTy), $1, $3); + EnumeratedTypes.push_back(*$$); } | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type? $2->insert(0,"[ "); - *$2 += " x " + *$4.newTy + " ]"; - delete $4.newTy; - $$.newTy = $2; - $$.oldTy = ArrayTy; - $$.elemTy = $4.oldTy; + *$2 += " x " + $4->getNewTy() + " ]"; + uint64_t elems = atoi($2->c_str()); + $$ = new TypeInfo($2, ArrayTy, $4, elems); + EnumeratedTypes.push_back(*$$); } | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type? $2->insert(0,"< "); - *$2 += " x " + *$4.newTy + " >"; - delete $4.newTy; - $$.newTy = $2; - $$.oldTy = PackedTy; - $$.elemTy = $4.oldTy; + *$2 += " x " + $4->getNewTy() + " >"; + uint64_t elems = atoi($2->c_str()); + $$ = new TypeInfo($2, PackedTy, $4, elems); + EnumeratedTypes.push_back(*$$); } | '{' TypeListI '}' { // Structure type? - $2->insert(0, "{ "); - *$2 += " }"; - $$.newTy = $2; - $$.oldTy = StructTy; + std::string newTy("{"); + for (unsigned i = 0; i < $2->size(); ++i) { + if (i != 0) + newTy += ", "; + newTy += (*$2)[i]->getNewTy(); + } + newTy += "}"; + $$ = new TypeInfo(new std::string(newTy), StructTy, $2); + EnumeratedTypes.push_back(*$$); } | '{' '}' { // Empty structure type? - $$.newTy = new std::string("{}"); - $$.oldTy = StructTy; + $$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList()); + EnumeratedTypes.push_back(*$$); } | '<' '{' TypeListI '}' '>' { // Packed Structure type? - $3->insert(0, "<{ "); - *$3 += " }>"; - $$.newTy = $3; - $$.oldTy = StructTy; + std::string newTy("<{"); + for (unsigned i = 0; i < $3->size(); ++i) { + if (i != 0) + newTy += ", "; + newTy += (*$3)[i]->getNewTy(); + } + newTy += "}>"; + $$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3); + EnumeratedTypes.push_back(*$$); } | '<' '{' '}' '>' { // Empty packed structure type? - $$.newTy = new std::string("<{}>"); - $$.oldTy = StructTy; + $$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList()); + EnumeratedTypes.push_back(*$$); } | UpRTypes '*' { // Pointer type? - *$1.newTy += '*'; - $$.elemTy = $1.oldTy; - $1.oldTy = PointerTy; - $$ = $1; + $$ = $1->getPointerType(); + EnumeratedTypes.push_back(*$$); }; // TypeList - Used for struct declarations and as a basis for function type @@ -525,27 +606,29 @@ UpRTypes // TypeListI : UpRTypes { - $$ = $1.newTy; + $$ = new TypeList(); + $$->push_back($1); } | TypeListI ',' UpRTypes { - *$1 += ", " + *$3.newTy; - delete $3.newTy; $$ = $1; + $$->push_back($3); }; // ArgTypeList - List of types for a function type declaration... ArgTypeListI : TypeListI | TypeListI ',' DOTDOTDOT { - *$1 += ", ..."; - delete $3; $$ = $1; + $$->push_back(new TypeInfo("void",VoidTy)); + delete $3; } | DOTDOTDOT { - $$ = $1; + $$ = new TypeList(); + $$->push_back(new TypeInfo("void",VoidTy)); + delete $1; } | /*empty*/ { - $$ = new std::string(); + $$ = new TypeList(); }; // ConstVal - The various declarations that go into the constant pool. This @@ -556,95 +639,96 @@ ArgTypeListI // ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " [ " + *$3 + " ]"; delete $3; } | Types '[' ']' { $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += "[ ]"; } | Types 'c' STRINGCONSTANT { $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " c" + *$3; delete $3; } | Types '<' ConstVector '>' { // Nonempty unsized arr $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " < " + *$3 + " >"; delete $3; } | Types '{' ConstVector '}' { $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " { " + *$3 + " }"; delete $3; } | Types '{' '}' { $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " {}"; } | Types NULL_TOK { $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; } | Types UNDEF { $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; } | Types SymbolicValueRef { + std::string Name = getUniqueName($2,$1); $$.type = $1; - $$.cnst = new std::string(*$1.newTy); - *$$.cnst += " " + *$2; + $$.cnst = new std::string($1->getNewTy()); + *$$.cnst += " " + Name; delete $2; } | Types ConstExpr { $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; } | Types ZEROINITIALIZER { $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; } | SIntType EInt64Val { // integral constants $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; } | UIntType EUINT64VAL { // integral constants $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; } | BOOL TRUETOK { // Boolean constants $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; } | BOOL FALSETOK { // Boolean constants $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; } | FPType FPVAL { // Float & Double constants $$.type = $1; - $$.cnst = new std::string(*$1.newTy); + $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + *$2; delete $2; }; @@ -652,17 +736,16 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr ConstExpr: CastOps '(' ConstVal TO Types ')' { std::string source = *$3.cnst; - TypeInfo DstTy = $5; - ResolveType(DstTy); + TypeInfo* DstTy = ResolveType($5); if (*$1 == "cast") { // Call getCastUpgrade to upgrade the old cast - $$ = new std::string(getCastUpgrade(source, $3.type, $5, true)); + $$ = new std::string(getCastUpgrade(source, $3.type, DstTy, true)); } else { // Nothing to upgrade, just create the cast constant expr $$ = new std::string(*$1); - *$$ += "( " + source + " to " + *$5.newTy + ")"; + *$$ += "( " + source + " to " + $5->getNewTy() + ")"; } - delete $1; $3.destroy(); delete $4; $5.destroy(); + delete $1; $3.destroy(); delete $4; delete $5; } | GETELEMENTPTR '(' ConstVal IndexList ')' { *$1 += "(" + *$3.cnst; @@ -711,7 +794,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' { | ShiftOps '(' ConstVal ',' ConstVal ')' { const char* shiftop = $1->c_str(); if (*$1 == "shr") - shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr"; + shiftop = ($3.type->isUnsigned()) ? "lshr" : "ashr"; $$ = new std::string(shiftop); *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")"; delete $1; $3.destroy(); $5.destroy(); @@ -783,15 +866,13 @@ External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; } // ConstPool - Constants with optional names assigned to them. ConstPool : ConstPool OptAssign TYPE TypesV { - EnumeratedTypes.push_back($4); + EnumeratedTypes.push_back(*$4); if (!$2->empty()) { - NamedTypes[*$2].newTy = new std::string(*$4.newTy); - NamedTypes[*$2].oldTy = $4.oldTy; - NamedTypes[*$2].elemTy = $4.elemTy; + NamedTypes[*$2] = *$4; *O << *$2 << " = "; } - *O << "type " << *$4.newTy << '\n'; - delete $2; delete $3; $4.destroy(); + *O << "type " << $4->getNewTy() << '\n'; + delete $2; delete $3; $$ = 0; } | ConstPool FunctionProto { // Function prototypes can be in const pool @@ -806,38 +887,42 @@ ConstPool : ConstPool OptAssign TYPE TypesV { } | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes { if (!$2->empty()) { - *O << *$2 << " = "; - Globals[*$2] = $5.type.clone(); + std::string Name = getUniqueName($2,$5.type); + *O << Name << " = "; + Globals[Name] = *$5.type; } *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n'; - delete $2; delete $3; delete $4; $5.destroy(); delete $6; + delete $2; delete $3; delete $4; delete $6; $$ = 0; } | ConstPool OptAssign External GlobalType Types GlobalVarAttributes { if (!$2->empty()) { - *O << *$2 << " = "; - Globals[*$2] = $5.clone(); + std::string Name = getUniqueName($2,$5); + *O << Name << " = "; + Globals[Name] = *$5; } - *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n'; - delete $2; delete $3; delete $4; $5.destroy(); delete $6; + *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n'; + delete $2; delete $3; delete $4; delete $6; $$ = 0; } | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes { if (!$2->empty()) { - *O << *$2 << " = "; - Globals[*$2] = $5.clone(); + std::string Name = getUniqueName($2,$5); + *O << Name << " = "; + Globals[Name] = *$5; } - *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n'; - delete $2; delete $3; delete $4; $5.destroy(); delete $6; + *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n'; + delete $2; delete $3; delete $4; delete $6; $$ = 0; } | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes { if (!$2->empty()) { - *O << *$2 << " = "; - Globals[*$2] = $5.clone(); + std::string Name = getUniqueName($2,$5); + *O << Name << " = "; + Globals[Name] = *$5; } - *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n'; - delete $2; delete $3; delete $4; $5.destroy(); delete $6; + *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n'; + delete $2; delete $3; delete $4; delete $6; $$ = 0; } | ConstPool TARGET TargetDefinition { @@ -909,9 +994,11 @@ Name : VAR_ID | STRINGCONSTANT; OptName : Name | /*empty*/ { $$ = new std::string(); }; ArgVal : Types OptName { - $$ = $1.newTy; - if (!$2->empty()) - *$$ += " " + *$2; + $$ = new std::string($1->getNewTy()); + if (!$2->empty()) { + std::string Name = getUniqueName($2, $1); + *$$ += " " + Name; + } delete $2; }; @@ -941,14 +1028,13 @@ FunctionHeaderH if (!$1->empty()) { *$1 += " "; } - *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")"; + *$1 += $2->getNewTy() + " " + *$3 + "(" + *$5 + ")"; if (!$7->empty()) { *$1 += " " + *$7; } if (!$8->empty()) { *$1 += " " + *$8; } - $2.destroy(); delete $3; delete $5; delete $7; @@ -978,6 +1064,7 @@ Function : FunctionHeader BasicBlockList END { if ($2) *O << *$2; *O << *$3 << "\n\n"; + delete $1; delete $2; delete $3; $$ = 0; }; @@ -1029,14 +1116,12 @@ ValueRef : SymbolicValueRef { $$.val = $1; $$.constant = false; - $$.type.newTy = 0; - $$.type.oldTy = UnresolvedTy; + $$.type = new TypeInfo(); } | ConstValueRef { $$.val = $1; $$.constant = true; - $$.type.newTy = 0; - $$.type.oldTy = UnresolvedTy; + $$.type = new TypeInfo(); } ; @@ -1044,9 +1129,12 @@ ValueRef // type immediately preceeds the value reference, and allows complex constant // pool references (for things like: 'ret [2 x int] [ int 12, int 42]') ResolvedVal : Types ValueRef { + std::string Name = getUniqueName($2.val, $1); $$ = $2; + delete $$.val; + delete $$.type; + $$.val = new std::string($1->getNewTy() + " " + Name); $$.type = $1; - $$.val->insert(0, *$1.newTy + " "); }; BasicBlockList : BasicBlockList BasicBlock { @@ -1086,42 +1174,48 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... $$ = 0; } | RET VOID { // Return with no result... - *O << " " << *$1 << ' ' << *$2.newTy << '\n'; - delete $1; $2.destroy(); + *O << " " << *$1 << ' ' << $2->getNewTy() << '\n'; + delete $1; delete $2; $$ = 0; } | BR LABEL ValueRef { // Unconditional Branch... - *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << '\n'; - delete $1; $2.destroy(); $3.destroy(); + *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << *$3.val << '\n'; + delete $1; delete $2; $3.destroy(); $$ = 0; } // Conditional Branch... | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef { - *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", " - << *$5.newTy << ' ' << *$6.val << ", " << *$8.newTy << ' ' + std::string Name = getUniqueName($3.val, $2); + *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", " + << $5->getNewTy() << ' ' << *$6.val << ", " << $8->getNewTy() << ' ' << *$9.val << '\n'; - delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy(); - $8.destroy(); $9.destroy(); + delete $1; delete $2; $3.destroy(); delete $5; $6.destroy(); + delete $8; $9.destroy(); $$ = 0; } | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' { - *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", " - << *$5.newTy << ' ' << *$6.val << " [" << *$8 << " ]\n"; - delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy(); + std::string Name = getUniqueName($3.val, $2); + *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", " + << $5->getNewTy() << ' ' << *$6.val << " [" << *$8 << " ]\n"; + delete $1; delete $2; $3.destroy(); delete $5; $6.destroy(); delete $8; $$ = 0; } | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' { - *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", " - << *$5.newTy << ' ' << *$6.val << "[]\n"; - delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy(); + std::string Name = getUniqueName($3.val, $2); + *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", " + << $5->getNewTy() << ' ' << *$6.val << "[]\n"; + delete $1; delete $2; $3.destroy(); delete $5; $6.destroy(); $$ = 0; } | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')' TO LABEL ValueRef Unwind LABEL ValueRef { + TypeInfo* ResTy = getFunctionReturnType($4); *O << " "; - if (!$1->empty()) - *O << *$1 << " = "; - *O << *$2 << ' ' << *$3 << ' ' << *$4.newTy << ' ' << *$5.val << " ("; + if (!$1->empty()) { + std::string Name = getUniqueName($1, ResTy); + *O << Name << " = "; + } + *O << *$2 << ' ' << *$3 << ' ' << $4->getNewTy() << ' ' << *$5.val << " ("; for (unsigned i = 0; i < $7->size(); ++i) { ValueInfo& VI = (*$7)[i]; *O << *VI.val; @@ -1129,10 +1223,10 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... *O << ", "; VI.destroy(); } - *O << ") " << *$9 << ' ' << *$10.newTy << ' ' << *$11.val << ' ' - << *$12 << ' ' << *$13.newTy << ' ' << *$14.val << '\n'; - delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7; - delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy(); + *O << ") " << *$9 << ' ' << $10->getNewTy() << ' ' << *$11.val << ' ' + << *$12 << ' ' << $13->getNewTy() << ' ' << *$14.val << '\n'; + delete $1; delete $2; delete $3; delete $4; $5.destroy(); delete $7; + delete $9; delete $10; $11.destroy(); delete $12; delete $13; $14.destroy(); $$ = 0; } @@ -1148,14 +1242,15 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result... }; JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef { - *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val; - $2.destroy(); delete $3; $5.destroy(); $6.destroy(); + *$1 += " " + $2->getNewTy() + " " + *$3 + ", " + $5->getNewTy() + " " + + *$6.val; + delete $2; delete $3; delete $5; $6.destroy(); $$ = $1; } | IntType ConstValueRef ',' LABEL ValueRef { - $2->insert(0, *$1.newTy + " " ); - *$2 += ", " + *$4.newTy + " " + *$5.val; - $1.destroy(); $4.destroy(); $5.destroy(); + $2->insert(0, $1->getNewTy() + " " ); + *$2 += ", " + $4->getNewTy() + " " + *$5.val; + delete $1; delete $4; $5.destroy(); $$ = $2; }; @@ -1167,38 +1262,41 @@ Inst $1->insert(0, "; "); // don't actually delete it, just comment it out delete deleteUselessCastName; } else { - *$1 += " = "; + // Get a unique name for the name of this value, based on its type. + *$1 = getUniqueName($1, $2.type) + " = "; } } - *$1 += *$2; - delete $2; + *$1 += *$2.val; + $2.destroy(); deleteUselessCastFlag = false; $$ = $1; }; PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes - $3.val->insert(0, *$1.newTy + "["); - *$3.val += "," + *$5.val + "]"; - $1.destroy(); $5.destroy(); - $$ = new std::string(*$3.val); - $3.destroy(); + std::string Name = getUniqueName($3.val, $1); + Name.insert(0, $1->getNewTy() + "["); + Name += "," + *$5.val + "]"; + $$.val = new std::string(Name); + $$.type = $1; + $3.destroy(); $5.destroy(); } | PHIList ',' '[' ValueRef ',' ValueRef ']' { - *$1 += ", [" + *$4.val + "," + *$6.val + "]"; + std::string Name = getUniqueName($4.val, $1.type); + *$1.val += ", [" + Name + "," + *$6.val + "]"; $4.destroy(); $6.destroy(); $$ = $1; }; ValueRefList - : ResolvedVal { + : ResolvedVal { $$ = new ValueList(); $$->push_back($1); } | ValueRefList ',' ResolvedVal { - $1->push_back($3); $$ = $1; + $$->push_back($3); }; // ValueRefListE - Just like ValueRefList, except that it may also be empty! @@ -1218,61 +1316,77 @@ OptTailCall InstVal : ArithmeticOps Types ValueRef ',' ValueRef { const char* op = getDivRemOpcode(*$1, $2); - $$ = new std::string(op); - *$$ += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val; - delete $1; $2.destroy(); $3.destroy(); $5.destroy(); + std::string Name1 = getUniqueName($3.val, $2); + std::string Name2 = getUniqueName($5.val, $2); + $$.val = new std::string(op); + *$$.val += " " + $2->getNewTy() + " " + Name1 + ", " + Name2; + $$.type = $2; + delete $1; $3.destroy(); $5.destroy(); } | LogicalOps Types ValueRef ',' ValueRef { - *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val; - $2.destroy(); $3.destroy(); $5.destroy(); - $$ = $1; + std::string Name1 = getUniqueName($3.val, $2); + std::string Name2 = getUniqueName($5.val, $2); + *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2; + $$.val = $1; + $$.type = $2; + $3.destroy(); $5.destroy(); } | SetCondOps Types ValueRef ',' ValueRef { + std::string Name1 = getUniqueName($3.val, $2); + std::string Name2 = getUniqueName($5.val, $2); *$1 = getCompareOp(*$1, $2); - *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val; - $2.destroy(); $3.destroy(); $5.destroy(); - $$ = $1; + *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2; + $$.val = $1; + $$.type = new TypeInfo("bool",BoolTy); + $3.destroy(); $5.destroy(); } | ICMP IPredicates Types ValueRef ',' ValueRef { - *$1 += " " + *$2 + " " + *$3.newTy + " " + *$4.val + "," + *$6.val; + std::string Name1 = getUniqueName($4.val, $3); + std::string Name2 = getUniqueName($6.val, $3); + *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2; + $$.val = $1; + $$.type = new TypeInfo("bool",BoolTy); delete $2; $4.destroy(); $6.destroy(); - $$ = $1; } | FCMP FPredicates Types ValueRef ',' ValueRef { - *$1 += " " + *$2 + " " + *$3.newTy + " " + *$4.val + "," + *$6.val; + std::string Name1 = getUniqueName($4.val, $3); + std::string Name2 = getUniqueName($6.val, $3); + *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2; + $$.val = $1; + $$.type = new TypeInfo("bool",BoolTy); delete $2; $4.destroy(); $6.destroy(); - $$ = $1; } | NOT ResolvedVal { - *$1 += " " + *$2.val; - $2.destroy(); - $$ = $1; + $$ = $2; + $$.val->insert(0, *$1 + " "); + delete $1; } | ShiftOps ResolvedVal ',' ResolvedVal { const char* shiftop = $1->c_str(); if (*$1 == "shr") - shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr"; - $$ = new std::string(shiftop); - *$$ += " " + *$2.val + ", " + *$4.val; - delete $1; $2.destroy(); $4.destroy(); + shiftop = ($2.type->isUnsigned()) ? "lshr" : "ashr"; + $$.val = new std::string(shiftop); + *$$.val += " " + *$2.val + ", " + *$4.val; + $$.type = $2.type; + delete $1; delete $2.val; $4.destroy(); } | CastOps ResolvedVal TO Types { std::string source = *$2.val; - TypeInfo SrcTy = $2.type; - TypeInfo DstTy = $4; - ResolveType(DstTy); - $$ = new std::string(); + TypeInfo* SrcTy = $2.type; + TypeInfo* DstTy = ResolveType($4); + $$.val = new std::string(); if (*$1 == "cast") { - *$$ += getCastUpgrade(source, SrcTy, DstTy, false); + *$$.val += getCastUpgrade(source, SrcTy, DstTy, false); } else { - *$$ += *$1 + " " + source + " to " + *DstTy.newTy; + *$$.val += *$1 + " " + source + " to " + DstTy->getNewTy(); } + $$.type = $4; // Check to see if this is a useless cast of a value to the same name // and the same type. Such casts will probably cause redefinition errors // when assembled and perform no code gen action so just remove them. if (*$1 == "cast" || *$1 == "bitcast") - if ($2.type.isInteger() && $4.isInteger() && - $2.type.getBitWidth() == $4.getBitWidth()) { + if ($2.type->isInteger() && DstTy->isInteger() && + $2.type->getBitWidth() == DstTy->getBitWidth()) { deleteUselessCastFlag = true; // Flag the "Inst" rule deleteUselessCastName = new std::string(*$2.val); // save the name size_t pos = deleteUselessCastName->find_first_of("%\"",0); @@ -1282,44 +1396,51 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { } } delete $1; $2.destroy(); - delete $3; $4.destroy(); + delete $3; } | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val; - $2.destroy(); $4.destroy(); $6.destroy(); - $$ = $1; + $$.val = $1; + $$.type = $4.type; + $2.destroy(); delete $4.val; $6.destroy(); } | VAARG ResolvedVal ',' Types { - *$1 += " " + *$2.val + ", " + *$4.newTy; - $2.destroy(); $4.destroy(); - $$ = $1; + *$1 += " " + *$2.val + ", " + $4->getNewTy(); + $$.val = $1; + $$.type = $4; + $2.destroy(); } | EXTRACTELEMENT ResolvedVal ',' ResolvedVal { *$1 += " " + *$2.val + ", " + *$4.val; - $2.destroy(); $4.destroy(); - $$ = $1; + $$.val = $1; + ResolveType($2.type); + $$.type = $2.type->getElementType()->clone(); + delete $2.val; $4.destroy(); } | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal { *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val; - $2.destroy(); $4.destroy(); $6.destroy(); - $$ = $1; + $$.val = $1; + $$.type = $2.type; + delete $2.val; $4.destroy(); $6.destroy(); } | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal { *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val; - $2.destroy(); $4.destroy(); $6.destroy(); - $$ = $1; + $$.val = $1; + $$.type = $2.type; + delete $2.val; $4.destroy(); $6.destroy(); } | PHI_TOK PHIList { - *$1 += " " + *$2; - delete $2; - $$ = $1; + *$1 += " " + *$2.val; + $$.val = $1; + $$.type = $2.type; + delete $2.val; } | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' { if (!$2->empty()) *$1 += " " + *$2; if (!$1->empty()) *$1 += " "; - *$1 += *$3.newTy + " " + *$4.val + "("; + *$1 += $3->getNewTy() + " " + *$4.val + "("; for (unsigned i = 0; i < $6->size(); ++i) { ValueInfo& VI = (*$6)[i]; *$1 += *VI.val; @@ -1328,8 +1449,9 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef { VI.destroy(); } *$1 += ")"; - delete $2; $3.destroy(); $4.destroy(); delete $6; - $$ = $1; + $$.val = $1; + $$.type = getFunctionReturnType($3); + delete $2; delete $3; $4.destroy(); delete $6; } | MemoryInst ; @@ -1346,74 +1468,85 @@ OptVolatile ; MemoryInst : MALLOC Types OptCAlign { - *$1 += " " + *$2.newTy; + *$1 += " " + $2->getNewTy(); if (!$3->empty()) *$1 += " " + *$3; - $2.destroy(); delete $3; - $$ = $1; + $$.val = $1; + $$.type = $2->getPointerType(); + delete $2; delete $3; } | MALLOC Types ',' UINT ValueRef OptCAlign { - *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val; + std::string Name = getUniqueName($5.val, $4); + *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name; if (!$6->empty()) *$1 += " " + *$6; - $2.destroy(); $4.destroy(); $5.destroy(); delete $6; - $$ = $1; + $$.val = $1; + $$.type = $2->getPointerType(); + delete $2; delete $4; $5.destroy(); delete $6; } | ALLOCA Types OptCAlign { - *$1 += " " + *$2.newTy; + *$1 += " " + $2->getNewTy(); if (!$3->empty()) *$1 += " " + *$3; - $2.destroy(); delete $3; - $$ = $1; + $$.val = $1; + $$.type = $2->getPointerType(); + delete $2; delete $3; } | ALLOCA Types ',' UINT ValueRef OptCAlign { - *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val; + std::string Name = getUniqueName($5.val, $4); + *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name; if (!$6->empty()) *$1 += " " + *$6; - $2.destroy(); $4.destroy(); $5.destroy(); delete $6; - $$ = $1; + $$.val = $1; + $$.type = $2->getPointerType(); + delete $2; delete $4; $5.destroy(); delete $6; } | FREE ResolvedVal { *$1 += " " + *$2.val; + $$.val = $1; + $$.type = new TypeInfo("void", VoidTy); $2.destroy(); - $$ = $1; } | OptVolatile LOAD Types ValueRef { + std::string Name = getUniqueName($4.val, $3); if (!$1->empty()) *$1 += " "; - *$1 += *$2 + " " + *$3.newTy + " " + *$4.val; - delete $2; $3.destroy(); $4.destroy(); - $$ = $1; + *$1 += *$2 + " " + $3->getNewTy() + " " + Name; + $$.val = $1; + $$.type = $3->getElementType()->clone(); + delete $2; delete $3; $4.destroy(); } | OptVolatile STORE ResolvedVal ',' Types ValueRef { + std::string Name = getUniqueName($6.val, $5); if (!$1->empty()) *$1 += " "; - *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val; - delete $2; $3.destroy(); $5.destroy(); $6.destroy(); - $$ = $1; + *$1 += *$2 + " " + *$3.val + ", " + $5->getNewTy() + " " + Name; + $$.val = $1; + $$.type = new TypeInfo("void", VoidTy); + delete $2; $3.destroy(); delete $5; $6.destroy(); } | GETELEMENTPTR Types ValueRef IndexList { + std::string Name = getUniqueName($3.val, $2); // Upgrade the indices for (unsigned i = 0; i < $4->size(); ++i) { ValueInfo& VI = (*$4)[i]; - if (VI.type.isUnsigned() && !VI.isConstant() && - VI.type.getBitWidth() < 64) { + if (VI.type->isUnsigned() && !VI.isConstant() && + VI.type->getBitWidth() < 64) { std::string* old = VI.val; *O << " %gep_upgrade" << unique << " = zext " << *old << " to i64\n"; VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++)); - VI.type.oldTy = ULongTy; - delete old; + VI.type->setOldTy(ULongTy); } } - *$1 += " " + *$2.newTy + " " + *$3.val; + *$1 += " " + $2->getNewTy() + " " + Name; for (unsigned i = 0; i < $4->size(); ++i) { ValueInfo& VI = (*$4)[i]; *$1 += ", " + *VI.val; - VI.destroy(); } - $2.destroy(); $3.destroy(); delete $4; - $$ = $1; + $$.val = $1; + $$.type = getGEPIndexedType($2,$4); + $3.destroy(); delete $4; }; %% |