X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-upgrade%2FUpgradeParser.y.cvs;h=211934f368a0978a3d9c2bc770413af58da904fd;hb=4424757d3e38eaa646cd5c8dab19b8b24ee49416;hp=14183a40cbc2953e37b5dd6d142042a4f6451daf;hpb=d7c4f8ceff83ff0c5b4dd758c82e0896a7868b69;p=oota-llvm.git diff --git a/tools/llvm-upgrade/UpgradeParser.y.cvs b/tools/llvm-upgrade/UpgradeParser.y.cvs index 14183a40cbc..211934f368a 100644 --- a/tools/llvm-upgrade/UpgradeParser.y.cvs +++ b/tools/llvm-upgrade/UpgradeParser.y.cvs @@ -17,12 +17,14 @@ #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.h" -#include "llvm/SymbolTable.h" +#include "llvm/ParameterAttributes.h" +#include "llvm/ValueSymbolTable.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/MathExtras.h" #include #include +#include #include #include @@ -60,13 +62,14 @@ static bool ObsoleteVarArgs; static bool NewVarArgs; static BasicBlock *CurBB; static GlobalVariable *CurGV; +static unsigned lastCallingConv; // This contains info used when building the body of a function. It is // destroyed when the function is completed. // typedef std::vector ValueList; // Numbered defs -typedef std::pair RenameMapKey; +typedef std::pair RenameMapKey; typedef std::map RenameMapType; static void @@ -77,7 +80,10 @@ static struct PerModuleInfo { Module *CurrentModule; std::map Values; // Module level numbered definitions std::map LateResolveValues; - std::vector Types; + std::vector Types; + std::vector TypeSigns; + std::map NamedTypeSigns; + std::map NamedValueSigns; std::map LateResolveTypes; static Module::Endianness Endian; static Module::PointerSize PointerSize; @@ -134,6 +140,9 @@ static struct PerModuleInfo { Values.clear(); // Clear out function local definitions Types.clear(); + TypeSigns.clear(); + NamedTypeSigns.clear(); + NamedValueSigns.clear(); CurrentModule = 0; } @@ -207,6 +216,24 @@ static struct PerFunctionInfo { static bool inFunctionScope() { return CurFun.CurrentFunction != 0; } +/// This function is just a utility to make a Key value for the rename map. +/// The Key is a combination of the name, type, Signedness of the original +/// value (global/function). This just constructs the key and ensures that +/// named Signedness values are resolved to the actual Signedness. +/// @brief Make a key for the RenameMaps +static RenameMapKey makeRenameMapKey(const std::string &Name, const Type* Ty, + const Signedness &Sign) { + TypeInfo TI; + TI.T = Ty; + if (Sign.isNamed()) + // Don't allow Named Signedness nodes because they won't match. The actual + // Signedness must be looked up in the NamedTypeSigns map. + TI.S.copy(CurModule.NamedTypeSigns[Sign.getName()]); + else + TI.S.copy(Sign); + return std::make_pair(Name, TI); +} + //===----------------------------------------------------------------------===// // Code to handle definitions of all the types @@ -232,7 +259,6 @@ static const Type *getType(const ValID &D, bool DoNotImprovise = false) { break; case ValID::NameVal: // Is it a named definition? if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) { - D.destroy(); // Free old strdup'd memory... return N; } break; @@ -247,7 +273,6 @@ static const Type *getType(const ValID &D, bool DoNotImprovise = false) { // if (DoNotImprovise) return 0; // Do we just want a null to be returned? - if (inFunctionScope()) { if (D.Type == ValID::NameVal) { error("Reference to an undefined type: '" + D.getName() + "'"); @@ -265,7 +290,160 @@ static const Type *getType(const ValID &D, bool DoNotImprovise = false) { Type *Typ = OpaqueType::get(); CurModule.LateResolveTypes.insert(std::make_pair(D, Typ)); return Typ; - } +} + +/// This is like the getType method except that instead of looking up the type +/// for a given ID, it looks up that type's sign. +/// @brief Get the signedness of a referenced type +static Signedness getTypeSign(const ValID &D) { + switch (D.Type) { + case ValID::NumberVal: // Is it a numbered definition? + // Module constants occupy the lowest numbered slots... + if ((unsigned)D.Num < CurModule.TypeSigns.size()) { + return CurModule.TypeSigns[(unsigned)D.Num]; + } + break; + case ValID::NameVal: { // Is it a named definition? + std::map::const_iterator I = + CurModule.NamedTypeSigns.find(D.Name); + if (I != CurModule.NamedTypeSigns.end()) + return I->second; + // Perhaps its a named forward .. just cache the name + Signedness S; + S.makeNamed(D.Name); + return S; + } + default: + break; + } + // If we don't find it, its signless + Signedness S; + S.makeSignless(); + return S; +} + +/// This function is analagous to getElementType in LLVM. It provides the same +/// function except that it looks up the Signedness instead of the type. This is +/// used when processing GEP instructions that need to extract the type of an +/// indexed struct/array/ptr member. +/// @brief Look up an element's sign. +static Signedness getElementSign(const ValueInfo& VI, + const std::vector &Indices) { + const Type *Ptr = VI.V->getType(); + assert(isa(Ptr) && "Need pointer type"); + + unsigned CurIdx = 0; + Signedness S(VI.S); + while (const CompositeType *CT = dyn_cast(Ptr)) { + if (CurIdx == Indices.size()) + break; + + Value *Index = Indices[CurIdx++]; + assert(!isa(CT) || CurIdx == 1 && "Invalid type"); + Ptr = CT->getTypeAtIndex(Index); + if (const Type* Ty = Ptr->getForwardedType()) + Ptr = Ty; + assert(S.isComposite() && "Bad Signedness type"); + if (isa(CT)) { + S = S.get(cast(Index)->getZExtValue()); + } else { + S = S.get(0UL); + } + if (S.isNamed()) + S = CurModule.NamedTypeSigns[S.getName()]; + } + Signedness Result; + Result.makeComposite(S); + return Result; +} + +/// This function just translates a ConstantInfo into a ValueInfo and calls +/// getElementSign(ValueInfo,...). Its just a convenience. +/// @brief ConstantInfo version of getElementSign. +static Signedness getElementSign(const ConstInfo& CI, + const std::vector &Indices) { + ValueInfo VI; + VI.V = CI.C; + VI.S.copy(CI.S); + std::vector Idx; + for (unsigned i = 0; i < Indices.size(); ++i) + Idx.push_back(Indices[i]); + Signedness result = getElementSign(VI, Idx); + VI.destroy(); + return result; +} + +/// This function determines if two function types differ only in their use of +/// the sret parameter attribute in the first argument. If they are identical +/// in all other respects, it returns true. Otherwise, it returns false. +static bool FuncTysDifferOnlyBySRet(const FunctionType *F1, + const FunctionType *F2) { + if (F1->getReturnType() != F2->getReturnType() || + F1->getNumParams() != F2->getNumParams()) + return false; + const ParamAttrsList *PAL1 = F1->getParamAttrs(); + const ParamAttrsList *PAL2 = F2->getParamAttrs(); + if (PAL1 && !PAL2 || PAL2 && !PAL1) + return false; + if (PAL1 && PAL2 && ((PAL1->size() != PAL2->size()) || + (PAL1->getParamAttrs(0) != PAL2->getParamAttrs(0)))) + return false; + unsigned SRetMask = ~unsigned(ParamAttr::StructRet); + for (unsigned i = 0; i < F1->getNumParams(); ++i) { + if (F1->getParamType(i) != F2->getParamType(i) || (PAL1 && PAL2 && + (unsigned(PAL1->getParamAttrs(i+1)) & SRetMask != + unsigned(PAL2->getParamAttrs(i+1)) & SRetMask))) + return false; + } + return true; +} + +/// This function determines if the type of V and Ty differ only by the SRet +/// parameter attribute. This is a more generalized case of +/// FuncTysDIfferOnlyBySRet since it doesn't require FunctionType arguments. +static bool TypesDifferOnlyBySRet(Value *V, const Type* Ty) { + if (V->getType() == Ty) + return true; + const PointerType *PF1 = dyn_cast(Ty); + const PointerType *PF2 = dyn_cast(V->getType()); + if (PF1 && PF2) { + const FunctionType* FT1 = dyn_cast(PF1->getElementType()); + const FunctionType* FT2 = dyn_cast(PF2->getElementType()); + if (FT1 && FT2) + return FuncTysDifferOnlyBySRet(FT1, FT2); + } + return false; +} + +// The upgrade of csretcc to sret param attribute may have caused a function +// to not be found because the param attribute changed the type of the called +// function. This helper function, used in getExistingValue, detects that +// situation and bitcasts the function to the correct type. +static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) { + // Handle degenerate cases + if (!V) + return 0; + if (V->getType() == Ty) + return V; + + const PointerType *PF1 = dyn_cast(Ty); + const PointerType *PF2 = dyn_cast(V->getType()); + if (PF1 && PF2) { + const FunctionType *FT1 = dyn_cast(PF1->getElementType()); + const FunctionType *FT2 = dyn_cast(PF2->getElementType()); + if (FT1 && FT2 && FuncTysDifferOnlyBySRet(FT1, FT2)) { + const ParamAttrsList *PAL2 = FT2->getParamAttrs(); + if (PAL2 && PAL2->paramHasAttr(1, ParamAttr::StructRet)) + return V; + else if (Constant *C = dyn_cast(V)) + return ConstantExpr::getBitCast(C, PF1); + else + return new BitCastInst(V, PF1, "upgrd.cast", CurBB); + } + + } + return 0; +} // getExistingValue - Look up the value specified by the provided type and // the provided ValID. If the value exists and has already been defined, return @@ -300,9 +478,8 @@ static Value *getExistingValue(const Type *Ty, const ValID &D) { case ValID::NameVal: { // Is it a named definition? // Get the name out of the ID - std::string Name(D.Name); - Value* V = 0; - RenameMapKey Key = std::make_pair(Name, Ty); + RenameMapKey Key = makeRenameMapKey(D.Name, Ty, D.S); + Value *V = 0; if (inFunctionScope()) { // See if the name was renamed RenameMapType::const_iterator I = CurFun.RenameMap.find(Key); @@ -310,9 +487,12 @@ static Value *getExistingValue(const Type *Ty, const ValID &D) { if (I != CurFun.RenameMap.end()) LookupName = I->second; else - LookupName = Name; - SymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable(); - V = SymTab.lookup(Ty, LookupName); + LookupName = D.Name; + ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable(); + V = SymTab.lookup(LookupName); + if (V && V->getType() != Ty) + V = handleSRetFuncTypeMerge(V, Ty); + assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type"); } if (!V) { RenameMapType::const_iterator I = CurModule.RenameMap.find(Key); @@ -320,10 +500,13 @@ static Value *getExistingValue(const Type *Ty, const ValID &D) { if (I != CurModule.RenameMap.end()) LookupName = I->second; else - LookupName = Name; - V = CurModule.CurrentModule->getValueSymbolTable().lookup(Ty, LookupName); + LookupName = D.Name; + V = CurModule.CurrentModule->getValueSymbolTable().lookup(LookupName); + if (V && V->getType() != Ty) + V = handleSRetFuncTypeMerge(V, Ty); + assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type"); } - if (V == 0) + if (!V) return 0; D.destroy(); // Free old strdup'd memory... @@ -350,9 +533,13 @@ static Value *getExistingValue(const Type *Ty, const ValID &D) { return ConstantInt::get(Ty, D.UConstPool64); case ValID::ConstFPVal: // Is it a floating point const pool reference? - if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP)) + if (!ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) error("FP constant invalid for type"); - return ConstantFP::get(Ty, D.ConstPoolFP); + // Lexer has no type info, so builds all FP constants as double. + // Fix this here. + if (Ty==Type::FloatTy) + D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); + return ConstantFP::get(Ty, *D.ConstPoolFP); case ValID::ConstNullVal: // Is it a null value? if (!isa(Ty)) @@ -415,7 +602,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) { // Remember where this forward reference came from. FIXME, shouldn't we try // to recycle these things?? CurModule.PlaceHolderInfo.insert( - std::make_pair(V, std::make_pair(ID, Upgradelineno-1))); + std::make_pair(V, std::make_pair(ID, Upgradelineno))); if (inFunctionScope()) InsertValue(V, CurFun.LateResolveValues); @@ -424,6 +611,14 @@ static Value *getVal(const Type *Ty, const ValID &ID) { return V; } +/// @brief This just makes any name given to it unique, up to MAX_UINT times. +static std::string makeNameUnique(const std::string& Name) { + static unsigned UniqueNameCounter = 1; + std::string Result(Name); + Result += ".upgrd." + llvm::utostr(UniqueNameCounter++); + return Result; +} + /// getBBVal - This is used for two purposes: /// * If isDefinition is true, a new basic block with the specified ID is being /// defined. @@ -446,11 +641,19 @@ static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) { break; case ValID::NameVal: // Is it a named definition? Name = ID.Name; - if (Value *N = CurFun.CurrentFunction-> - getValueSymbolTable().lookup(Type::LabelTy, Name)) { - if (N->getType() != Type::LabelTy) - error("Name '" + Name + "' does not refer to a BasicBlock"); - BB = cast(N); + if (Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name)) { + if (N->getType() != Type::LabelTy) { + // Register names didn't use to conflict with basic block names + // because of type planes. Now they all have to be unique. So, we just + // rename the register and treat this name as if no basic block + // had been found. + RenameMapKey Key = makeRenameMapKey(ID.Name, N->getType(), ID.S); + N->setName(makeNameUnique(N->getName())); + CurModule.RenameMap[Key] = N->getName(); + BB = 0; + } else { + BB = cast(N); + } } break; } @@ -511,9 +714,11 @@ static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) { static void ResolveDefinitions(std::map &LateResolvers, std::map *FutureLateResolvers) { + // Loop over LateResolveDefs fixing up stuff that couldn't be resolved for (std::map::iterator LRI = LateResolvers.begin(), E = LateResolvers.end(); LRI != E; ++LRI) { + const Type* Ty = LRI->first; ValueList &List = LRI->second; while (!List.empty()) { Value *V = List.back(); @@ -525,7 +730,7 @@ ResolveDefinitions(std::map &LateResolvers, ValID &DID = PHI->second.first; - Value *TheRealValue = getExistingValue(LRI->first, DID); + Value *TheRealValue = getExistingValue(Ty, DID); if (TheRealValue) { V->replaceAllUsesWith(TheRealValue); delete V; @@ -536,10 +741,10 @@ ResolveDefinitions(std::map &LateResolvers, InsertValue(V, *FutureLateResolvers); } else { if (DID.Type == ValID::NameVal) { - error("Reference to an invalid definition: '" +DID.getName()+ + error("Reference to an invalid definition: '" + DID.getName() + "' of type '" + V->getType()->getDescription() + "'", PHI->second.second); - return; + return; } else { error("Reference to an invalid definition: #" + itostr(DID.Num) + " of type '" + @@ -553,40 +758,99 @@ ResolveDefinitions(std::map &LateResolvers, LateResolvers.clear(); } -// ResolveTypeTo - A brand new type was just declared. This means that (if -// name is not null) things referencing Name can be resolved. Otherwise, things -// refering to the number can be resolved. Do this now. -// -static void ResolveTypeTo(char *Name, const Type *ToTy) { +/// This function is used for type resolution and upref handling. When a type +/// becomes concrete, this function is called to adjust the signedness for the +/// concrete type. +static void ResolveTypeSign(const Type* oldTy, const Signedness &Sign) { + std::string TyName = CurModule.CurrentModule->getTypeName(oldTy); + if (!TyName.empty()) + CurModule.NamedTypeSigns[TyName] = Sign; +} + +/// ResolveTypeTo - A brand new type was just declared. This means that (if +/// name is not null) things referencing Name can be resolved. Otherwise, +/// things refering to the number can be resolved. Do this now. +static void ResolveTypeTo(char *Name, const Type *ToTy, const Signedness& Sign){ ValID D; - if (Name) D = ValID::create(Name); - else D = ValID::create((int)CurModule.Types.size()); + if (Name) + D = ValID::create(Name); + else + D = ValID::create((int)CurModule.Types.size()); + D.S.copy(Sign); + + if (Name) + CurModule.NamedTypeSigns[Name] = Sign; std::map::iterator I = CurModule.LateResolveTypes.find(D); if (I != CurModule.LateResolveTypes.end()) { - ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); + const Type *OldTy = I->second.get(); + ((DerivedType*)OldTy)->refineAbstractTypeTo(ToTy); CurModule.LateResolveTypes.erase(I); } } -static std::string makeNameUnique(const std::string& Name) { - static unsigned UniqueNameCounter = 1; - std::string Result(Name); - Result += ".upgrd." + llvm::utostr(UniqueNameCounter++); - return Result; +/// This is the implementation portion of TypeHasInteger. It traverses the +/// type given, avoiding recursive types, and returns true as soon as it finds +/// an integer type. If no integer type is found, it returns false. +static bool TypeHasIntegerI(const Type *Ty, std::vector Stack) { + // Handle some easy cases + if (Ty->isPrimitiveType() || (Ty->getTypeID() == Type::OpaqueTyID)) + return false; + if (Ty->isInteger()) + return true; + if (const SequentialType *STy = dyn_cast(Ty)) + return STy->getElementType()->isInteger(); + + // Avoid type structure recursion + for (std::vector::iterator I = Stack.begin(), E = Stack.end(); + I != E; ++I) + if (Ty == *I) + return false; + + // Push us on the type stack + Stack.push_back(Ty); + + if (const FunctionType *FTy = dyn_cast(Ty)) { + if (TypeHasIntegerI(FTy->getReturnType(), Stack)) + return true; + FunctionType::param_iterator I = FTy->param_begin(); + FunctionType::param_iterator E = FTy->param_end(); + for (; I != E; ++I) + if (TypeHasIntegerI(*I, Stack)) + return true; + return false; + } else if (const StructType *STy = dyn_cast(Ty)) { + StructType::element_iterator I = STy->element_begin(); + StructType::element_iterator E = STy->element_end(); + for (; I != E; ++I) { + if (TypeHasIntegerI(*I, Stack)) + return true; + } + return false; + } + // There shouldn't be anything else, but its definitely not integer + assert(0 && "What type is this?"); + return false; +} + +/// This is the interface to TypeHasIntegerI. It just provides the type stack, +/// to avoid recursion, and then calls TypeHasIntegerI. +static inline bool TypeHasInteger(const Type *Ty) { + std::vector TyStack; + return TypeHasIntegerI(Ty, TyStack); } // setValueName - Set the specified value to the name given. The name may be // null potentially, in which case this is a noop. The string passed in is // assumed to be a malloc'd string buffer, and is free'd by this function. // -static void setValueName(Value *V, char *NameStr) { +static void setValueName(const ValueInfo &V, char *NameStr) { if (NameStr) { std::string Name(NameStr); // Copy string free(NameStr); // Free old string - if (V->getType() == Type::VoidTy) { + if (V.V->getType() == Type::VoidTy) { error("Can't assign name '" + Name + "' to value with void type"); return; } @@ -594,27 +858,19 @@ static void setValueName(Value *V, char *NameStr) { assert(inFunctionScope() && "Must be in function scope"); // Search the function's symbol table for an existing value of this name - Value* Existing = 0; - SymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable(); - SymbolTable::plane_const_iterator PI = ST.plane_begin(), PE =ST.plane_end(); - for ( ; PI != PE; ++PI) { - SymbolTable::value_const_iterator VI = PI->second.find(Name); - if (VI != PI->second.end()) { - Existing = VI->second; - break; - } - } + ValueSymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable(); + Value* Existing = ST.lookup(Name); if (Existing) { - if (Existing->getType() == V->getType()) { - // The type of the Existing value and the new one are the same. This - // is probably a type plane collapsing error. If the types involved - // are both integer, just rename it. Otherwise it - // is a redefinition error. - if (!Existing->getType()->isInteger()) { - error("Redefinition of value named '" + Name + "' in the '" + - V->getType()->getDescription() + "' type plane"); - return; - } + // An existing value of the same name was found. This might have happened + // because of the integer type planes collapsing in LLVM 2.0. + if (Existing->getType() == V.V->getType() && + !TypeHasInteger(Existing->getType())) { + // If the type does not contain any integers in them then this can't be + // a type plane collapsing issue. It truly is a redefinition and we + // should error out as the assembly is invalid. + error("Redefinition of value named '" + Name + "' of type '" + + V.V->getType()->getDescription() + "'"); + return; } // In LLVM 2.0 we don't allow names to be re-used for any values in a // function, regardless of Type. Previously re-use of names was okay as @@ -627,13 +883,13 @@ static void setValueName(Value *V, char *NameStr) { // We're changing the name but it will probably be used by other // instructions as operands later on. Consequently we have to retain // a mapping of the renaming that we're doing. - RenameMapKey Key = std::make_pair(Name,V->getType()); + RenameMapKey Key = makeRenameMapKey(Name, V.V->getType(), V.S); CurFun.RenameMap[Key] = NewName; Name = NewName; } // Set the name. - V->setName(Name); + V.V->setName(Name); } } @@ -642,7 +898,8 @@ static void setValueName(Value *V, char *NameStr) { static GlobalVariable * ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, bool isConstantGlobal, const Type *Ty, - Constant *Initializer) { + Constant *Initializer, + const Signedness &Sign) { if (isa(Ty)) error("Cannot declare global vars of function type"); @@ -662,6 +919,7 @@ ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, } else { ID = ValID::create((int)CurModule.Values[PTy].size()); } + ID.S.makeComposite(Sign); if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) { // Move the global to the end of the list, from whereever it was @@ -680,20 +938,15 @@ ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, // of this global in the module and emit warnings if there are conflicts. if (!Name.empty()) { // The global has a name. See if there's an existing one of the same name. - if (CurModule.CurrentModule->getNamedGlobal(Name)) { - // We found an existing global ov the same name. This isn't allowed + if (CurModule.CurrentModule->getNamedGlobal(Name) || + CurModule.CurrentModule->getFunction(Name)) { + // We found an existing global of the same name. This isn't allowed // in LLVM 2.0. Consequently, we must alter the name of the global so it // can at least compile. This can happen because of type planes // There is alread a global of the same name which means there is a // conflict. Let's see what we can do about it. std::string NewName(makeNameUnique(Name)); - if (Linkage == GlobalValue::InternalLinkage) { - // The linkage type is internal so just warn about the rename without - // invoking "scarey language" about linkage failures. GVars with - // InternalLinkage can be renamed at will. - warning("Global variable '" + Name + "' was renamed to '"+ - NewName + "'"); - } else { + if (Linkage != GlobalValue::InternalLinkage) { // The linkage of this gval is external so we can't reliably rename // it because it could potentially create a linking problem. // However, we can't leave the name conflict in the output either or @@ -704,7 +957,7 @@ ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, } // Put the renaming in the global rename map - RenameMapKey Key = std::make_pair(Name,PointerType::get(Ty)); + RenameMapKey Key = makeRenameMapKey(Name, PointerType::get(Ty), ID.S); CurModule.RenameMap[Key] = NewName; // Rename it @@ -717,6 +970,8 @@ ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, CurModule.CurrentModule); InsertValue(GV, CurModule.Values); + // Remember the sign of this global. + CurModule.NamedValueSigns[Name] = ID.S; return GV; } @@ -727,21 +982,26 @@ ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, // This function returns true if the type has already been defined, but is // allowed to be redefined in the specified context. If the name is a new name // for the type plane, it is inserted and false is returned. -static bool setTypeName(const Type *T, char *NameStr) { +static bool setTypeName(const PATypeInfo& TI, char *NameStr) { assert(!inFunctionScope() && "Can't give types function-local names"); if (NameStr == 0) return false; std::string Name(NameStr); // Copy string free(NameStr); // Free old string + const Type* Ty = TI.PAT->get(); + // We don't allow assigning names to void type - if (T == Type::VoidTy) { + if (Ty == Type::VoidTy) { error("Can't assign name '" + Name + "' to the void type"); return false; } // Set the type name, checking for conflicts as we do so. - bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, T); + bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, Ty); + + // Save the sign information for later use + CurModule.NamedTypeSigns[Name] = TI.S; if (AlreadyExists) { // Inserting a name that is already defined??? const Type *Existing = CurModule.CurrentModule->getTypeByName(Name); @@ -751,7 +1011,7 @@ static bool setTypeName(const Type *T, char *NameStr) { // opaque type. In this case, Existing will be an opaque type. if (const OpaqueType *OpTy = dyn_cast(Existing)) { // We ARE replacing an opaque type! - const_cast(OpTy)->refineAbstractTypeTo(T); + const_cast(OpTy)->refineAbstractTypeTo(Ty); return true; } @@ -759,11 +1019,11 @@ static bool setTypeName(const Type *T, char *NameStr) { // the redefinition is identical to the original. This will be so if // Existing and T point to the same Type object. In this one case we // allow the equivalent redefinition. - if (Existing == T) return true; // Yes, it's equal. + if (Existing == Ty) return true; // Yes, it's equal. // Any other kind of (non-equivalent) redefinition is an error. error("Redefinition of type named '" + Name + "' in the '" + - T->getDescription() + "' type plane"); + Ty->getDescription() + "' type plane"); } return false; @@ -795,7 +1055,7 @@ namespace { OpaqueType *UpRefTy; UpRefRecord(unsigned NL, OpaqueType *URTy) - : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) {} + : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) { } }; } @@ -809,7 +1069,7 @@ static std::vector UpRefs; /// count reaches zero, the upreferenced type is the type that is passed in: /// thus we can complete the cycle. /// -static PATypeHolder HandleUpRefs(const Type *ty) { +static PATypeHolder HandleUpRefs(const Type *ty, const Signedness& Sign) { // If Ty isn't abstract, or if there are no up-references in it, then there is // nothing to resolve here. if (!ty->isAbstract() || UpRefs.empty()) return ty; @@ -825,10 +1085,11 @@ static PATypeHolder HandleUpRefs(const Type *ty) { // this variable. OpaqueType *TypeToResolve = 0; - for (unsigned i = 0; i != UpRefs.size(); ++i) { + unsigned i = 0; + for (; i != UpRefs.size(); ++i) { UR_OUT(" UR#" << i << " - TypeContains(" << Ty->getDescription() << ", " - << UpRefs[i].second->getDescription() << ") = " - << (TypeContains(Ty, UpRefs[i].second) ? "true" : "false") << "\n"); + << UpRefs[i].UpRefTy->getDescription() << ") = " + << (TypeContains(Ty, UpRefs[i].UpRefTy) ? "true" : "false") << "\n"); if (TypeContains(Ty, UpRefs[i].LastContainedTy)) { // Decrement level of upreference unsigned Level = --UpRefs[i].NestingLevel; @@ -839,8 +1100,9 @@ static PATypeHolder HandleUpRefs(const Type *ty) { TypeToResolve = UpRefs[i].UpRefTy; } else { UR_OUT(" * Resolving upreference for " - << UpRefs[i].second->getDescription() << "\n"; - std::string OldName = UpRefs[i].UpRefTy->getDescription()); + << UpRefs[i].UpRefTy->getDescription() << "\n"; + std::string OldName = UpRefs[i].UpRefTy->getDescription()); + ResolveTypeSign(UpRefs[i].UpRefTy, Sign); UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve); UR_OUT(" * Type '" << OldName << "' refined upreference to: " << (const void*)Ty << ", " << Ty->getDescription() << "\n"); @@ -853,14 +1115,115 @@ static PATypeHolder HandleUpRefs(const Type *ty) { if (TypeToResolve) { UR_OUT(" * Resolving upreference for " - << UpRefs[i].second->getDescription() << "\n"; + << UpRefs[i].UpRefTy->getDescription() << "\n"; std::string OldName = TypeToResolve->getDescription()); + ResolveTypeSign(TypeToResolve, Sign); TypeToResolve->refineAbstractTypeTo(Ty); } return Ty; } +bool Signedness::operator<(const Signedness &that) const { + if (isNamed()) { + if (that.isNamed()) + return *(this->name) < *(that.name); + else + return CurModule.NamedTypeSigns[*name] < that; + } else if (that.isNamed()) { + return *this < CurModule.NamedTypeSigns[*that.name]; + } + + if (isComposite() && that.isComposite()) { + if (sv->size() == that.sv->size()) { + SignVector::const_iterator thisI = sv->begin(), thisE = sv->end(); + SignVector::const_iterator thatI = that.sv->begin(), + thatE = that.sv->end(); + for (; thisI != thisE; ++thisI, ++thatI) { + if (*thisI < *thatI) + return true; + else if (!(*thisI == *thatI)) + return false; + } + return false; + } + return sv->size() < that.sv->size(); + } + return kind < that.kind; +} + +bool Signedness::operator==(const Signedness &that) const { + if (isNamed()) + if (that.isNamed()) + return *(this->name) == *(that.name); + else + return CurModule.NamedTypeSigns[*(this->name)] == that; + else if (that.isNamed()) + return *this == CurModule.NamedTypeSigns[*(that.name)]; + if (isComposite() && that.isComposite()) { + if (sv->size() == that.sv->size()) { + SignVector::const_iterator thisI = sv->begin(), thisE = sv->end(); + SignVector::const_iterator thatI = that.sv->begin(), + thatE = that.sv->end(); + for (; thisI != thisE; ++thisI, ++thatI) { + if (!(*thisI == *thatI)) + return false; + } + return true; + } + return false; + } + return kind == that.kind; +} + +void Signedness::copy(const Signedness &that) { + if (that.isNamed()) { + kind = Named; + name = new std::string(*that.name); + } else if (that.isComposite()) { + kind = Composite; + sv = new SignVector(); + *sv = *that.sv; + } else { + kind = that.kind; + sv = 0; + } +} + +void Signedness::destroy() { + if (isNamed()) { + delete name; + } else if (isComposite()) { + delete sv; + } +} + +#ifndef NDEBUG +void Signedness::dump() const { + if (isComposite()) { + if (sv->size() == 1) { + (*sv)[0].dump(); + std::cerr << "*"; + } else { + std::cerr << "{ " ; + for (unsigned i = 0; i < sv->size(); ++i) { + if (i != 0) + std::cerr << ", "; + (*sv)[i].dump(); + } + std::cerr << "} " ; + } + } else if (isNamed()) { + std::cerr << *name; + } else if (isSigned()) { + std::cerr << "S"; + } else if (isUnsigned()) { + std::cerr << "U"; + } else + std::cerr << "."; +} +#endif + static inline Instruction::TermOps getTermOp(TermOps op) { switch (op) { @@ -875,7 +1238,7 @@ getTermOp(TermOps op) { } static inline Instruction::BinaryOps -getBinaryOp(BinaryOps op, const Type *Ty, Signedness Sign) { +getBinaryOp(BinaryOps op, const Type *Ty, const Signedness& Sign) { switch (op) { default : assert(0 && "Invalid OldBinaryOps"); case SetEQ : @@ -891,12 +1254,12 @@ getBinaryOp(BinaryOps op, const Type *Ty, Signedness Sign) { // This is an obsolete instruction so we must upgrade it based on the // types of its operands. bool isFP = Ty->isFloatingPoint(); - if (const PackedType* PTy = dyn_cast(Ty)) - // If its a packed type we want to use the element type + if (const VectorType* PTy = dyn_cast(Ty)) + // If its a vector type we want to use the element type isFP = PTy->getElementType()->isFloatingPoint(); if (isFP) return Instruction::FDiv; - else if (Sign == Signed) + else if (Sign.isSigned()) return Instruction::SDiv; return Instruction::UDiv; } @@ -907,19 +1270,26 @@ getBinaryOp(BinaryOps op, const Type *Ty, Signedness Sign) { // This is an obsolete instruction so we must upgrade it based on the // types of its operands. bool isFP = Ty->isFloatingPoint(); - if (const PackedType* PTy = dyn_cast(Ty)) - // If its a packed type we want to use the element type + if (const VectorType* PTy = dyn_cast(Ty)) + // If its a vector type we want to use the element type isFP = PTy->getElementType()->isFloatingPoint(); // Select correct opcode if (isFP) return Instruction::FRem; - else if (Sign == Signed) + else if (Sign.isSigned()) return Instruction::SRem; return Instruction::URem; } case URemOp : return Instruction::URem; case SRemOp : return Instruction::SRem; case FRemOp : return Instruction::FRem; + case LShrOp : return Instruction::LShr; + case AShrOp : return Instruction::AShr; + case ShlOp : return Instruction::Shl; + case ShrOp : + if (Sign.isSigned()) + return Instruction::AShr; + return Instruction::LShr; case AndOp : return Instruction::And; case OrOp : return Instruction::Or; case XorOp : return Instruction::Xor; @@ -928,8 +1298,8 @@ getBinaryOp(BinaryOps op, const Type *Ty, Signedness Sign) { static inline Instruction::OtherOps getCompareOp(BinaryOps op, unsigned short &predicate, const Type* &Ty, - Signedness Sign) { - bool isSigned = Sign == Signed; + const Signedness &Sign) { + bool isSigned = Sign.isSigned(); bool isFP = Ty->isFloatingPoint(); switch (op) { default : assert(0 && "Invalid OldSetCC"); @@ -1009,16 +1379,11 @@ static inline Instruction::MemoryOps getMemoryOp(MemoryOps op) { } static inline Instruction::OtherOps -getOtherOp(OtherOps op, Signedness Sign) { +getOtherOp(OtherOps op, const Signedness &Sign) { switch (op) { default : assert(0 && "Invalid OldOtherOps"); case PHIOp : return Instruction::PHI; case CallOp : return Instruction::Call; - case ShlOp : return Instruction::Shl; - case ShrOp : - if (Sign == Signed) - return Instruction::AShr; - return Instruction::LShr; case SelectOp : return Instruction::Select; case UserOp1 : return Instruction::UserOp1; case UserOp2 : return Instruction::UserOp2; @@ -1028,14 +1393,12 @@ getOtherOp(OtherOps op, Signedness Sign) { case ShuffleVectorOp : return Instruction::ShuffleVector; case ICmpOp : return Instruction::ICmp; case FCmpOp : return Instruction::FCmp; - case LShrOp : return Instruction::LShr; - case AShrOp : return Instruction::AShr; }; } static inline Value* -getCast(CastOps op, Value *Src, Signedness SrcSign, const Type *DstTy, - Signedness DstSign, bool ForceInstruction = false) { +getCast(CastOps op, Value *Src, const Signedness &SrcSign, const Type *DstTy, + const Signedness &DstSign, bool ForceInstruction = false) { Instruction::CastOps Opcode; const Type* SrcTy = Src->getType(); if (op == CastOp) { @@ -1072,7 +1435,8 @@ getCast(CastOps op, Value *Src, Signedness SrcSign, const Type *DstTy, } // Determine the opcode to use by calling CastInst::getCastOpcode Opcode = - CastInst::getCastOpcode(Src, SrcSign == Signed, DstTy, DstSign == Signed); + CastInst::getCastOpcode(Src, SrcSign.isSigned(), DstTy, + DstSign.isSigned()); } else switch (op) { default: assert(0 && "Invalid cast token"); @@ -1100,93 +1464,144 @@ upgradeIntrinsicCall(const Type* RetTy, const ValID &ID, std::vector& Args) { std::string Name = ID.Type == ValID::NameVal ? ID.Name : ""; - if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") { - if (Args.size() != 2) - error("Invalid prototype for " + Name + " prototype"); - return new FCmpInst(FCmpInst::FCMP_UNO, Args[0], Args[1]); - } else { - static unsigned upgradeCount = 1; - const Type* PtrTy = PointerType::get(Type::Int8Ty); - std::vector Params; - if (Name == "llvm.va_start" || Name == "llvm.va_end") { - if (Args.size() != 1) - error("Invalid prototype for " + Name + " prototype"); - Params.push_back(PtrTy); - const FunctionType *FTy = FunctionType::get(Type::VoidTy, Params, false); - const PointerType *PFTy = PointerType::get(FTy); - Value* Func = getVal(PFTy, ID); - std::string InstName("va_upgrade"); - InstName += llvm::utostr(upgradeCount++); - Args[0] = new BitCastInst(Args[0], PtrTy, InstName, CurBB); - return new CallInst(Func, Args); - } else if (Name == "llvm.va_copy") { - if (Args.size() != 2) - error("Invalid prototype for " + Name + " prototype"); - Params.push_back(PtrTy); - Params.push_back(PtrTy); - const FunctionType *FTy = FunctionType::get(Type::VoidTy, Params, false); - const PointerType *PFTy = PointerType::get(FTy); - Value* Func = getVal(PFTy, ID); - std::string InstName0("va_upgrade"); - InstName0 += llvm::utostr(upgradeCount++); - std::string InstName1("va_upgrade"); - InstName1 += llvm::utostr(upgradeCount++); - Args[0] = new BitCastInst(Args[0], PtrTy, InstName0, CurBB); - Args[1] = new BitCastInst(Args[1], PtrTy, InstName1, CurBB); - return new CallInst(Func, Args); + if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || + Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.') + return 0; + + switch (Name[5]) { + case 'i': + if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") { + if (Args.size() != 2) + error("Invalid prototype for " + Name); + return new FCmpInst(FCmpInst::FCMP_UNO, Args[0], Args[1]); + } + break; + + case 'v' : { + const Type* PtrTy = PointerType::get(Type::Int8Ty); + std::vector Params; + if (Name == "llvm.va_start" || Name == "llvm.va_end") { + if (Args.size() != 1) + error("Invalid prototype for " + Name + " prototype"); + Params.push_back(PtrTy); + const FunctionType *FTy = + FunctionType::get(Type::VoidTy, Params, false); + const PointerType *PFTy = PointerType::get(FTy); + Value* Func = getVal(PFTy, ID); + Args[0] = new BitCastInst(Args[0], PtrTy, makeNameUnique("va"), CurBB); + return new CallInst(Func, Args.begin(), Args.end()); + } else if (Name == "llvm.va_copy") { + if (Args.size() != 2) + error("Invalid prototype for " + Name + " prototype"); + Params.push_back(PtrTy); + Params.push_back(PtrTy); + const FunctionType *FTy = + FunctionType::get(Type::VoidTy, Params, false); + const PointerType *PFTy = PointerType::get(FTy); + Value* Func = getVal(PFTy, ID); + std::string InstName0(makeNameUnique("va0")); + std::string InstName1(makeNameUnique("va1")); + Args[0] = new BitCastInst(Args[0], PtrTy, InstName0, CurBB); + Args[1] = new BitCastInst(Args[1], PtrTy, InstName1, CurBB); + return new CallInst(Func, Args.begin(), Args.end()); + } } } return 0; } -const Type* upgradeGEPIndices(const Type* PTy, - std::vector *Indices, - std::vector &VIndices, - std::vector *CIndices = 0) { - // Traverse the indices with a gep_type_iterator so we can build the list - // of constant and value indices for use later. Also perform upgrades - VIndices.clear(); - if (CIndices) CIndices->clear(); - for (unsigned i = 0, e = Indices->size(); i != e; ++i) - VIndices.push_back((*Indices)[i].V); - generic_gep_type_iterator::iterator> - GTI = gep_type_begin(PTy, VIndices.begin(), VIndices.end()), - GTE = gep_type_end(PTy, VIndices.begin(), VIndices.end()); - for (unsigned i = 0, e = Indices->size(); i != e && GTI != GTE; ++i, ++GTI) { - Value *Index = VIndices[i]; - if (CIndices && !isa(Index)) - error("Indices to constant getelementptr must be constants"); - // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte - // struct indices to i32 struct indices with ZExt for compatibility. - else if (isa(*GTI)) { // Only change struct indices - if (ConstantInt *CUI = dyn_cast(Index)) - if (CUI->getType()->getBitWidth() == 8) - Index = - ConstantExpr::getCast(Instruction::ZExt, CUI, Type::Int32Ty); +const Type* upgradeGEPCEIndices(const Type* PTy, + std::vector *Indices, + std::vector &Result) { + const Type *Ty = PTy; + Result.clear(); + for (unsigned i = 0, e = Indices->size(); i != e ; ++i) { + Constant *Index = cast((*Indices)[i].V); + + if (ConstantInt *CI = dyn_cast(Index)) { + // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte + // struct indices to i32 struct indices with ZExt for compatibility. + if (CI->getBitWidth() < 32) + Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty); + } + + if (isa(Ty)) { + // Make sure that unsigned SequentialType indices are zext'd to + // 64-bits if they were smaller than that because LLVM 2.0 will sext + // all indices for SequentialType elements. We must retain the same + // semantic (zext) for unsigned types. + if (const IntegerType *Ity = dyn_cast(Index->getType())) { + if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) { + Index = ConstantExpr::getCast(Instruction::ZExt, Index,Type::Int64Ty); + } + } + } + Result.push_back(Index); + Ty = GetElementPtrInst::getIndexedType(PTy, Result.begin(), + Result.end(),true); + if (!Ty) + error("Index list invalid for constant getelementptr"); + } + return Ty; +} + +const Type* upgradeGEPInstIndices(const Type* PTy, + std::vector *Indices, + std::vector &Result) { + const Type *Ty = PTy; + Result.clear(); + for (unsigned i = 0, e = Indices->size(); i != e ; ++i) { + Value *Index = (*Indices)[i].V; + + if (ConstantInt *CI = dyn_cast(Index)) { + // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte + // struct indices to i32 struct indices with ZExt for compatibility. + if (CI->getBitWidth() < 32) + Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty); + } + + + if (isa(Ty)) { // Only change struct indices + if (!isa(Index)) { + error("Invalid non-constant structure index"); + return 0; + } } else { // Make sure that unsigned SequentialType indices are zext'd to // 64-bits if they were smaller than that because LLVM 2.0 will sext // all indices for SequentialType elements. We must retain the same // semantic (zext) for unsigned types. - if (const IntegerType *Ity = dyn_cast(Index->getType())) - if (Ity->getBitWidth() < 64 && (*Indices)[i].S == Unsigned) - if (CIndices) + if (const IntegerType *Ity = dyn_cast(Index->getType())) { + if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) { + if (isa(Index)) Index = ConstantExpr::getCast(Instruction::ZExt, cast(Index), Type::Int64Ty); else Index = CastInst::create(Instruction::ZExt, Index, Type::Int64Ty, - makeNameUnique("gep_upgrade"), CurBB); + makeNameUnique("gep"), CurBB); + } + } } - // Add to the CIndices list, if requested. - if (CIndices) - CIndices->push_back(cast(Index)); + Result.push_back(Index); + Ty = GetElementPtrInst::getIndexedType(PTy, Result.begin(), + Result.end(),true); + if (!Ty) + error("Index list invalid for constant getelementptr"); } + return Ty; +} - const Type *IdxTy = - GetElementPtrInst::getIndexedType(PTy, VIndices, true); - if (!IdxTy) - error("Index list invalid for constant getelementptr"); - return IdxTy; +unsigned upgradeCallingConv(unsigned CC) { + switch (CC) { + case OldCallingConv::C : return CallingConv::C; + case OldCallingConv::CSRet : return CallingConv::C; + case OldCallingConv::Fast : return CallingConv::Fast; + case OldCallingConv::Cold : return CallingConv::Cold; + case OldCallingConv::X86_StdCall : return CallingConv::X86_StdCall; + case OldCallingConv::X86_FastCall: return CallingConv::X86_FastCall; + default: + return CC; + } } Module* UpgradeAssembly(const std::string &infile, std::istream& in, @@ -1223,10 +1638,10 @@ Module* UpgradeAssembly(const std::string &infile, std::istream& in, //Not all functions use vaarg, so make a second check for ObsoleteVarArgs { Function* F; - if ((F = Result->getNamedFunction("llvm.va_start")) + if ((F = Result->getFunction("llvm.va_start")) && F->getFunctionType()->getNumParams() == 0) ObsoleteVarArgs = true; - if((F = Result->getNamedFunction("llvm.va_copy")) + if((F = Result->getFunction("llvm.va_copy")) && F->getFunctionType()->getNumParams() == 1) ObsoleteVarArgs = true; } @@ -1237,7 +1652,7 @@ Module* UpgradeAssembly(const std::string &infile, std::istream& in, } if(ObsoleteVarArgs) { - if(Function* F = Result->getNamedFunction("llvm.va_start")) { + if(Function* F = Result->getFunction("llvm.va_start")) { if (F->arg_size() != 0) { error("Obsolete va_start takes 0 argument"); return 0; @@ -1266,7 +1681,7 @@ Module* UpgradeAssembly(const std::string &infile, std::istream& in, Result->getFunctionList().erase(F); } - if(Function* F = Result->getNamedFunction("llvm.va_end")) { + if(Function* F = Result->getFunction("llvm.va_end")) { if(F->arg_size() != 1) { error("Obsolete va_end takes 1 argument"); return 0; @@ -1292,7 +1707,7 @@ Module* UpgradeAssembly(const std::string &infile, std::istream& in, Result->getFunctionList().erase(F); } - if(Function* F = Result->getNamedFunction("llvm.va_copy")) { + if(Function* F = Result->getFunction("llvm.va_copy")) { if(F->arg_size() != 1) { error("Obsolete va_copy takes 1 argument"); return 0; @@ -1313,11 +1728,13 @@ Module* UpgradeAssembly(const std::string &infile, std::istream& in, while (!F->use_empty()) { CallInst* CI = cast(F->use_back()); - AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI); - AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI); - new StoreInst(CI->getOperand(1), b, CI); - new CallInst(NF, a, b, "", CI); - Value* foo = new LoadInst(a, "vacopy.fix.3", CI); + Value *Args[2] = { + new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI), + new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI) + }; + new StoreInst(CI->getOperand(1), Args[1], CI); + new CallInst(NF, Args, Args + 2, "", CI); + Value* foo = new LoadInst(Args[0], "vacopy.fix.3", CI); CI->replaceAllUsesWith(foo); CI->getParent()->getInstList().erase(CI); } @@ -1339,7 +1756,7 @@ using namespace llvm; llvm::Function *FunctionVal; std::pair *ArgVal; llvm::BasicBlock *BasicBlockVal; - llvm::TerminatorInst *TermInstVal; + llvm::TermInstInfo TermInstVal; llvm::InstrInfo InstVal; llvm::ConstInfo ConstVal; llvm::ValueInfo ValueVal; @@ -1360,7 +1777,7 @@ using namespace llvm; uint64_t UInt64Val; int SIntVal; unsigned UIntVal; - double FPVal; + llvm::APFloat *FPVal; bool BoolVal; char *StrVal; // This memory is strdup'd! @@ -1394,7 +1811,7 @@ using namespace llvm; %type OptVolatile // 'volatile' or not %type OptTailCall // TAIL CALL or plain CALL. %type OptSideEffect // 'sideeffect' or not. -%type OptLinkage +%type OptLinkage FnDeclareLinkage %type BigOrLittle // ValueRef - Unresolved reference to a definition or BB @@ -1443,8 +1860,9 @@ using namespace llvm; // Binary Operators %type ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories +%type ShiftOps %token ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM -%token AND OR XOR +%token AND OR XOR SHL SHR ASHR LSHR %token SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators %token ICMP FCMP @@ -1452,8 +1870,7 @@ using namespace llvm; %token MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR // Other Operators -%type ShiftOps -%token PHI_TOK SELECT SHL SHR ASHR LSHR VAARG +%token PHI_TOK SELECT VAARG %token EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR %token VAARG_old VANEXT_old //OBSOLETE @@ -1561,28 +1978,28 @@ OptAssign }; OptLinkage - : INTERNAL { $$ = GlobalValue::InternalLinkage; } + : INTERNAL { $$ = GlobalValue::InternalLinkage; } | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } | WEAK { $$ = GlobalValue::WeakLinkage; } | APPENDING { $$ = GlobalValue::AppendingLinkage; } | DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; } | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } - | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } + | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } | /*empty*/ { $$ = GlobalValue::ExternalLinkage; } ; OptCallingConv - : /*empty*/ { $$ = CallingConv::C; } - | CCC_TOK { $$ = CallingConv::C; } - | CSRETCC_TOK { $$ = CallingConv::CSRet; } - | FASTCC_TOK { $$ = CallingConv::Fast; } - | COLDCC_TOK { $$ = CallingConv::Cold; } - | X86_STDCALLCC_TOK { $$ = CallingConv::X86_StdCall; } - | X86_FASTCALLCC_TOK { $$ = CallingConv::X86_FastCall; } + : /*empty*/ { $$ = lastCallingConv = OldCallingConv::C; } + | CCC_TOK { $$ = lastCallingConv = OldCallingConv::C; } + | CSRETCC_TOK { $$ = lastCallingConv = OldCallingConv::CSRet; } + | FASTCC_TOK { $$ = lastCallingConv = OldCallingConv::Fast; } + | COLDCC_TOK { $$ = lastCallingConv = OldCallingConv::Cold; } + | X86_STDCALLCC_TOK { $$ = lastCallingConv = OldCallingConv::X86_StdCall; } + | X86_FASTCALLCC_TOK { $$ = lastCallingConv = OldCallingConv::X86_FastCall; } | CC_TOK EUINT64VAL { if ((unsigned)$2 != $2) error("Calling conv too large"); - $$ = $2; + $$ = lastCallingConv = $2; } ; @@ -1651,23 +2068,23 @@ GlobalVarAttribute TypesV : Types | VOID { - $$.T = new PATypeHolder($1.T); - $$.S = Signless; + $$.PAT = new PATypeHolder($1.T); + $$.S.makeSignless(); } ; UpRTypesV : UpRTypes | VOID { - $$.T = new PATypeHolder($1.T); - $$.S = Signless; + $$.PAT = new PATypeHolder($1.T); + $$.S.makeSignless(); } ; Types : UpRTypes { if (!UpRefs.empty()) - error("Invalid upreference in type: " + (*$1.T)->getDescription()); + error("Invalid upreference in type: " + (*$1.PAT)->getDescription()); $$ = $1; } ; @@ -1680,96 +2097,112 @@ PrimType // Derived types are added later... UpRTypes : PrimType { - $$.T = new PATypeHolder($1.T); - $$.S = $1.S; + $$.PAT = new PATypeHolder($1.T); + $$.S.copy($1.S); } | OPAQUE { - $$.T = new PATypeHolder(OpaqueType::get()); - $$.S = Signless; + $$.PAT = new PATypeHolder(OpaqueType::get()); + $$.S.makeSignless(); } | SymbolicValueRef { // Named types are also simple types... + $$.S.copy(getTypeSign($1)); const Type* tmp = getType($1); - $$.T = new PATypeHolder(tmp); - $$.S = Signless; // FIXME: what if its signed? + $$.PAT = new PATypeHolder(tmp); } | '\\' EUINT64VAL { // Type UpReference if ($2 > (uint64_t)~0U) error("Value out of range"); OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder UpRefs.push_back(UpRefRecord((unsigned)$2, OT)); // Add to vector... - $$.T = new PATypeHolder(OT); - $$.S = Signless; + $$.PAT = new PATypeHolder(OT); + $$.S.makeSignless(); UR_OUT("New Upreference!\n"); } | UpRTypesV '(' ArgTypeListI ')' { // Function derived type? + $$.S.makeComposite($1.S); std::vector Params; for (std::list::iterator I = $3->begin(), E = $3->end(); I != E; ++I) { - Params.push_back(I->T->get()); - delete I->T; + Params.push_back(I->PAT->get()); + $$.S.add(I->S); } bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - $$.T = new PATypeHolder(HandleUpRefs( - FunctionType::get($1.T->get(),Params,isVarArg))); - $$.S = $1.S; - delete $1.T; // Delete the return type handle + ParamAttrsList *PAL = 0; + if (lastCallingConv == OldCallingConv::CSRet) { + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg + Attrs.push_back(PAWI); + PAL = ParamAttrsList::get(Attrs); + } + + const FunctionType *FTy = + FunctionType::get($1.PAT->get(), Params, isVarArg, PAL); + + $$.PAT = new PATypeHolder( HandleUpRefs(FTy, $$.S) ); + delete $1.PAT; // Delete the return type handle delete $3; // Delete the argument list } | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type? - $$.T = new PATypeHolder(HandleUpRefs(ArrayType::get($4.T->get(), - (unsigned)$2))); - $$.S = $4.S; - delete $4.T; - } - | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type? - const llvm::Type* ElemTy = $4.T->get(); - if ((unsigned)$2 != $2) - error("Unsigned result not equal to signed result"); - if (!(ElemTy->isInteger() || ElemTy->isFloatingPoint())) - error("Elements of a PackedType must be integer or floating point"); - if (!isPowerOf2_32($2)) - error("PackedType length should be a power of 2"); - $$.T = new PATypeHolder(HandleUpRefs(PackedType::get(ElemTy, - (unsigned)$2))); - $$.S = $4.S; - delete $4.T; + $$.S.makeComposite($4.S); + $$.PAT = new PATypeHolder(HandleUpRefs(ArrayType::get($4.PAT->get(), + (unsigned)$2), $$.S)); + delete $4.PAT; + } + | '<' EUINT64VAL 'x' UpRTypes '>' { // Vector type? + const llvm::Type* ElemTy = $4.PAT->get(); + if ((unsigned)$2 != $2) + error("Unsigned result not equal to signed result"); + if (!(ElemTy->isInteger() || ElemTy->isFloatingPoint())) + error("Elements of a VectorType must be integer or floating point"); + if (!isPowerOf2_32($2)) + error("VectorType length should be a power of 2"); + $$.S.makeComposite($4.S); + $$.PAT = new PATypeHolder(HandleUpRefs(VectorType::get(ElemTy, + (unsigned)$2), $$.S)); + delete $4.PAT; } | '{' TypeListI '}' { // Structure type? std::vector Elements; + $$.S.makeComposite(); for (std::list::iterator I = $2->begin(), - E = $2->end(); I != E; ++I) - Elements.push_back(I->T->get()); - $$.T = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); - $$.S = Signless; + E = $2->end(); I != E; ++I) { + Elements.push_back(I->PAT->get()); + $$.S.add(I->S); + } + $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements), $$.S)); delete $2; } | '{' '}' { // Empty structure type? - $$.T = new PATypeHolder(StructType::get(std::vector())); - $$.S = Signless; + $$.PAT = new PATypeHolder(StructType::get(std::vector())); + $$.S.makeComposite(); } | '<' '{' TypeListI '}' '>' { // Packed Structure type? + $$.S.makeComposite(); std::vector Elements; for (std::list::iterator I = $3->begin(), E = $3->end(); I != E; ++I) { - Elements.push_back(I->T->get()); - delete I->T; + Elements.push_back(I->PAT->get()); + $$.S.add(I->S); + delete I->PAT; } - $$.T = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true))); - $$.S = Signless; + $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true), + $$.S)); delete $3; } | '<' '{' '}' '>' { // Empty packed structure type? - $$.T = new PATypeHolder(StructType::get(std::vector(),true)); - $$.S = Signless; + $$.PAT = new PATypeHolder(StructType::get(std::vector(),true)); + $$.S.makeComposite(); } | UpRTypes '*' { // Pointer type? - if ($1.T->get() == Type::LabelTy) + if ($1.PAT->get() == Type::LabelTy) error("Cannot form a pointer to a basic block"); - $$.T = new PATypeHolder(HandleUpRefs(PointerType::get($1.T->get()))); - $$.S = $1.S; - delete $1.T; + $$.S.makeComposite($1.S); + $$.PAT = new PATypeHolder(HandleUpRefs(PointerType::get($1.PAT->get()), + $$.S)); + delete $1.PAT; } ; @@ -1791,15 +2224,15 @@ ArgTypeListI : TypeListI | TypeListI ',' DOTDOTDOT { PATypeInfo VoidTI; - VoidTI.T = new PATypeHolder(Type::VoidTy); - VoidTI.S = Signless; + VoidTI.PAT = new PATypeHolder(Type::VoidTy); + VoidTI.S.makeSignless(); ($$=$1)->push_back(VoidTI); } | DOTDOTDOT { $$ = new std::list(); PATypeInfo VoidTI; - VoidTI.T = new PATypeHolder(Type::VoidTy); - VoidTI.S = Signless; + VoidTI.PAT = new PATypeHolder(Type::VoidTy); + VoidTI.S.makeSignless(); $$->push_back(VoidTI); } | /*empty*/ { @@ -1815,10 +2248,10 @@ ArgTypeListI // ConstVal : Types '[' ConstVector ']' { // Nonempty unsized arr - const ArrayType *ATy = dyn_cast($1.T->get()); + const ArrayType *ATy = dyn_cast($1.PAT->get()); if (ATy == 0) error("Cannot make array constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); const Type *ETy = ATy->getElementType(); int NumElements = ATy->getNumElements(); @@ -1840,28 +2273,28 @@ ConstVal Elems.push_back(C); } $$.C = ConstantArray::get(ATy, Elems); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; delete $3; } | Types '[' ']' { - const ArrayType *ATy = dyn_cast($1.T->get()); + const ArrayType *ATy = dyn_cast($1.PAT->get()); if (ATy == 0) error("Cannot make array constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); int NumElements = ATy->getNumElements(); if (NumElements != -1 && NumElements != 0) error("Type mismatch: constant sized array initialized with 0" " arguments, but has size of " + itostr(NumElements) +""); $$.C = ConstantArray::get(ATy, std::vector()); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; } | Types 'c' STRINGCONSTANT { - const ArrayType *ATy = dyn_cast($1.T->get()); + const ArrayType *ATy = dyn_cast($1.PAT->get()); if (ATy == 0) error("Cannot make array constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); int NumElements = ATy->getNumElements(); const Type *ETy = dyn_cast(ATy->getElementType()); if (!ETy || cast(ETy)->getBitWidth() != 8) @@ -1877,14 +2310,14 @@ ConstVal Vals.push_back(ConstantInt::get(ETy, *C)); free($3); $$.C = ConstantArray::get(ATy, Vals); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; } | Types '<' ConstVector '>' { // Nonempty unsized arr - const PackedType *PTy = dyn_cast($1.T->get()); + const VectorType *PTy = dyn_cast($1.PAT->get()); if (PTy == 0) error("Cannot make packed constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); const Type *ETy = PTy->getElementType(); int NumElements = PTy->getNumElements(); // Verify that we have the correct size... @@ -1903,16 +2336,16 @@ ConstVal ValTy->getDescription() + "'"); Elems.push_back(C); } - $$.C = ConstantPacked::get(PTy, Elems); - $$.S = $1.S; - delete $1.T; + $$.C = ConstantVector::get(PTy, Elems); + $$.S.copy($1.S); + delete $1.PAT; delete $3; } | Types '{' ConstVector '}' { - const StructType *STy = dyn_cast($1.T->get()); + const StructType *STy = dyn_cast($1.PAT->get()); if (STy == 0) error("Cannot make struct constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); if ($3->size() != STy->getNumContainedTypes()) error("Illegal number of initializers for structure type"); @@ -1926,26 +2359,26 @@ ConstVal Fields.push_back(C); } $$.C = ConstantStruct::get(STy, Fields); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; delete $3; } | Types '{' '}' { - const StructType *STy = dyn_cast($1.T->get()); + const StructType *STy = dyn_cast($1.PAT->get()); if (STy == 0) error("Cannot make struct constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); if (STy->getNumContainedTypes() != 0) error("Illegal number of initializers for structure type"); $$.C = ConstantStruct::get(STy, std::vector()); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; } | Types '<' '{' ConstVector '}' '>' { - const StructType *STy = dyn_cast($1.T->get()); + const StructType *STy = dyn_cast($1.PAT->get()); if (STy == 0) error("Cannot make packed struct constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); if ($4->size() != STy->getNumContainedTypes()) error("Illegal number of initializers for packed structure type"); @@ -1959,40 +2392,40 @@ ConstVal Fields.push_back(C); } $$.C = ConstantStruct::get(STy, Fields); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; delete $4; } | Types '<' '{' '}' '>' { - const StructType *STy = dyn_cast($1.T->get()); + const StructType *STy = dyn_cast($1.PAT->get()); if (STy == 0) error("Cannot make packed struct constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); if (STy->getNumContainedTypes() != 0) error("Illegal number of initializers for packed structure type"); $$.C = ConstantStruct::get(STy, std::vector()); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; } | Types NULL_TOK { - const PointerType *PTy = dyn_cast($1.T->get()); + const PointerType *PTy = dyn_cast($1.PAT->get()); if (PTy == 0) error("Cannot make null pointer constant with type: '" + - $1.T->get()->getDescription() + "'"); + $1.PAT->get()->getDescription() + "'"); $$.C = ConstantPointerNull::get(PTy); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; } | Types UNDEF { - $$.C = UndefValue::get($1.T->get()); - $$.S = $1.S; - delete $1.T; + $$.C = UndefValue::get($1.PAT->get()); + $$.S.copy($1.S); + delete $1.PAT; } | Types SymbolicValueRef { - const PointerType *Ty = dyn_cast($1.T->get()); + const PointerType *Ty = dyn_cast($1.PAT->get()); if (Ty == 0) error("Global const reference must be a pointer type, not" + - $1.T->get()->getDescription()); + $1.PAT->get()->getDescription()); // ConstExprs can exist in the body of a function, thus creating // GlobalValues whenever they refer to a variable. Because we are in @@ -2003,6 +2436,7 @@ ConstVal // Function *SavedCurFn = CurFun.CurrentFunction; CurFun.CurrentFunction = 0; + $2.S.copy($1.S); Value *V = getExistingValue(Ty, $2); CurFun.CurrentFunction = SavedCurFn; @@ -2043,60 +2477,65 @@ ConstVal } } $$.C = cast(V); - $$.S = $1.S; - delete $1.T; // Free the type handle + $$.S.copy($1.S); + delete $1.PAT; // Free the type handle } | Types ConstExpr { - if ($1.T->get() != $2.C->getType()) + if ($1.PAT->get() != $2.C->getType()) error("Mismatched types for constant expression"); $$ = $2; - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; } | Types ZEROINITIALIZER { - const Type *Ty = $1.T->get(); + const Type *Ty = $1.PAT->get(); if (isa(Ty) || Ty == Type::LabelTy || isa(Ty)) error("Cannot create a null initialized value of this type"); $$.C = Constant::getNullValue(Ty); - $$.S = $1.S; - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; } | SIntType EINT64VAL { // integral constants const Type *Ty = $1.T; if (!ConstantInt::isValueValidForType(Ty, $2)) error("Constant value doesn't fit in type"); $$.C = ConstantInt::get(Ty, $2); - $$.S = Signed; + $$.S.makeSigned(); } | UIntType EUINT64VAL { // integral constants const Type *Ty = $1.T; if (!ConstantInt::isValueValidForType(Ty, $2)) error("Constant value doesn't fit in type"); $$.C = ConstantInt::get(Ty, $2); - $$.S = Unsigned; + $$.S.makeUnsigned(); } | BOOL TRUETOK { // Boolean constants $$.C = ConstantInt::get(Type::Int1Ty, true); - $$.S = Unsigned; + $$.S.makeUnsigned(); } | BOOL FALSETOK { // Boolean constants $$.C = ConstantInt::get(Type::Int1Ty, false); - $$.S = Unsigned; + $$.S.makeUnsigned(); } | FPType FPVAL { // Float & Double constants - if (!ConstantFP::isValueValidForType($1.T, $2)) + if (!ConstantFP::isValueValidForType($1.T, *$2)) error("Floating point constant invalid for type"); - $$.C = ConstantFP::get($1.T, $2); - $$.S = Signless; + // Lexer has no type info, so builds all FP constants as double. + // Fix this here. + if ($1.T==Type::FloatTy) + $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); + $$.C = ConstantFP::get($1.T, *$2); + delete $2; + $$.S.makeSignless(); } ; ConstExpr : CastOps '(' ConstVal TO Types ')' { const Type* SrcTy = $3.C->getType(); - const Type* DstTy = $5.T->get(); - Signedness SrcSign = $3.S; - Signedness DstSign = $5.S; + const Type* DstTy = $5.PAT->get(); + Signedness SrcSign($3.S); + Signedness DstSign($5.S); if (!SrcTy->isFirstClassType()) error("cast constant expression from a non-primitive type: '" + SrcTy->getDescription() + "'"); @@ -2104,21 +2543,20 @@ ConstExpr error("cast constant expression to a non-primitive type: '" + DstTy->getDescription() + "'"); $$.C = cast(getCast($1, $3.C, SrcSign, DstTy, DstSign)); - $$.S = DstSign; - delete $5.T; + $$.S.copy(DstSign); + delete $5.PAT; } | GETELEMENTPTR '(' ConstVal IndexList ')' { const Type *Ty = $3.C->getType(); if (!isa(Ty)) error("GetElementPtr requires a pointer operand"); - std::vector VIndices; std::vector CIndices; - upgradeGEPIndices($3.C->getType(), $4, VIndices, &CIndices); + upgradeGEPCEIndices($3.C->getType(), $4, CIndices); delete $4; - $$.C = ConstantExpr::getGetElementPtr($3.C, CIndices); - $$.S = Signless; + $$.C = ConstantExpr::getGetElementPtr($3.C, &CIndices[0], CIndices.size()); + $$.S.copy(getElementSign($3, CIndices)); } | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' { if (!$3.C->getType()->isInteger() || @@ -2127,7 +2565,7 @@ ConstExpr if ($5.C->getType() != $7.C->getType()) error("Select operand types must match"); $$.C = ConstantExpr::getSelect($3.C, $5.C, $7.C); - $$.S = Unsigned; + $$.S.copy($5.S); } | ArithmeticOps '(' ConstVal ',' ConstVal ')' { const Type *Ty = $3.C->getType(); @@ -2155,20 +2593,20 @@ ConstExpr ConstantExpr::getCast(Instruction::PtrToInt, $5.C, IntPtrTy)); $$.C = ConstantExpr::getCast(Instruction::IntToPtr, $$.C, Ty); } - $$.S = $3.S; + $$.S.copy($3.S); } | LogicalOps '(' ConstVal ',' ConstVal ')' { const Type* Ty = $3.C->getType(); if (Ty != $5.C->getType()) error("Logical operator types must match"); if (!Ty->isInteger()) { - if (!isa(Ty) || - !cast(Ty)->getElementType()->isInteger()) + if (!isa(Ty) || + !cast(Ty)->getElementType()->isInteger()) error("Logical operator requires integer operands"); } Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $3.S); $$.C = ConstantExpr::get(Opcode, $3.C, $5.C); - $$.S = $3.S; + $$.S.copy($3.S); } | SetCondOps '(' ConstVal ',' ConstVal ')' { const Type* Ty = $3.C->getType(); @@ -2177,46 +2615,48 @@ ConstExpr unsigned short pred; Instruction::OtherOps Opcode = getCompareOp($1, pred, Ty, $3.S); $$.C = ConstantExpr::getCompare(Opcode, $3.C, $5.C); - $$.S = Unsigned; + $$.S.makeUnsigned(); } | ICMP IPredicates '(' ConstVal ',' ConstVal ')' { if ($4.C->getType() != $6.C->getType()) error("icmp operand types must match"); $$.C = ConstantExpr::getCompare($2, $4.C, $6.C); - $$.S = Unsigned; + $$.S.makeUnsigned(); } | FCMP FPredicates '(' ConstVal ',' ConstVal ')' { if ($4.C->getType() != $6.C->getType()) error("fcmp operand types must match"); $$.C = ConstantExpr::getCompare($2, $4.C, $6.C); - $$.S = Unsigned; + $$.S.makeUnsigned(); } | ShiftOps '(' ConstVal ',' ConstVal ')' { if (!$5.C->getType()->isInteger() || cast($5.C->getType())->getBitWidth() != 8) error("Shift count for shift constant must be unsigned byte"); + const Type* Ty = $3.C->getType(); if (!$3.C->getType()->isInteger()) error("Shift constant expression requires integer operand"); - $$.C = ConstantExpr::get(getOtherOp($1, $3.S), $3.C, $5.C); - $$.S = $3.S; + Constant *ShiftAmt = ConstantExpr::getZExt($5.C, Ty); + $$.C = ConstantExpr::get(getBinaryOp($1, Ty, $3.S), $3.C, ShiftAmt); + $$.S.copy($3.S); } | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' { if (!ExtractElementInst::isValidOperands($3.C, $5.C)) error("Invalid extractelement operands"); $$.C = ConstantExpr::getExtractElement($3.C, $5.C); - $$.S = $3.S; + $$.S.copy($3.S.get(0)); } | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' { if (!InsertElementInst::isValidOperands($3.C, $5.C, $7.C)) error("Invalid insertelement operands"); $$.C = ConstantExpr::getInsertElement($3.C, $5.C, $7.C); - $$.S = $3.S; + $$.S.copy($3.S); } | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' { if (!ShuffleVectorInst::isValidOperands($3.C, $5.C, $7.C)) error("Invalid shufflevector operands"); $$.C = ConstantExpr::getShuffleVector($3.C, $5.C, $7.C); - $$.S = $3.S; + $$.S.copy($3.S); } ; @@ -2285,15 +2725,15 @@ ConstPool // If types are not resolved eagerly, then the two types will not be // determined to be the same type! // - const Type* Ty = $4.T->get(); - ResolveTypeTo($2, Ty); + ResolveTypeTo($2, $4.PAT->get(), $4.S); - if (!setTypeName(Ty, $2) && !$2) { - // If this is a named type that is not a redefinition, add it to the slot - // table. - CurModule.Types.push_back(Ty); + if (!setTypeName($4, $2) && !$2) { + // If this is a numbered type that is not a redefinition, add it to the + // slot table. + CurModule.Types.push_back($4.PAT->get()); + CurModule.TypeSigns.push_back($4.S); } - delete $4.T; + delete $4.PAT; } | ConstPool FunctionProto { // Function prototypes can be in const pool } @@ -2302,29 +2742,32 @@ ConstPool | ConstPool OptAssign OptLinkage GlobalType ConstVal { if ($5.C == 0) error("Global value initializer is not a constant"); - CurGV = ParseGlobalVariable($2, $3, $4, $5.C->getType(), $5.C); + CurGV = ParseGlobalVariable($2, $3, $4, $5.C->getType(), $5.C, $5.S); } GlobalVarAttributes { CurGV = 0; } | ConstPool OptAssign EXTERNAL GlobalType Types { - const Type *Ty = $5.T->get(); - CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, Ty, 0); - delete $5.T; + const Type *Ty = $5.PAT->get(); + CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, Ty, 0, + $5.S); + delete $5.PAT; } GlobalVarAttributes { CurGV = 0; } | ConstPool OptAssign DLLIMPORT GlobalType Types { - const Type *Ty = $5.T->get(); - CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, Ty, 0); - delete $5.T; + const Type *Ty = $5.PAT->get(); + CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, Ty, 0, + $5.S); + delete $5.PAT; } GlobalVarAttributes { CurGV = 0; } | ConstPool OptAssign EXTERN_WEAK GlobalType Types { - const Type *Ty = $5.T->get(); + const Type *Ty = $5.PAT->get(); CurGV = - ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, Ty, 0); - delete $5.T; + ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, Ty, 0, + $5.S); + delete $5.PAT; } GlobalVarAttributes { CurGV = 0; } @@ -2408,7 +2851,7 @@ OptName ArgVal : Types OptName { - if ($1.T->get() == Type::VoidTy) + if ($1.PAT->get() == Type::VoidTy) error("void typed arguments are invalid"); $$ = new std::pair($1, $2); } @@ -2432,15 +2875,15 @@ ArgList | ArgListH ',' DOTDOTDOT { $$ = $1; PATypeInfo VoidTI; - VoidTI.T = new PATypeHolder(Type::VoidTy); - VoidTI.S = Signless; + VoidTI.PAT = new PATypeHolder(Type::VoidTy); + VoidTI.S.makeSignless(); $$->push_back(std::pair(VoidTI, 0)); } | DOTDOTDOT { $$ = new std::vector >(); PATypeInfo VoidTI; - VoidTI.T = new PATypeHolder(Type::VoidTy); - VoidTI.S = Signless; + VoidTI.PAT = new PATypeHolder(Type::VoidTy); + VoidTI.S.makeSignless(); $$->push_back(std::pair(VoidTI, 0)); } | /* empty */ { $$ = 0; } @@ -2452,36 +2895,51 @@ FunctionHeaderH std::string FunctionName($3); free($3); // Free strdup'd memory! - const Type* RetTy = $2.T->get(); + const Type* RetTy = $2.PAT->get(); if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy) error("LLVM functions cannot return aggregate types"); - std::vector ParamTypeList; + Signedness FTySign; + FTySign.makeComposite($2.S); + std::vector ParamTyList; // In LLVM 2.0 the signatures of three varargs intrinsics changed to take // i8*. We check here for those names and override the parameter list // types to ensure the prototype is correct. if (FunctionName == "llvm.va_start" || FunctionName == "llvm.va_end") { - ParamTypeList.push_back(PointerType::get(Type::Int8Ty)); + ParamTyList.push_back(PointerType::get(Type::Int8Ty)); } else if (FunctionName == "llvm.va_copy") { - ParamTypeList.push_back(PointerType::get(Type::Int8Ty)); - ParamTypeList.push_back(PointerType::get(Type::Int8Ty)); + ParamTyList.push_back(PointerType::get(Type::Int8Ty)); + ParamTyList.push_back(PointerType::get(Type::Int8Ty)); } else if ($5) { // If there are arguments... for (std::vector >::iterator I = $5->begin(), E = $5->end(); I != E; ++I) { - const Type *Ty = I->first.T->get(); - ParamTypeList.push_back(Ty); + const Type *Ty = I->first.PAT->get(); + ParamTyList.push_back(Ty); + FTySign.add(I->first.S); } } - bool isVarArg = - ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; - if (isVarArg) ParamTypeList.pop_back(); + bool isVarArg = ParamTyList.size() && ParamTyList.back() == Type::VoidTy; + if (isVarArg) + ParamTyList.pop_back(); + + // Convert the CSRet calling convention into the corresponding parameter + // attribute. + ParamAttrsList *PAL = 0; + if ($1 == OldCallingConv::CSRet) { + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg + Attrs.push_back(PAWI); + PAL = ParamAttrsList::get(Attrs); + } - const FunctionType *FT = FunctionType::get(RetTy, ParamTypeList, isVarArg); + const FunctionType *FT = + FunctionType::get(RetTy, ParamTyList, isVarArg, PAL); const PointerType *PFT = PointerType::get(FT); - delete $2.T; + delete $2.PAT; ValID ID; if (!FunctionName.empty()) { @@ -2489,34 +2947,99 @@ FunctionHeaderH } else { ID = ValID::create((int)CurModule.Values[PFT].size()); } + ID.S.makeComposite(FTySign); Function *Fn = 0; + Module* M = CurModule.CurrentModule; + // See if this function was forward referenced. If so, recycle the object. if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) { // Move the function to the end of the list, from whereever it was // previously inserted. Fn = cast(FWRef); - CurModule.CurrentModule->getFunctionList().remove(Fn); - CurModule.CurrentModule->getFunctionList().push_back(Fn); - } else if (!FunctionName.empty() && // Merge with an earlier prototype? - (Fn = CurModule.CurrentModule->getFunction(FunctionName, FT))) { - // If this is the case, either we need to be a forward decl, or it needs - // to be. - if (!CurFun.isDeclare && !Fn->isExternal()) - error("Redefinition of function '" + FunctionName + "'"); - - // Make sure to strip off any argument names so we can't get conflicts. - if (Fn->isExternal()) - for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end(); - AI != AE; ++AI) - AI->setName(""); - } else { // Not already defined? - Fn = new Function(FT, GlobalValue::ExternalLinkage, FunctionName, - CurModule.CurrentModule); - + M->getFunctionList().remove(Fn); + M->getFunctionList().push_back(Fn); + } else if (!FunctionName.empty()) { + GlobalValue *Conflict = M->getFunction(FunctionName); + if (!Conflict) + Conflict = M->getNamedGlobal(FunctionName); + if (Conflict && PFT == Conflict->getType()) { + if (!CurFun.isDeclare && !Conflict->isDeclaration()) { + // We have two function definitions that conflict, same type, same + // name. We should really check to make sure that this is the result + // of integer type planes collapsing and generate an error if it is + // not, but we'll just rename on the assumption that it is. However, + // let's do it intelligently and rename the internal linkage one + // if there is one. + std::string NewName(makeNameUnique(FunctionName)); + if (Conflict->hasInternalLinkage()) { + Conflict->setName(NewName); + RenameMapKey Key = + makeRenameMapKey(FunctionName, Conflict->getType(), ID.S); + CurModule.RenameMap[Key] = NewName; + Fn = new Function(FT, CurFun.Linkage, FunctionName, M); + InsertValue(Fn, CurModule.Values); + } else { + Fn = new Function(FT, CurFun.Linkage, NewName, M); + InsertValue(Fn, CurModule.Values); + RenameMapKey Key = + makeRenameMapKey(FunctionName, PFT, ID.S); + CurModule.RenameMap[Key] = NewName; + } + } else { + // If they are not both definitions, then just use the function we + // found since the types are the same. + Fn = cast(Conflict); + + // Make sure to strip off any argument names so we can't get + // conflicts. + if (Fn->isDeclaration()) + for (Function::arg_iterator AI = Fn->arg_begin(), + AE = Fn->arg_end(); AI != AE; ++AI) + AI->setName(""); + } + } else if (Conflict) { + // We have two globals with the same name and different types. + // Previously, this was permitted because the symbol table had + // "type planes" and names only needed to be distinct within a + // type plane. After PR411 was fixed, this is no loner the case. + // To resolve this we must rename one of the two. + if (Conflict->hasInternalLinkage()) { + // We can safely rename the Conflict. + RenameMapKey Key = + makeRenameMapKey(Conflict->getName(), Conflict->getType(), + CurModule.NamedValueSigns[Conflict->getName()]); + Conflict->setName(makeNameUnique(Conflict->getName())); + CurModule.RenameMap[Key] = Conflict->getName(); + Fn = new Function(FT, CurFun.Linkage, FunctionName, M); + InsertValue(Fn, CurModule.Values); + } else { + // We can't quietly rename either of these things, but we must + // rename one of them. Only if the function's linkage is internal can + // we forgo a warning message about the renamed function. + std::string NewName = makeNameUnique(FunctionName); + if (CurFun.Linkage != GlobalValue::InternalLinkage) { + warning("Renaming function '" + FunctionName + "' as '" + NewName + + "' may cause linkage errors"); + } + // Elect to rename the thing we're now defining. + Fn = new Function(FT, CurFun.Linkage, NewName, M); + InsertValue(Fn, CurModule.Values); + RenameMapKey Key = makeRenameMapKey(FunctionName, PFT, ID.S); + CurModule.RenameMap[Key] = NewName; + } + } else { + // There's no conflict, just define the function + Fn = new Function(FT, CurFun.Linkage, FunctionName, M); + InsertValue(Fn, CurModule.Values); + } + } else { + // There's no conflict, just define the function + Fn = new Function(FT, CurFun.Linkage, FunctionName, M); InsertValue(Fn, CurModule.Values); } + CurFun.FunctionStart(Fn); if (CurFun.isDeclare) { @@ -2525,7 +3048,7 @@ FunctionHeaderH // argument to another function. Fn->setLinkage(CurFun.Linkage); } - Fn->setCallingConv($1); + Fn->setCallingConv(upgradeCallingConv($1)); Fn->setAlignment($8); if ($7) { Fn->setSection($7); @@ -2535,20 +3058,24 @@ FunctionHeaderH // Add all of the arguments we parsed to the function... if ($5) { // Is null if empty... if (isVarArg) { // Nuke the last entry - assert($5->back().first.T->get() == Type::VoidTy && + assert($5->back().first.PAT->get() == Type::VoidTy && $5->back().second == 0 && "Not a varargs marker"); - delete $5->back().first.T; + delete $5->back().first.PAT; $5->pop_back(); // Delete the last entry } Function::arg_iterator ArgIt = Fn->arg_begin(); - for (std::vector >::iterator - I = $5->begin(), E = $5->end(); I != E; ++I, ++ArgIt) { - delete I->first.T; // Delete the typeholder... - setValueName(ArgIt, I->second); // Insert arg into symtab... + Function::arg_iterator ArgEnd = Fn->arg_end(); + std::vector >::iterator I = $5->begin(); + std::vector >::iterator E = $5->end(); + for ( ; I != E && ArgIt != ArgEnd; ++I, ++ArgIt) { + delete I->first.PAT; // Delete the typeholder... + ValueInfo VI; VI.V = ArgIt; VI.S.copy(I->first.S); + setValueName(VI, I->second); // Insert arg into symtab... InsertValue(ArgIt); } delete $5; // We're now done with the argument list } + lastCallingConv = OldCallingConv::C; } ; @@ -2557,7 +3084,7 @@ BEGIN ; FunctionHeader - : OptLinkage FunctionHeaderH BEGIN { + : OptLinkage { CurFun.Linkage = $1; } FunctionHeaderH BEGIN { $$ = CurFun.CurrentFunction; // Make sure that we keep track of the linkage type even if there was a @@ -2576,13 +3103,14 @@ Function }; FnDeclareLinkage - : /*default*/ - | DLLIMPORT { CurFun.Linkage = GlobalValue::DLLImportLinkage; } - | EXTERN_WEAK { CurFun.Linkage = GlobalValue::ExternalWeakLinkage; } + : /*default*/ { $$ = GlobalValue::ExternalLinkage; } + | DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; } + | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } ; FunctionProto - : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH { + : DECLARE { CurFun.isDeclare = true; } + FnDeclareLinkage { CurFun.Linkage = $3; } FunctionHeaderH { $$ = CurFun.CurrentFunction; CurFun.FunctionDone(); @@ -2600,20 +3128,26 @@ OptSideEffect ConstValueRef // A reference to a direct constant - : ESINT64VAL { $$ = ValID::create($1); } + : ESINT64VAL { $$ = ValID::create($1); } | EUINT64VAL { $$ = ValID::create($1); } | FPVAL { $$ = ValID::create($1); } - | TRUETOK { $$ = ValID::create(ConstantInt::get(Type::Int1Ty, true)); } - | FALSETOK { $$ = ValID::create(ConstantInt::get(Type::Int1Ty, false)); } + | TRUETOK { + $$ = ValID::create(ConstantInt::get(Type::Int1Ty, true)); + $$.S.makeUnsigned(); + } + | FALSETOK { + $$ = ValID::create(ConstantInt::get(Type::Int1Ty, false)); + $$.S.makeUnsigned(); + } | NULL_TOK { $$ = ValID::createNull(); } | UNDEF { $$ = ValID::createUndef(); } | ZEROINITIALIZER { $$ = ValID::createZeroInit(); } | '<' ConstVector '>' { // Nonempty unsized packed vector const Type *ETy = (*$2)[0].C->getType(); int NumElements = $2->size(); - PackedType* pt = PackedType::get(ETy, NumElements); - PATypeHolder* PTy = new PATypeHolder( - HandleUpRefs(PackedType::get(ETy, NumElements))); + VectorType* pt = VectorType::get(ETy, NumElements); + $$.S.makeComposite((*$2)[0].S); + PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt, $$.S)); // Verify all elements are correct type! std::vector Elems; @@ -2626,11 +3160,12 @@ ConstValueRef CTy->getDescription() + "'"); Elems.push_back(C); } - $$ = ValID::create(ConstantPacked::get(pt, Elems)); + $$ = ValID::create(ConstantVector::get(pt, Elems)); delete PTy; delete $2; } | ConstExpr { $$ = ValID::create($1.C); + $$.S.copy($1.S); } | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT { char *End = UnEscapeLexed($3, true); @@ -2643,12 +3178,11 @@ ConstValueRef } ; -// SymbolicValueRef - Reference to one of two ways of symbolically refering to -// another value. +// SymbolicValueRef - Reference to one of two ways of symbolically refering to // another value. // SymbolicValueRef - : INTVAL { $$ = ValID::create($1); } - | Name { $$ = ValID::create($1); } + : INTVAL { $$ = ValID::create($1); $$.S.makeSignless(); } + | Name { $$ = ValID::create($1); $$.S.makeSignless(); } ; // ValueRef - A reference to a definition... either constant or symbolic @@ -2662,10 +3196,11 @@ ValueRef // pool references (for things like: 'ret [2 x int] [ int 12, int 42]') ResolvedVal : Types ValueRef { - const Type *Ty = $1.T->get(); - $$.S = $1.S; + const Type *Ty = $1.PAT->get(); + $2.S.copy($1.S); $$.V = getVal(Ty, $2); - delete $1.T; + $$.S.copy($1.S); + delete $1.PAT; } ; @@ -2683,9 +3218,10 @@ BasicBlockList // BasicBlock : InstructionList OptAssign BBTerminatorInst { - setValueName($3, $2); - InsertValue($3); - $1->getInstList().push_back($3); + ValueInfo VI; VI.V = $3.TI; VI.S.copy($3.S); + setValueName(VI, $2); + InsertValue($3.TI); + $1->getInstList().push_back($3.TI); InsertValue($1); $$ = $1; } @@ -2698,7 +3234,7 @@ InstructionList $$ = $1; } | /* empty */ { - $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); + $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++),true); // Make sure to move the basic block to the correct location in the // function, instead of leaving it inserted wherever it was first // referenced. @@ -2721,26 +3257,36 @@ Unwind : UNWIND | EXCEPT; BBTerminatorInst : RET ResolvedVal { // Return with a result... - $$ = new ReturnInst($2.V); + $$.TI = new ReturnInst($2.V); + $$.S.makeSignless(); } | RET VOID { // Return with no result... - $$ = new ReturnInst(); + $$.TI = new ReturnInst(); + $$.S.makeSignless(); } | BR LABEL ValueRef { // Unconditional Branch... BasicBlock* tmpBB = getBBVal($3); - $$ = new BranchInst(tmpBB); + $$.TI = new BranchInst(tmpBB); + $$.S.makeSignless(); } // Conditional Branch... | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef { + $6.S.makeSignless(); + $9.S.makeSignless(); BasicBlock* tmpBBA = getBBVal($6); BasicBlock* tmpBBB = getBBVal($9); + $3.S.makeUnsigned(); Value* tmpVal = getVal(Type::Int1Ty, $3); - $$ = new BranchInst(tmpBBA, tmpBBB, tmpVal); + $$.TI = new BranchInst(tmpBBA, tmpBBB, tmpVal); + $$.S.makeSignless(); } | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' { + $3.S.copy($2.S); Value* tmpVal = getVal($2.T, $3); + $6.S.makeSignless(); BasicBlock* tmpBB = getBBVal($6); SwitchInst *S = new SwitchInst(tmpVal, tmpBB, $8->size()); - $$ = S; + $$.TI = S; + $$.S.makeSignless(); std::vector >::iterator I = $8->begin(), E = $8->end(); for (; I != E; ++I) { @@ -2752,37 +3298,62 @@ BBTerminatorInst delete $8; } | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' { + $3.S.copy($2.S); Value* tmpVal = getVal($2.T, $3); + $6.S.makeSignless(); BasicBlock* tmpBB = getBBVal($6); SwitchInst *S = new SwitchInst(tmpVal, tmpBB, 0); - $$ = S; + $$.TI = S; + $$.S.makeSignless(); } | INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')' TO LABEL ValueRef Unwind LABEL ValueRef { const PointerType *PFTy; const FunctionType *Ty; + Signedness FTySign; - if (!(PFTy = dyn_cast($3.T->get())) || + if (!(PFTy = dyn_cast($3.PAT->get())) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector ParamTypes; + FTySign.makeComposite($3.S); if ($6) { for (std::vector::iterator I = $6->begin(), E = $6->end(); - I != E; ++I) + I != E; ++I) { ParamTypes.push_back((*I).V->getType()); + FTySign.add(I->S); + } + } + ParamAttrsList *PAL = 0; + if ($2 == OldCallingConv::CSRet) { + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg + Attrs.push_back(PAWI); + PAL = ParamAttrsList::get(Attrs); } bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; if (isVarArg) ParamTypes.pop_back(); - Ty = FunctionType::get($3.T->get(), ParamTypes, isVarArg); + Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, PAL); PFTy = PointerType::get(Ty); + $$.S.copy($3.S); + } else { + FTySign = $3.S; + // Get the signedness of the result type. $3 is the pointer to the + // function type so we get the 0th element to extract the function type, + // and then the 0th element again to get the result type. + $$.S.copy($3.S.get(0).get(0)); } + + $4.S.makeComposite(FTySign); Value *V = getVal(PFTy, $4); // Get the function we're calling... BasicBlock *Normal = getBBVal($10); BasicBlock *Except = getBBVal($13); // Create the call node... if (!$6) { // Has no arguments? - $$ = new InvokeInst(V, Normal, Except, std::vector()); + std::vector Args; + $$.TI = new InvokeInst(V, Normal, Except, Args.begin(), Args.end()); } else { // Has arguments? // Loop through FunctionType's arguments and ensure they are specified // correctly! @@ -2802,38 +3373,45 @@ BBTerminatorInst if (I != E || (ArgI != ArgE && !Ty->isVarArg())) error("Invalid number of parameters detected"); - $$ = new InvokeInst(V, Normal, Except, Args); + $$.TI = new InvokeInst(V, Normal, Except, Args.begin(), Args.end()); } - cast($$)->setCallingConv($2); - delete $3.T; + cast($$.TI)->setCallingConv(upgradeCallingConv($2)); + delete $3.PAT; delete $6; + lastCallingConv = OldCallingConv::C; } | Unwind { - $$ = new UnwindInst(); + $$.TI = new UnwindInst(); + $$.S.makeSignless(); } | UNREACHABLE { - $$ = new UnreachableInst(); + $$.TI = new UnreachableInst(); + $$.S.makeSignless(); } ; JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef { $$ = $1; + $3.S.copy($2.S); Constant *V = cast(getExistingValue($2.T, $3)); if (V == 0) error("May only switch on a constant pool value"); + $6.S.makeSignless(); BasicBlock* tmpBB = getBBVal($6); $$->push_back(std::make_pair(V, tmpBB)); } | IntType ConstValueRef ',' LABEL ValueRef { $$ = new std::vector >(); + $2.S.copy($1.S); Constant *V = cast(getExistingValue($1.T, $2)); if (V == 0) error("May only switch on a constant pool value"); + $5.S.makeSignless(); BasicBlock* tmpBB = getBBVal($5); $$->push_back(std::make_pair(V, tmpBB)); } @@ -2861,9 +3439,10 @@ Inst omit = true; if (omit) { $$.I = 0; - $$.S = Signless; + $$.S.makeSignless(); } else { - setValueName($2.I, $1); + ValueInfo VI; VI.V = $2.I; VI.S.copy($2.S); + setValueName(VI, $1); InsertValue($2.I); $$ = $2; } @@ -2871,15 +3450,19 @@ Inst PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes $$.P = new std::list >(); - $$.S = $1.S; - Value* tmpVal = getVal($1.T->get(), $3); + $$.S.copy($1.S); + $3.S.copy($1.S); + Value* tmpVal = getVal($1.PAT->get(), $3); + $5.S.makeSignless(); BasicBlock* tmpBB = getBBVal($5); $$.P->push_back(std::make_pair(tmpVal, tmpBB)); - delete $1.T; + delete $1.PAT; } | PHIList ',' '[' ValueRef ',' ValueRef ']' { $$ = $1; + $4.S.copy($1.S); Value* tmpVal = getVal($1.P->front().first->getType(), $4); + $6.S.makeSignless(); BasicBlock* tmpBB = getBBVal($6); $1.P->push_back(std::make_pair(tmpVal, tmpBB)); } @@ -2911,12 +3494,14 @@ OptTailCall InstVal : ArithmeticOps Types ValueRef ',' ValueRef { - const Type* Ty = $2.T->get(); - if (!Ty->isInteger() && !Ty->isFloatingPoint() && !isa(Ty)) + $3.S.copy($2.S); + $5.S.copy($2.S); + const Type* Ty = $2.PAT->get(); + if (!Ty->isInteger() && !Ty->isFloatingPoint() && !isa(Ty)) error("Arithmetic operator requires integer, FP, or packed operands"); - if (isa(Ty) && + if (isa(Ty) && ($1 == URemOp || $1 == SRemOp || $1 == FRemOp || $1 == RemOp)) - error("Remainder not supported on packed types"); + error("Remainder not supported on vector types"); // Upgrade the opcode from obsolete versions before we do anything with it. Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $2.S); Value* val1 = getVal(Ty, $3); @@ -2924,14 +3509,16 @@ InstVal $$.I = BinaryOperator::create(Opcode, val1, val2); if ($$.I == 0) error("binary operator returned null"); - $$.S = $2.S; - delete $2.T; + $$.S.copy($2.S); + delete $2.PAT; } | LogicalOps Types ValueRef ',' ValueRef { - const Type *Ty = $2.T->get(); + $3.S.copy($2.S); + $5.S.copy($2.S); + const Type *Ty = $2.PAT->get(); if (!Ty->isInteger()) { - if (!isa(Ty) || - !cast(Ty)->getElementType()->isInteger()) + if (!isa(Ty) || + !cast(Ty)->getElementType()->isInteger()) error("Logical operator requires integral operands"); } Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $2.S); @@ -2940,13 +3527,15 @@ InstVal $$.I = BinaryOperator::create(Opcode, tmpVal1, tmpVal2); if ($$.I == 0) error("binary operator returned null"); - $$.S = $2.S; - delete $2.T; + $$.S.copy($2.S); + delete $2.PAT; } | SetCondOps Types ValueRef ',' ValueRef { - const Type* Ty = $2.T->get(); - if(isa(Ty)) - error("PackedTypes currently not supported in setcc instructions"); + $3.S.copy($2.S); + $5.S.copy($2.S); + const Type* Ty = $2.PAT->get(); + if(isa(Ty)) + error("VectorTypes currently not supported in setcc instructions"); unsigned short pred; Instruction::OtherOps Opcode = getCompareOp($1, pred, Ty, $2.S); Value* tmpVal1 = getVal(Ty, $3); @@ -2954,32 +3543,36 @@ InstVal $$.I = CmpInst::create(Opcode, pred, tmpVal1, tmpVal2); if ($$.I == 0) error("binary operator returned null"); - $$.S = Unsigned; - delete $2.T; + $$.S.makeUnsigned(); + delete $2.PAT; } | ICMP IPredicates Types ValueRef ',' ValueRef { - const Type *Ty = $3.T->get(); - if (isa(Ty)) - error("PackedTypes currently not supported in icmp instructions"); + $4.S.copy($3.S); + $6.S.copy($3.S); + const Type *Ty = $3.PAT->get(); + if (isa(Ty)) + error("VectorTypes currently not supported in icmp instructions"); else if (!Ty->isInteger() && !isa(Ty)) error("icmp requires integer or pointer typed operands"); Value* tmpVal1 = getVal(Ty, $4); Value* tmpVal2 = getVal(Ty, $6); $$.I = new ICmpInst($2, tmpVal1, tmpVal2); - $$.S = Unsigned; - delete $3.T; + $$.S.makeUnsigned(); + delete $3.PAT; } | FCMP FPredicates Types ValueRef ',' ValueRef { - const Type *Ty = $3.T->get(); - if (isa(Ty)) - error("PackedTypes currently not supported in fcmp instructions"); + $4.S.copy($3.S); + $6.S.copy($3.S); + const Type *Ty = $3.PAT->get(); + if (isa(Ty)) + error("VectorTypes currently not supported in fcmp instructions"); else if (!Ty->isFloatingPoint()) error("fcmp instruction requires floating point operands"); Value* tmpVal1 = getVal(Ty, $4); Value* tmpVal2 = getVal(Ty, $6); $$.I = new FCmpInst($2, tmpVal1, tmpVal2); - $$.S = Unsigned; - delete $3.T; + $$.S.makeUnsigned(); + delete $3.PAT; } | NOT ResolvedVal { warning("Use of obsolete 'not' instruction: Replacing with 'xor"); @@ -2990,25 +3583,34 @@ InstVal $$.I = BinaryOperator::create(Instruction::Xor, $2.V, Ones); if ($$.I == 0) error("Could not create a xor instruction"); - $$.S = $2.S + $$.S.copy($2.S); } | ShiftOps ResolvedVal ',' ResolvedVal { if (!$4.V->getType()->isInteger() || cast($4.V->getType())->getBitWidth() != 8) error("Shift amount must be int8"); - if (!$2.V->getType()->isInteger()) + const Type* Ty = $2.V->getType(); + if (!Ty->isInteger()) error("Shift constant expression requires integer operand"); - $$.I = new ShiftInst(getOtherOp($1, $2.S), $2.V, $4.V); - $$.S = $2.S; + Value* ShiftAmt = 0; + if (cast(Ty)->getBitWidth() > Type::Int8Ty->getBitWidth()) + if (Constant *C = dyn_cast($4.V)) + ShiftAmt = ConstantExpr::getZExt(C, Ty); + else + ShiftAmt = new ZExtInst($4.V, Ty, makeNameUnique("shift"), CurBB); + else + ShiftAmt = $4.V; + $$.I = BinaryOperator::create(getBinaryOp($1, Ty, $2.S), $2.V, ShiftAmt); + $$.S.copy($2.S); } | CastOps ResolvedVal TO Types { - const Type *DstTy = $4.T->get(); + const Type *DstTy = $4.PAT->get(); if (!DstTy->isFirstClassType()) error("cast instruction to a non-primitive type: '" + DstTy->getDescription() + "'"); $$.I = cast(getCast($1, $2.V, $2.S, DstTy, $4.S, true)); - $$.S = $4.S; - delete $4.T; + $$.S.copy($4.S); + delete $4.PAT; } | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { if (!$2.V->getType()->isInteger() || @@ -3017,18 +3619,18 @@ InstVal if ($4.V->getType() != $6.V->getType()) error("select value types should match"); $$.I = new SelectInst($2.V, $4.V, $6.V); - $$.S = $2.S; + $$.S.copy($4.S); } | VAARG ResolvedVal ',' Types { - const Type *Ty = $4.T->get(); + const Type *Ty = $4.PAT->get(); NewVarArgs = true; $$.I = new VAArgInst($2.V, Ty); - $$.S = $4.S; - delete $4.T; + $$.S.copy($4.S); + delete $4.PAT; } | VAARG_old ResolvedVal ',' Types { const Type* ArgTy = $2.V->getType(); - const Type* DstTy = $4.T->get(); + const Type* DstTy = $4.PAT->get(); ObsoleteVarArgs = true; Function* NF = cast(CurModule.CurrentModule-> getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0)); @@ -3044,12 +3646,12 @@ InstVal CurBB->getInstList().push_back(bar); CurBB->getInstList().push_back(new StoreInst(bar, foo)); $$.I = new VAArgInst(foo, DstTy); - $$.S = $4.S; - delete $4.T; + $$.S.copy($4.S); + delete $4.PAT; } | VANEXT_old ResolvedVal ',' Types { const Type* ArgTy = $2.V->getType(); - const Type* DstTy = $4.T->get(); + const Type* DstTy = $4.PAT->get(); ObsoleteVarArgs = true; Function* NF = cast(CurModule.CurrentModule-> getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0)); @@ -3068,26 +3670,26 @@ InstVal Instruction* tmp = new VAArgInst(foo, DstTy); CurBB->getInstList().push_back(tmp); $$.I = new LoadInst(foo); - $$.S = $4.S; - delete $4.T; + $$.S.copy($4.S); + delete $4.PAT; } | EXTRACTELEMENT ResolvedVal ',' ResolvedVal { if (!ExtractElementInst::isValidOperands($2.V, $4.V)) error("Invalid extractelement operands"); $$.I = new ExtractElementInst($2.V, $4.V); - $$.S = $2.S; + $$.S.copy($2.S.get(0)); } | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal { if (!InsertElementInst::isValidOperands($2.V, $4.V, $6.V)) error("Invalid insertelement operands"); $$.I = new InsertElementInst($2.V, $4.V, $6.V); - $$.S = $2.S; + $$.S.copy($2.S); } | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal { if (!ShuffleVectorInst::isValidOperands($2.V, $4.V, $6.V)) error("Invalid shufflevector operands"); $$.I = new ShuffleVectorInst($2.V, $4.V, $6.V); - $$.S = $2.S; + $$.S.copy($2.S); } | PHI_TOK PHIList { const Type *Ty = $2.P->front().first->getType(); @@ -3102,46 +3704,66 @@ InstVal $2.P->pop_front(); } $$.I = PHI; - $$.S = $2.S; + $$.S.copy($2.S); delete $2.P; // Free the list... } - | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' { - + | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' { // Handle the short call syntax const PointerType *PFTy; const FunctionType *FTy; - if (!(PFTy = dyn_cast($3.T->get())) || + Signedness FTySign; + if (!(PFTy = dyn_cast($3.PAT->get())) || !(FTy = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector ParamTypes; + FTySign.makeComposite($3.S); if ($6) { for (std::vector::iterator I = $6->begin(), E = $6->end(); - I != E; ++I) + I != E; ++I) { ParamTypes.push_back((*I).V->getType()); + FTySign.add(I->S); + } } bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; if (isVarArg) ParamTypes.pop_back(); - const Type *RetTy = $3.T->get(); + const Type *RetTy = $3.PAT->get(); if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy) error("Functions cannot return aggregate types"); - FTy = FunctionType::get(RetTy, ParamTypes, isVarArg); + // Deal with CSRetCC + ParamAttrsList *PAL = 0; + if ($2 == OldCallingConv::CSRet) { + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg + Attrs.push_back(PAWI); + PAL = ParamAttrsList::get(Attrs); + } + + FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, PAL); PFTy = PointerType::get(FTy); + $$.S.copy($3.S); + } else { + FTySign = $3.S; + // Get the signedness of the result type. $3 is the pointer to the + // function type so we get the 0th element to extract the function type, + // and then the 0th element again to get the result type. + $$.S.copy($3.S.get(0).get(0)); } + $4.S.makeComposite(FTySign); // First upgrade any intrinsic calls. std::vector Args; if ($6) for (unsigned i = 0, e = $6->size(); i < e; ++i) Args.push_back((*$6)[i].V); - Instruction *Inst = upgradeIntrinsicCall(FTy, $4, Args); + Instruction *Inst = upgradeIntrinsicCall(FTy->getReturnType(), $4, Args); // If we got an upgraded intrinsic if (Inst) { $$.I = Inst; - $$.S = Signless; } else { // Get the function we're calling Value *V = getVal(PFTy, $4); @@ -3169,14 +3791,14 @@ InstVal } // Create the call instruction - CallInst *CI = new CallInst(V, Args); + CallInst *CI = new CallInst(V, Args.begin(), Args.end()); CI->setTailCall($1); - CI->setCallingConv($2); + CI->setCallingConv(upgradeCallingConv($2)); $$.I = CI; - $$.S = $3.S; } - delete $3.T; + delete $3.PAT; delete $6; + lastCallingConv = OldCallingConv::C; } | MemoryInst { $$ = $1; @@ -3197,39 +3819,41 @@ OptVolatile MemoryInst : MALLOC Types OptCAlign { - const Type *Ty = $2.T->get(); - $$.S = $2.S; + const Type *Ty = $2.PAT->get(); + $$.S.makeComposite($2.S); $$.I = new MallocInst(Ty, 0, $3); - delete $2.T; + delete $2.PAT; } | MALLOC Types ',' UINT ValueRef OptCAlign { - const Type *Ty = $2.T->get(); - $$.S = $2.S; + const Type *Ty = $2.PAT->get(); + $5.S.makeUnsigned(); + $$.S.makeComposite($2.S); $$.I = new MallocInst(Ty, getVal($4.T, $5), $6); - delete $2.T; + delete $2.PAT; } | ALLOCA Types OptCAlign { - const Type *Ty = $2.T->get(); - $$.S = $2.S; + const Type *Ty = $2.PAT->get(); + $$.S.makeComposite($2.S); $$.I = new AllocaInst(Ty, 0, $3); - delete $2.T; + delete $2.PAT; } | ALLOCA Types ',' UINT ValueRef OptCAlign { - const Type *Ty = $2.T->get(); - $$.S = $2.S; + const Type *Ty = $2.PAT->get(); + $5.S.makeUnsigned(); + $$.S.makeComposite($4.S); $$.I = new AllocaInst(Ty, getVal($4.T, $5), $6); - delete $2.T; + delete $2.PAT; } | FREE ResolvedVal { const Type *PTy = $2.V->getType(); if (!isa(PTy)) error("Trying to free nonpointer type '" + PTy->getDescription() + "'"); $$.I = new FreeInst($2.V); - $$.S = Signless; + $$.S.makeSignless(); } | OptVolatile LOAD Types ValueRef { - const Type* Ty = $3.T->get(); - $$.S = $3.S; + const Type* Ty = $3.PAT->get(); + $4.S.copy($3.S); if (!isa(Ty)) error("Can't load from nonpointer type: " + Ty->getDescription()); if (!cast(Ty)->getElementType()->isFirstClassType()) @@ -3237,34 +3861,49 @@ MemoryInst Ty->getDescription()); Value* tmpVal = getVal(Ty, $4); $$.I = new LoadInst(tmpVal, "", $1); - delete $3.T; + $$.S.copy($3.S.get(0)); + delete $3.PAT; } | OptVolatile STORE ResolvedVal ',' Types ValueRef { - const PointerType *PTy = dyn_cast($5.T->get()); + $6.S.copy($5.S); + const PointerType *PTy = dyn_cast($5.PAT->get()); if (!PTy) error("Can't store to a nonpointer type: " + - $5.T->get()->getDescription()); + $5.PAT->get()->getDescription()); const Type *ElTy = PTy->getElementType(); - if (ElTy != $3.V->getType()) - error("Can't store '" + $3.V->getType()->getDescription() + - "' into space of type '" + ElTy->getDescription() + "'"); + Value *StoreVal = $3.V; Value* tmpVal = getVal(PTy, $6); - $$.I = new StoreInst($3.V, tmpVal, $1); - $$.S = Signless; - delete $5.T; + if (ElTy != $3.V->getType()) { + StoreVal = handleSRetFuncTypeMerge($3.V, ElTy); + if (!StoreVal) + error("Can't store '" + $3.V->getType()->getDescription() + + "' into space of type '" + ElTy->getDescription() + "'"); + else { + PTy = PointerType::get(StoreVal->getType()); + if (Constant *C = dyn_cast(tmpVal)) + tmpVal = ConstantExpr::getBitCast(C, PTy); + else + tmpVal = new BitCastInst(tmpVal, PTy, "upgrd.cast", CurBB); + } + } + $$.I = new StoreInst(StoreVal, tmpVal, $1); + $$.S.makeSignless(); + delete $5.PAT; } | GETELEMENTPTR Types ValueRef IndexList { - const Type* Ty = $2.T->get(); + $3.S.copy($2.S); + const Type* Ty = $2.PAT->get(); if (!isa(Ty)) error("getelementptr insn requires pointer operand"); std::vector VIndices; - upgradeGEPIndices(Ty, $4, VIndices); + upgradeGEPInstIndices(Ty, $4, VIndices); Value* tmpVal = getVal(Ty, $3); - $$.I = new GetElementPtrInst(tmpVal, VIndices); - $$.S = Signless; - delete $2.T; + $$.I = new GetElementPtrInst(tmpVal, VIndices.begin(), VIndices.end()); + ValueInfo VI; VI.V = tmpVal; VI.S.copy($2.S); + $$.S.copy(getElementSign(VI, VIndices)); + delete $2.PAT; delete $4; }; @@ -3274,7 +3913,7 @@ MemoryInst int yyerror(const char *ErrorMsg) { std::string where = std::string((CurFilename == "-") ? std::string("") : CurFilename) - + ":" + llvm::utostr((unsigned) Upgradelineno-1) + ": "; + + ":" + llvm::utostr((unsigned) Upgradelineno) + ": "; std::string errMsg = where + "error: " + std::string(ErrorMsg); if (yychar != YYEMPTY && yychar != 0) errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) + @@ -3287,7 +3926,7 @@ int yyerror(const char *ErrorMsg) { void warning(const std::string& ErrorMsg) { std::string where = std::string((CurFilename == "-") ? std::string("") : CurFilename) - + ":" + llvm::utostr((unsigned) Upgradelineno-1) + ": "; + + ":" + llvm::utostr((unsigned) Upgradelineno) + ": "; std::string errMsg = where + "warning: " + std::string(ErrorMsg); if (yychar != YYEMPTY && yychar != 0) errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +