X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-upgrade%2FUpgradeParser.y;h=0173b44dddcceb3c6b8c773498be5905bba071de;hb=84867442146b6a860ba01e65b3b225cba56cb283;hp=e73141c9fa1d977c9c1c03164a89c28776502c76;hpb=e7c326b3f886d3cb97e93344a5ad076536046a29;p=oota-llvm.git diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y index e73141c9fa1..0173b44dddc 100644 --- a/tools/llvm-upgrade/UpgradeParser.y +++ b/tools/llvm-upgrade/UpgradeParser.y @@ -17,12 +17,14 @@ #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" #include "llvm/Module.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 @@ -66,7 +68,7 @@ static GlobalVariable *CurGV; // typedef std::vector ValueList; // Numbered defs -typedef std::pair RenameMapKey; +typedef std::pair RenameMapKey; typedef std::map RenameMapType; static void @@ -77,7 +79,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 +139,9 @@ static struct PerModuleInfo { Values.clear(); // Clear out function local definitions Types.clear(); + TypeSigns.clear(); + NamedTypeSigns.clear(); + NamedValueSigns.clear(); CurrentModule = 0; } @@ -207,6 +215,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 +258,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 +272,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,31 +289,136 @@ 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. -bool FuncTysDifferOnlyBySRet(const FunctionType *F1, - const FunctionType *F2) { +static bool FuncTysDifferOnlyBySRet(const FunctionType *F1, + const FunctionType *F2) { if (F1->getReturnType() != F2->getReturnType() || - F1->getNumParams() != F2->getNumParams() || - F1->getParamAttrs(0) != F2->getParamAttrs(0)) + F1->getNumParams() != F2->getNumParams()) + return false; + ParamAttrsList PAL1; + if (F1->getParamAttrs()) + PAL1 = *F1->getParamAttrs(); + ParamAttrsList PAL2; + if (F2->getParamAttrs()) + PAL2 = *F2->getParamAttrs(); + if (PAL1.getParamAttrs(0) != PAL2.getParamAttrs(0)) return false; - unsigned SRetMask = ~unsigned(FunctionType::StructRetAttribute); + unsigned SRetMask = ~unsigned(ParamAttr::StructRet); for (unsigned i = 0; i < F1->getNumParams(); ++i) { if (F1->getParamType(i) != F2->getParamType(i) || - unsigned(F1->getParamAttrs(i+1)) & SRetMask != - unsigned(F2->getParamAttrs(i+1)) & SRetMask) + 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 returns V if it occurs and 0 otherwise. +// situation and bitcasts the function to the correct type. static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) { // Handle degenerate cases if (!V) @@ -297,23 +426,23 @@ static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) { if (V->getType() == Ty) return V; - Value* Result = 0; 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)) - if (FT2->paramHasAttr(1, FunctionType::StructRetAttribute)) - Result = V; + 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)) - Result = ConstantExpr::getBitCast(C, PF1); + return ConstantExpr::getBitCast(C, PF1); else - Result = new BitCastInst(V, PF1, "upgrd.cast", CurBB); + return new BitCastInst(V, PF1, "upgrd.cast", CurBB); + } + } - return Result; + return 0; } // getExistingValue - Look up the value specified by the provided type and @@ -349,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); @@ -359,10 +487,12 @@ static Value *getExistingValue(const Type *Ty, const ValID &D) { if (I != CurFun.RenameMap.end()) LookupName = I->second; else - LookupName = Name; + LookupName = D.Name; ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable(); V = SymTab.lookup(LookupName); - V = handleSRetFuncTypeMerge(V, Ty); + 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); @@ -370,9 +500,11 @@ static Value *getExistingValue(const Type *Ty, const ValID &D) { if (I != CurModule.RenameMap.end()) LookupName = I->second; else - LookupName = Name; + LookupName = D.Name; V = CurModule.CurrentModule->getValueSymbolTable().lookup(LookupName); - V = handleSRetFuncTypeMerge(V, Ty); + if (V && V->getType() != Ty) + V = handleSRetFuncTypeMerge(V, Ty); + assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type"); } if (!V) return 0; @@ -475,6 +607,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. @@ -497,11 +637,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(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; } @@ -606,31 +754,38 @@ 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); } } -/// @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; -} - /// 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. @@ -686,12 +841,12 @@ static inline bool TypeHasInteger(const Type *Ty) { // 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; } @@ -704,13 +859,13 @@ static void setValueName(Value *V, char *NameStr) { if (Existing) { // 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->getType() && + 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->getType()->getDescription() + "'"); + V.V->getType()->getDescription() + "'"); return; } // In LLVM 2.0 we don't allow names to be re-used for any values in a @@ -724,13 +879,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); } } @@ -739,7 +894,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"); @@ -759,6 +915,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 @@ -784,13 +941,7 @@ ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, // 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 @@ -801,7 +952,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 @@ -814,6 +965,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; } @@ -824,21 +977,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); @@ -848,7 +1006,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; } @@ -856,11 +1014,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; @@ -892,7 +1050,7 @@ namespace { OpaqueType *UpRefTy; UpRefRecord(unsigned NL, OpaqueType *URTy) - : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) {} + : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) { } }; } @@ -906,7 +1064,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; @@ -922,10 +1080,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; @@ -936,8 +1095,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"); @@ -950,14 +1110,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) { @@ -972,7 +1233,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 : @@ -988,12 +1249,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; } @@ -1004,13 +1265,13 @@ 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; } @@ -1021,7 +1282,7 @@ getBinaryOp(BinaryOps op, const Type *Ty, Signedness Sign) { case AShrOp : return Instruction::AShr; case ShlOp : return Instruction::Shl; case ShrOp : - if (Sign == Signed) + if (Sign.isSigned()) return Instruction::AShr; return Instruction::LShr; case AndOp : return Instruction::And; @@ -1032,8 +1293,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"); @@ -1113,7 +1374,7 @@ 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; @@ -1131,8 +1392,8 @@ getOtherOp(OtherOps op, Signedness Sign) { } 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) { @@ -1169,7 +1430,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"); @@ -1197,35 +1459,71 @@ 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 { - 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); - } 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); + 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 'b': + if (Name.length() == 14 && !memcmp(&Name[5], "bswap.i", 7)) { + const Type* ArgTy = Args[0]->getType(); + Name += ".i" + utostr(cast(ArgTy)->getBitWidth()); + Function *F = cast( + CurModule.CurrentModule->getOrInsertFunction(Name, RetTy, ArgTy, + (void*)0)); + return new CallInst(F, Args[0]); + } + break; + case 'c': + if ((Name.length() <= 14 && !memcmp(&Name[5], "ctpop.i", 7)) || + (Name.length() <= 13 && !memcmp(&Name[5], "ctlz.i", 6)) || + (Name.length() <= 13 && !memcmp(&Name[5], "cttz.i", 6))) { + // These intrinsics changed their result type. + const Type* ArgTy = Args[0]->getType(); + Function *OldF = CurModule.CurrentModule->getFunction(Name); + if (OldF) + OldF->setName("upgrd.rm." + Name); + + Function *NewF = cast( + CurModule.CurrentModule->getOrInsertFunction(Name, Type::Int32Ty, + ArgTy, (void*)0)); + + Instruction *Call = new CallInst(NewF, Args[0], "", CurBB); + return CastInst::createIntegerCast(Call, RetTy, false); + } + 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[0], Args.size()); + } 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[0], Args.size()); + } } } return 0; @@ -1261,7 +1559,7 @@ const Type* upgradeGEPIndices(const Type* PTy, // 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 (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) { if (CIndices) Index = ConstantExpr::getCast(Instruction::ZExt, cast(Index), Type::Int64Ty); @@ -1277,7 +1575,7 @@ const Type* upgradeGEPIndices(const Type* PTy, } const Type *IdxTy = - GetElementPtrInst::getIndexedType(PTy, VIndices, true); + GetElementPtrInst::getIndexedType(PTy, &VIndices[0], VIndices.size(), true); if (!IdxTy) error("Index list invalid for constant getelementptr"); return IdxTy; @@ -1446,7 +1744,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; @@ -1759,7 +2057,7 @@ TypesV : Types | VOID { $$.PAT = new PATypeHolder($1.T); - $$.S = Signless; + $$.S.makeSignless(); } ; @@ -1767,7 +2065,7 @@ UpRTypesV : UpRTypes | VOID { $$.PAT = new PATypeHolder($1.T); - $$.S = Signless; + $$.S.makeSignless(); } ; @@ -1788,16 +2086,16 @@ PrimType UpRTypes : PrimType { $$.PAT = new PATypeHolder($1.T); - $$.S = $1.S; + $$.S.copy($1.S); } | OPAQUE { $$.PAT = new PATypeHolder(OpaqueType::get()); - $$.S = Signless; + $$.S.makeSignless(); } | SymbolicValueRef { // Named types are also simple types... + $$.S.copy(getTypeSign($1)); const Type* tmp = getType($1); $$.PAT = new PATypeHolder(tmp); - $$.S = Signless; // FIXME: what if its signed? } | '\\' EUINT64VAL { // Type UpReference if ($2 > (uint64_t)~0U) @@ -1805,78 +2103,84 @@ UpRTypes OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder UpRefs.push_back(UpRefRecord((unsigned)$2, OT)); // Add to vector... $$.PAT = new PATypeHolder(OT); - $$.S = Signless; + $$.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->PAT->get()); + $$.S.add(I->S); } - FunctionType::ParamAttrsList ParamAttrs; bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); - $$.PAT = new PATypeHolder( - HandleUpRefs(FunctionType::get($1.PAT->get(), Params, isVarArg, - ParamAttrs))); - $$.S = $1.S; - delete $1.PAT; // Delete the return type handle + const FunctionType *FTy = + FunctionType::get($1.PAT->get(), Params, isVarArg, 0); + + $$.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? + $$.S.makeComposite($4.S); $$.PAT = new PATypeHolder(HandleUpRefs(ArrayType::get($4.PAT->get(), - (unsigned)$2))); - $$.S = $4.S; + (unsigned)$2), $$.S)); delete $4.PAT; } - | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array 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 PackedType must be integer or floating point"); - if (!isPowerOf2_32($2)) - error("PackedType length should be a power of 2"); - $$.PAT = new PATypeHolder(HandleUpRefs(PackedType::get(ElemTy, - (unsigned)$2))); - $$.S = $4.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) + E = $2->end(); I != E; ++I) { Elements.push_back(I->PAT->get()); - $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); - $$.S = Signless; + $$.S.add(I->S); + } + $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements), $$.S)); delete $2; } | '{' '}' { // Empty structure type? $$.PAT = new PATypeHolder(StructType::get(std::vector())); - $$.S = Signless; + $$.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->PAT->get()); + $$.S.add(I->S); delete I->PAT; } - $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true))); - $$.S = Signless; + $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true), + $$.S)); delete $3; } | '<' '{' '}' '>' { // Empty packed structure type? $$.PAT = new PATypeHolder(StructType::get(std::vector(),true)); - $$.S = Signless; + $$.S.makeComposite(); } | UpRTypes '*' { // Pointer type? if ($1.PAT->get() == Type::LabelTy) error("Cannot form a pointer to a basic block"); - $$.PAT = new PATypeHolder(HandleUpRefs(PointerType::get($1.PAT->get()))); - $$.S = $1.S; + $$.S.makeComposite($1.S); + $$.PAT = new PATypeHolder(HandleUpRefs(PointerType::get($1.PAT->get()), + $$.S)); delete $1.PAT; } ; @@ -1900,14 +2204,14 @@ ArgTypeListI | TypeListI ',' DOTDOTDOT { PATypeInfo VoidTI; VoidTI.PAT = new PATypeHolder(Type::VoidTy); - VoidTI.S = Signless; + VoidTI.S.makeSignless(); ($$=$1)->push_back(VoidTI); } | DOTDOTDOT { $$ = new std::list(); PATypeInfo VoidTI; VoidTI.PAT = new PATypeHolder(Type::VoidTy); - VoidTI.S = Signless; + VoidTI.S.makeSignless(); $$->push_back(VoidTI); } | /*empty*/ { @@ -1948,7 +2252,7 @@ ConstVal Elems.push_back(C); } $$.C = ConstantArray::get(ATy, Elems); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; delete $3; } @@ -1962,7 +2266,7 @@ ConstVal 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; + $$.S.copy($1.S); delete $1.PAT; } | Types 'c' STRINGCONSTANT { @@ -1985,11 +2289,11 @@ ConstVal Vals.push_back(ConstantInt::get(ETy, *C)); free($3); $$.C = ConstantArray::get(ATy, Vals); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; } | Types '<' ConstVector '>' { // Nonempty unsized arr - const PackedType *PTy = dyn_cast($1.PAT->get()); + const VectorType *PTy = dyn_cast($1.PAT->get()); if (PTy == 0) error("Cannot make packed constant with type: '" + $1.PAT->get()->getDescription() + "'"); @@ -2011,8 +2315,8 @@ ConstVal ValTy->getDescription() + "'"); Elems.push_back(C); } - $$.C = ConstantPacked::get(PTy, Elems); - $$.S = $1.S; + $$.C = ConstantVector::get(PTy, Elems); + $$.S.copy($1.S); delete $1.PAT; delete $3; } @@ -2034,7 +2338,7 @@ ConstVal Fields.push_back(C); } $$.C = ConstantStruct::get(STy, Fields); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; delete $3; } @@ -2046,7 +2350,7 @@ ConstVal if (STy->getNumContainedTypes() != 0) error("Illegal number of initializers for structure type"); $$.C = ConstantStruct::get(STy, std::vector()); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; } | Types '<' '{' ConstVector '}' '>' { @@ -2067,7 +2371,7 @@ ConstVal Fields.push_back(C); } $$.C = ConstantStruct::get(STy, Fields); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; delete $4; } @@ -2079,7 +2383,7 @@ ConstVal if (STy->getNumContainedTypes() != 0) error("Illegal number of initializers for packed structure type"); $$.C = ConstantStruct::get(STy, std::vector()); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; } | Types NULL_TOK { @@ -2088,12 +2392,12 @@ ConstVal error("Cannot make null pointer constant with type: '" + $1.PAT->get()->getDescription() + "'"); $$.C = ConstantPointerNull::get(PTy); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; } | Types UNDEF { $$.C = UndefValue::get($1.PAT->get()); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; } | Types SymbolicValueRef { @@ -2111,6 +2415,7 @@ ConstVal // Function *SavedCurFn = CurFun.CurrentFunction; CurFun.CurrentFunction = 0; + $2.S.copy($1.S); Value *V = getExistingValue(Ty, $2); CurFun.CurrentFunction = SavedCurFn; @@ -2151,14 +2456,14 @@ ConstVal } } $$.C = cast(V); - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; // Free the type handle } | Types ConstExpr { if ($1.PAT->get() != $2.C->getType()) error("Mismatched types for constant expression"); $$ = $2; - $$.S = $1.S; + $$.S.copy($1.S); delete $1.PAT; } | Types ZEROINITIALIZER { @@ -2166,7 +2471,7 @@ ConstVal 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; + $$.S.copy($1.S); delete $1.PAT; } | SIntType EINT64VAL { // integral constants @@ -2174,28 +2479,28 @@ ConstVal 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)) error("Floating point constant invalid for type"); $$.C = ConstantFP::get($1.T, $2); - $$.S = Signless; + $$.S.makeSignless(); } ; @@ -2203,8 +2508,8 @@ ConstExpr : CastOps '(' ConstVal TO Types ')' { const Type* SrcTy = $3.C->getType(); const Type* DstTy = $5.PAT->get(); - Signedness SrcSign = $3.S; - Signedness DstSign = $5.S; + Signedness SrcSign($3.S); + Signedness DstSign($5.S); if (!SrcTy->isFirstClassType()) error("cast constant expression from a non-primitive type: '" + SrcTy->getDescription() + "'"); @@ -2212,7 +2517,7 @@ ConstExpr error("cast constant expression to a non-primitive type: '" + DstTy->getDescription() + "'"); $$.C = cast(getCast($1, $3.C, SrcSign, DstTy, DstSign)); - $$.S = DstSign; + $$.S.copy(DstSign); delete $5.PAT; } | GETELEMENTPTR '(' ConstVal IndexList ')' { @@ -2225,8 +2530,8 @@ ConstExpr upgradeGEPIndices($3.C->getType(), $4, VIndices, &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() || @@ -2235,7 +2540,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(); @@ -2263,20 +2568,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(); @@ -2285,19 +2590,19 @@ 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() || @@ -2308,25 +2613,25 @@ ConstExpr error("Shift constant expression requires integer operand"); Constant *ShiftAmt = ConstantExpr::getZExt($5.C, Ty); $$.C = ConstantExpr::get(getBinaryOp($1, Ty, $3.S), $3.C, ShiftAmt); - $$.S = $3.S; + $$.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); } ; @@ -2395,13 +2700,13 @@ ConstPool // If types are not resolved eagerly, then the two types will not be // determined to be the same type! // - const Type* Ty = $4.PAT->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.PAT; } @@ -2412,20 +2717,22 @@ 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.PAT->get(); - CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, Ty, 0); + 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.PAT->get(); - CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, Ty, 0); + CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, Ty, 0, + $5.S); delete $5.PAT; } GlobalVarAttributes { CurGV = 0; @@ -2433,7 +2740,8 @@ ConstPool | ConstPool OptAssign EXTERN_WEAK GlobalType Types { const Type *Ty = $5.PAT->get(); CurGV = - ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, Ty, 0); + ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, Ty, 0, + $5.S); delete $5.PAT; } GlobalVarAttributes { CurGV = 0; @@ -2543,14 +2851,14 @@ ArgList $$ = $1; PATypeInfo VoidTI; VoidTI.PAT = new PATypeHolder(Type::VoidTy); - VoidTI.S = Signless; + VoidTI.S.makeSignless(); $$->push_back(std::pair(VoidTI, 0)); } | DOTDOTDOT { $$ = new std::vector >(); PATypeInfo VoidTI; VoidTI.PAT = new PATypeHolder(Type::VoidTy); - VoidTI.S = Signless; + VoidTI.S.makeSignless(); $$->push_back(std::pair(VoidTI, 0)); } | /* empty */ { $$ = 0; } @@ -2567,6 +2875,8 @@ FunctionHeaderH if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy) error("LLVM functions cannot return aggregate types"); + Signedness FTySign; + FTySign.makeComposite($2.S); std::vector ParamTyList; // In LLVM 2.0 the signatures of three varargs intrinsics changed to take @@ -2582,6 +2892,7 @@ FunctionHeaderH I = $5->begin(), E = $5->end(); I != E; ++I) { const Type *Ty = I->first.PAT->get(); ParamTyList.push_back(Ty); + FTySign.add(I->first.S); } } @@ -2591,14 +2902,15 @@ FunctionHeaderH // Convert the CSRet calling convention into the corresponding parameter // attribute. - FunctionType::ParamAttrsList ParamAttrs; + ParamAttrsList *ParamAttrs = 0; if ($1 == OldCallingConv::CSRet) { - ParamAttrs.push_back(FunctionType::NoAttributeSet); // result - ParamAttrs.push_back(FunctionType::StructRetAttribute); // first arg + ParamAttrs = new ParamAttrsList(); + ParamAttrs->addAttributes(0, ParamAttr::None); // result + ParamAttrs->addAttributes(1, ParamAttr::StructRet); // first arg } - const FunctionType *FT = FunctionType::get(RetTy, ParamTyList, isVarArg, - ParamAttrs); + const FunctionType *FT = + FunctionType::get(RetTy, ParamTyList, isVarArg, ParamAttrs); const PointerType *PFT = PointerType::get(FT); delete $2.PAT; @@ -2608,6 +2920,7 @@ FunctionHeaderH } else { ID = ValID::create((int)CurModule.Values[PFT].size()); } + ID.S.makeComposite(FTySign); Function *Fn = 0; Module* M = CurModule.CurrentModule; @@ -2626,10 +2939,26 @@ FunctionHeaderH if (Conflict && PFT == Conflict->getType()) { if (!CurFun.isDeclare && !Conflict->isDeclaration()) { // We have two function definitions that conflict, same type, same - // name. This wasn't allowed in 1.9, its not allowed here either - error("Redefinition of function '" + FunctionName + "' of type '" + - PFT->getDescription() + "'"); - + // 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. @@ -2649,31 +2978,29 @@ FunctionHeaderH // 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 renamed the Conflict. + // We can safely rename the Conflict. + RenameMapKey Key = + makeRenameMapKey(Conflict->getName(), Conflict->getType(), + CurModule.NamedValueSigns[Conflict->getName()]); Conflict->setName(makeNameUnique(Conflict->getName())); - RenameMapKey Key = std::make_pair(FunctionName,Conflict->getType()); CurModule.RenameMap[Key] = Conflict->getName(); Fn = new Function(FT, CurFun.Linkage, FunctionName, M); InsertValue(Fn, CurModule.Values); - } else if (CurFun.Linkage == GlobalValue::InternalLinkage) { - // We can safely rename the function we're defining - std::string NewName = makeNameUnique(FunctionName); - Fn = new Function(FT, CurFun.Linkage, NewName, M); - InsertValue(Fn, CurModule.Values); - RenameMapKey Key = std::make_pair(FunctionName,PFT); - CurModule.RenameMap[Key] = NewName; - } else { + } else { // We can't quietly rename either of these things, but we must - // rename one of them. Generate a warning about the renaming and - // elect to rename the thing we're now defining. + // 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); - warning("Renaming function '" + FunctionName + "' as '" + NewName + - "' may cause linkage errors"); + 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 = std::make_pair(FunctionName,PFT); + 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); @@ -2710,7 +3037,8 @@ FunctionHeaderH std::vector >::iterator E = $5->end(); for ( ; I != E && ArgIt != ArgEnd; ++I, ++ArgIt) { delete I->first.PAT; // Delete the typeholder... - setValueName(ArgIt, I->second); // Insert arg into symtab... + 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 @@ -2723,7 +3051,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 @@ -2767,20 +3095,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; @@ -2793,11 +3127,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); @@ -2810,12 +3145,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 @@ -2830,8 +3164,9 @@ ValueRef ResolvedVal : Types ValueRef { const Type *Ty = $1.PAT->get(); - $$.S = $1.S; + $2.S.copy($1.S); $$.V = getVal(Ty, $2); + $$.S.copy($1.S); delete $1.PAT; } ; @@ -2850,9 +3185,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; } @@ -2865,7 +3201,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. @@ -2888,26 +3224,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) { @@ -2919,42 +3265,59 @@ 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.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); + } } - FunctionType::ParamAttrsList ParamAttrs; + ParamAttrsList *ParamAttrs = 0; if ($2 == OldCallingConv::CSRet) { - ParamAttrs.push_back(FunctionType::NoAttributeSet); - ParamAttrs.push_back(FunctionType::StructRetAttribute); + ParamAttrs = new ParamAttrsList(); + ParamAttrs->addAttributes(0, ParamAttr::None); // Function result + ParamAttrs->addAttributes(1, ParamAttr::StructRet); // first param } bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; if (isVarArg) ParamTypes.pop_back(); Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, ParamAttrs); 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()); + $$.TI = new InvokeInst(V, Normal, Except, 0, 0); } else { // Has arguments? // Loop through FunctionType's arguments and ensure they are specified // correctly! @@ -2974,38 +3337,44 @@ 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[0], Args.size()); } - cast($$)->setCallingConv(upgradeCallingConv($2)); + cast($$.TI)->setCallingConv(upgradeCallingConv($2)); delete $3.PAT; delete $6; } | 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)); } @@ -3033,9 +3402,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; } @@ -3043,15 +3413,19 @@ Inst PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes $$.P = new std::list >(); - $$.S = $1.S; + $$.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.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)); } @@ -3083,12 +3457,14 @@ OptTailCall InstVal : ArithmeticOps Types ValueRef ',' ValueRef { + $3.S.copy($2.S); + $5.S.copy($2.S); const Type* Ty = $2.PAT->get(); - if (!Ty->isInteger() && !Ty->isFloatingPoint() && !isa(Ty)) + 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); @@ -3096,14 +3472,16 @@ InstVal $$.I = BinaryOperator::create(Opcode, val1, val2); if ($$.I == 0) error("binary operator returned null"); - $$.S = $2.S; + $$.S.copy($2.S); delete $2.PAT; } | LogicalOps Types ValueRef ',' ValueRef { + $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); @@ -3112,13 +3490,15 @@ InstVal $$.I = BinaryOperator::create(Opcode, tmpVal1, tmpVal2); if ($$.I == 0) error("binary operator returned null"); - $$.S = $2.S; + $$.S.copy($2.S); delete $2.PAT; } | SetCondOps Types ValueRef ',' ValueRef { + $3.S.copy($2.S); + $5.S.copy($2.S); const Type* Ty = $2.PAT->get(); - if(isa(Ty)) - error("PackedTypes currently not supported in setcc instructions"); + 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); @@ -3126,31 +3506,35 @@ InstVal $$.I = CmpInst::create(Opcode, pred, tmpVal1, tmpVal2); if ($$.I == 0) error("binary operator returned null"); - $$.S = Unsigned; + $$.S.makeUnsigned(); delete $2.PAT; } | ICMP IPredicates Types ValueRef ',' ValueRef { + $4.S.copy($3.S); + $6.S.copy($3.S); const Type *Ty = $3.PAT->get(); - if (isa(Ty)) - error("PackedTypes currently not supported in icmp instructions"); + 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; + $$.S.makeUnsigned(); delete $3.PAT; } | FCMP FPredicates Types ValueRef ',' ValueRef { + $4.S.copy($3.S); + $6.S.copy($3.S); const Type *Ty = $3.PAT->get(); - if (isa(Ty)) - error("PackedTypes currently not supported in fcmp instructions"); + 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; + $$.S.makeUnsigned(); delete $3.PAT; } | NOT ResolvedVal { @@ -3162,7 +3546,7 @@ 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() || @@ -3180,7 +3564,7 @@ InstVal else ShiftAmt = $4.V; $$.I = BinaryOperator::create(getBinaryOp($1, Ty, $2.S), $2.V, ShiftAmt); - $$.S = $2.S; + $$.S.copy($2.S); } | CastOps ResolvedVal TO Types { const Type *DstTy = $4.PAT->get(); @@ -3188,7 +3572,7 @@ InstVal 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; + $$.S.copy($4.S); delete $4.PAT; } | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { @@ -3198,13 +3582,13 @@ 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.PAT->get(); NewVarArgs = true; $$.I = new VAArgInst($2.V, Ty); - $$.S = $4.S; + $$.S.copy($4.S); delete $4.PAT; } | VAARG_old ResolvedVal ',' Types { @@ -3225,7 +3609,7 @@ InstVal CurBB->getInstList().push_back(bar); CurBB->getInstList().push_back(new StoreInst(bar, foo)); $$.I = new VAArgInst(foo, DstTy); - $$.S = $4.S; + $$.S.copy($4.S); delete $4.PAT; } | VANEXT_old ResolvedVal ',' Types { @@ -3249,26 +3633,26 @@ InstVal Instruction* tmp = new VAArgInst(foo, DstTy); CurBB->getInstList().push_back(tmp); $$.I = new LoadInst(foo); - $$.S = $4.S; + $$.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(); @@ -3283,29 +3667,27 @@ 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; + 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); + } } - FunctionType::ParamAttrsList ParamAttrs; - if ($2 == OldCallingConv::CSRet) { - ParamAttrs.push_back(FunctionType::NoAttributeSet); - ParamAttrs.push_back(FunctionType::StructRetAttribute); - } bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; if (isVarArg) ParamTypes.pop_back(); @@ -3313,21 +3695,36 @@ InstVal if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy) error("Functions cannot return aggregate types"); + // Deal with CSRetCC + ParamAttrsList *ParamAttrs = 0; + if ($2 == OldCallingConv::CSRet) { + ParamAttrs = new ParamAttrsList(); + ParamAttrs->addAttributes(0, ParamAttr::None); // function result + ParamAttrs->addAttributes(1, ParamAttr::StructRet); // first parameter + } + FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, ParamAttrs); 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); @@ -3355,11 +3752,10 @@ InstVal } // Create the call instruction - CallInst *CI = new CallInst(V, Args); + CallInst *CI = new CallInst(V, &Args[0], Args.size()); CI->setTailCall($1); CI->setCallingConv(upgradeCallingConv($2)); $$.I = CI; - $$.S = $3.S; } delete $3.PAT; delete $6; @@ -3384,25 +3780,27 @@ OptVolatile MemoryInst : MALLOC Types OptCAlign { const Type *Ty = $2.PAT->get(); - $$.S = $2.S; + $$.S.makeComposite($2.S); $$.I = new MallocInst(Ty, 0, $3); delete $2.PAT; } | MALLOC Types ',' UINT ValueRef OptCAlign { const Type *Ty = $2.PAT->get(); - $$.S = $2.S; + $5.S.makeUnsigned(); + $$.S.makeComposite($2.S); $$.I = new MallocInst(Ty, getVal($4.T, $5), $6); delete $2.PAT; } | ALLOCA Types OptCAlign { const Type *Ty = $2.PAT->get(); - $$.S = $2.S; + $$.S.makeComposite($2.S); $$.I = new AllocaInst(Ty, 0, $3); delete $2.PAT; } | ALLOCA Types ',' UINT ValueRef OptCAlign { const Type *Ty = $2.PAT->get(); - $$.S = $2.S; + $5.S.makeUnsigned(); + $$.S.makeComposite($4.S); $$.I = new AllocaInst(Ty, getVal($4.T, $5), $6); delete $2.PAT; } @@ -3411,11 +3809,11 @@ MemoryInst 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.PAT->get(); - $$.S = $3.S; + $4.S.copy($3.S); if (!isa(Ty)) error("Can't load from nonpointer type: " + Ty->getDescription()); if (!cast(Ty)->getElementType()->isFirstClassType()) @@ -3423,9 +3821,11 @@ MemoryInst Ty->getDescription()); Value* tmpVal = getVal(Ty, $4); $$.I = new LoadInst(tmpVal, "", $1); + $$.S.copy($3.S.get(0)); delete $3.PAT; } | OptVolatile STORE ResolvedVal ',' Types ValueRef { + $6.S.copy($5.S); const PointerType *PTy = dyn_cast($5.PAT->get()); if (!PTy) error("Can't store to a nonpointer type: " + @@ -3447,10 +3847,11 @@ MemoryInst } } $$.I = new StoreInst(StoreVal, tmpVal, $1); - $$.S = Signless; + $$.S.makeSignless(); delete $5.PAT; } | GETELEMENTPTR Types ValueRef IndexList { + $3.S.copy($2.S); const Type* Ty = $2.PAT->get(); if (!isa(Ty)) error("getelementptr insn requires pointer operand"); @@ -3459,8 +3860,9 @@ MemoryInst upgradeGEPIndices(Ty, $4, VIndices); Value* tmpVal = getVal(Ty, $3); - $$.I = new GetElementPtrInst(tmpVal, VIndices); - $$.S = Signless; + $$.I = new GetElementPtrInst(tmpVal, &VIndices[0], VIndices.size()); + ValueInfo VI; VI.V = tmpVal; VI.S.copy($2.S); + $$.S.copy(getElementSign(VI, VIndices)); delete $2.PAT; delete $4; };