mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-20 00:43:48 +00:00
For PR1146:
Make ParamAttrsList objects unique. You can no longer directly create or destroy them but instead must go through the ParamAttrsList::get() interface. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36327 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3b87d6a7b5
commit
4f859aa532
@ -148,7 +148,6 @@ class FunctionType : public DerivedType {
|
||||
bool IsVarArgs, ParamAttrsList *Attrs = 0);
|
||||
|
||||
public:
|
||||
virtual ~FunctionType();
|
||||
/// FunctionType::get - This static method is the primary way of constructing
|
||||
/// a FunctionType.
|
||||
///
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define LLVM_PARAMETER_ATTRIBUTES_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -39,6 +40,17 @@ enum Attributes {
|
||||
|
||||
}
|
||||
|
||||
/// This is just a pair of values to associate a set of parameter attributes
|
||||
/// with a parameter index.
|
||||
/// @brief ParameterAttributes with a parameter index.
|
||||
struct ParamAttrsWithIndex {
|
||||
uint16_t attrs; ///< The attributes that are set, |'d together
|
||||
uint16_t index; ///< Index of the parameter for which the attributes apply
|
||||
};
|
||||
|
||||
/// @brief A vector of attribute/index pairs.
|
||||
typedef SmallVector<ParamAttrsWithIndex,4> ParamAttrsVector;
|
||||
|
||||
typedef ParamAttr::Attributes ParameterAttributes;
|
||||
|
||||
/// This class is used by Function and CallInst to represent the set of
|
||||
@ -50,38 +62,27 @@ typedef ParamAttr::Attributes ParameterAttributes;
|
||||
/// a string of mnemonics suitable for LLVM Assembly output. Various accessors
|
||||
/// are provided to obtain information about the attributes.
|
||||
/// @brief A List of ParameterAttributes.
|
||||
class ParamAttrsList {
|
||||
//void operator=(const ParamAttrsList &); // Do not implement
|
||||
//ParamAttrsList(const ParamAttrsList &); // Do not implement
|
||||
|
||||
/// @name Types
|
||||
/// @{
|
||||
public:
|
||||
/// This is an internal structure used to associate the ParameterAttributes
|
||||
/// with a parameter index.
|
||||
/// @brief ParameterAttributes with a parameter index.
|
||||
struct ParamAttrsWithIndex {
|
||||
uint16_t attrs; ///< The attributes that are set, |'d together
|
||||
uint16_t index; ///< Index of the parameter for which the attributes apply
|
||||
};
|
||||
|
||||
/// @brief A vector of attribute/index pairs.
|
||||
typedef SmallVector<ParamAttrsWithIndex,4> ParamAttrsVector;
|
||||
|
||||
/// @}
|
||||
class ParamAttrsList : public FoldingSetNode {
|
||||
/// @name Construction
|
||||
/// @{
|
||||
public:
|
||||
/// @brief Construct an empty ParamAttrsList
|
||||
ParamAttrsList() {}
|
||||
private:
|
||||
// ParamAttrsList is uniqued, thes should not be publicly available
|
||||
void operator=(const ParamAttrsList &); // Do not implement
|
||||
ParamAttrsList(const ParamAttrsList &); // Do not implement
|
||||
ParamAttrsList(); // Do not implement
|
||||
~ParamAttrsList() {} // Not public!
|
||||
|
||||
/// @brief Construct an ParamAttrsList from a ParamAttrsVector
|
||||
explicit ParamAttrsList(const ParamAttrsVector &attrVec) : attrs(attrVec) {}
|
||||
|
||||
public:
|
||||
/// This method ensures the uniqueness of ParamAttrsList instances. The
|
||||
/// argument is a vector of attribute/index pairs as represented by the
|
||||
/// ParamAttrsWithIndex structure. The vector is used in the construction of
|
||||
/// the ParamAttrsList instance. If an instance with identical vector pairs
|
||||
/// exists, it will be returned instead of creating a new instance.
|
||||
/// @brief Get a ParamAttrsList instance.
|
||||
ParamAttrsList *get(const ParamAttrsVector &attrVec);
|
||||
static ParamAttrsList *get(const ParamAttrsVector &attrVec);
|
||||
|
||||
/// @}
|
||||
/// @name Accessors
|
||||
@ -155,33 +156,12 @@ class ParamAttrsList {
|
||||
/// @brief Return the number of parameter attributes this type has.
|
||||
unsigned size() const { return attrs.size(); }
|
||||
|
||||
/// Clients generally should not use this method. It is used internally by
|
||||
/// LLVM.
|
||||
/// @returns true if this ParamAttrsList is empty.
|
||||
/// @brief Determine emptiness of ParamAttrsList.
|
||||
unsigned empty() const { return attrs.empty(); }
|
||||
|
||||
/// @}
|
||||
/// @name Mutators
|
||||
/// @name Implementation Details
|
||||
/// @{
|
||||
public:
|
||||
/// This method will add the \p attrs to the parameter with index
|
||||
/// \p param_index. If the parameter index does not exist it will be created
|
||||
/// and the \p attrs will be the only attributes set. Otherwise, any
|
||||
/// existing attributes for the specified parameter remain set and the
|
||||
/// attributes given by \p attrs are also set.
|
||||
/// @brief Add ParameterAttributes.
|
||||
void addAttributes(uint16_t param_index, uint16_t attrs);
|
||||
|
||||
/// This method will remove the \p attrs to the parameter with index
|
||||
/// \p param_index. If the parameter index does not exist in the list,
|
||||
/// an assertion will occur. If the specified attributes are the last
|
||||
/// attributes set for the specified parameter index, the attributes for
|
||||
/// that index are removed completely from the list (size is decremented).
|
||||
/// Otherwise, the specified attributes are removed from the set of
|
||||
/// attributes for the given index, retaining any others.
|
||||
/// @brief Remove a single ParameterAttribute
|
||||
void removeAttributes(uint16_t param_index, uint16_t attrs);
|
||||
void Profile(FoldingSetNodeID &ID) const;
|
||||
void dump() const;
|
||||
|
||||
/// @}
|
||||
/// @name Data
|
||||
|
@ -1299,24 +1299,28 @@ Types
|
||||
}
|
||||
| Types '(' ArgTypeListI ')' OptFuncAttrs {
|
||||
std::vector<const Type*> Params;
|
||||
ParamAttrsList Attrs;
|
||||
if ($5 != ParamAttr::None)
|
||||
Attrs.addAttributes(0, $5);
|
||||
ParamAttrsVector Attrs;
|
||||
if ($5 != ParamAttr::None) {
|
||||
ParamAttrsWithIndex X; X.index = 0; X.attrs = $5;
|
||||
Attrs.push_back(X);
|
||||
}
|
||||
unsigned index = 1;
|
||||
TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
|
||||
for (; I != E; ++I, ++index) {
|
||||
const Type *Ty = I->Ty->get();
|
||||
Params.push_back(Ty);
|
||||
if (Ty != Type::VoidTy)
|
||||
if (I->Attrs != ParamAttr::None)
|
||||
Attrs.addAttributes(index, I->Attrs);
|
||||
if (I->Attrs != ParamAttr::None) {
|
||||
ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs;
|
||||
Attrs.push_back(X);
|
||||
}
|
||||
}
|
||||
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
||||
if (isVarArg) Params.pop_back();
|
||||
|
||||
ParamAttrsList *ActualAttrs = 0;
|
||||
if (!Attrs.empty())
|
||||
ActualAttrs = new ParamAttrsList(Attrs);
|
||||
ActualAttrs = ParamAttrsList::get(Attrs);
|
||||
FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, ActualAttrs);
|
||||
delete $3; // Delete the argument list
|
||||
delete $1; // Delete the return type handle
|
||||
@ -1325,24 +1329,28 @@ Types
|
||||
}
|
||||
| VOID '(' ArgTypeListI ')' OptFuncAttrs {
|
||||
std::vector<const Type*> Params;
|
||||
ParamAttrsList Attrs;
|
||||
if ($5 != ParamAttr::None)
|
||||
Attrs.addAttributes(0, $5);
|
||||
ParamAttrsVector Attrs;
|
||||
if ($5 != ParamAttr::None) {
|
||||
ParamAttrsWithIndex X; X.index = 0; X.attrs = $5;
|
||||
Attrs.push_back(X);
|
||||
}
|
||||
TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
|
||||
unsigned index = 1;
|
||||
for ( ; I != E; ++I, ++index) {
|
||||
const Type* Ty = I->Ty->get();
|
||||
Params.push_back(Ty);
|
||||
if (Ty != Type::VoidTy)
|
||||
if (I->Attrs != ParamAttr::None)
|
||||
Attrs.addAttributes(index, I->Attrs);
|
||||
if (I->Attrs != ParamAttr::None) {
|
||||
ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs;
|
||||
Attrs.push_back(X);
|
||||
}
|
||||
}
|
||||
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
||||
if (isVarArg) Params.pop_back();
|
||||
|
||||
ParamAttrsList *ActualAttrs = 0;
|
||||
if (!Attrs.empty())
|
||||
ActualAttrs = new ParamAttrsList(Attrs);
|
||||
ActualAttrs = ParamAttrsList::get(Attrs);
|
||||
|
||||
FunctionType *FT = FunctionType::get($1, Params, isVarArg, ActualAttrs);
|
||||
delete $3; // Delete the argument list
|
||||
@ -2135,9 +2143,11 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
|
||||
|
||||
std::vector<const Type*> ParamTypeList;
|
||||
ParamAttrsList ParamAttrs;
|
||||
if ($7 != ParamAttr::None)
|
||||
ParamAttrs.addAttributes(0, $7);
|
||||
ParamAttrsVector Attrs;
|
||||
if ($7 != ParamAttr::None) {
|
||||
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $7;
|
||||
Attrs.push_back(PAWI);
|
||||
}
|
||||
if ($5) { // If there are arguments...
|
||||
unsigned index = 1;
|
||||
for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
|
||||
@ -2146,20 +2156,21 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
|
||||
ParamTypeList.push_back(Ty);
|
||||
if (Ty != Type::VoidTy)
|
||||
if (I->Attrs != ParamAttr::None)
|
||||
ParamAttrs.addAttributes(index, I->Attrs);
|
||||
if (I->Attrs != ParamAttr::None) {
|
||||
ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
|
||||
Attrs.push_back(PAWI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
|
||||
if (isVarArg) ParamTypeList.pop_back();
|
||||
|
||||
ParamAttrsList *ActualAttrs = 0;
|
||||
if (!ParamAttrs.empty())
|
||||
ActualAttrs = new ParamAttrsList(ParamAttrs);
|
||||
ParamAttrsList *PAL = 0;
|
||||
if (!Attrs.empty())
|
||||
PAL = ParamAttrsList::get(Attrs);
|
||||
|
||||
FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg,
|
||||
ActualAttrs);
|
||||
FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg, PAL);
|
||||
const PointerType *PFT = PointerType::get(FT);
|
||||
delete $2;
|
||||
|
||||
@ -2490,9 +2501,11 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
||||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
|
||||
// Pull out the types of all of the arguments...
|
||||
std::vector<const Type*> ParamTypes;
|
||||
ParamAttrsList ParamAttrs;
|
||||
if ($8 != ParamAttr::None)
|
||||
ParamAttrs.addAttributes(0, $8);
|
||||
ParamAttrsVector Attrs;
|
||||
if ($8 != ParamAttr::None) {
|
||||
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = 8;
|
||||
Attrs.push_back(PAWI);
|
||||
}
|
||||
ValueRefList::iterator I = $6->begin(), E = $6->end();
|
||||
unsigned index = 1;
|
||||
for (; I != E; ++I, ++index) {
|
||||
@ -2500,14 +2513,16 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
||||
if (Ty == Type::VoidTy)
|
||||
GEN_ERROR("Short call syntax cannot be used with varargs");
|
||||
ParamTypes.push_back(Ty);
|
||||
if (I->Attrs != ParamAttr::None)
|
||||
ParamAttrs.addAttributes(index, I->Attrs);
|
||||
if (I->Attrs != ParamAttr::None) {
|
||||
ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
|
||||
Attrs.push_back(PAWI);
|
||||
}
|
||||
}
|
||||
|
||||
ParamAttrsList *Attrs = 0;
|
||||
if (!ParamAttrs.empty())
|
||||
Attrs = new ParamAttrsList(ParamAttrs);
|
||||
Ty = FunctionType::get($3->get(), ParamTypes, false, Attrs);
|
||||
ParamAttrsList *PAL = 0;
|
||||
if (!Attrs.empty())
|
||||
PAL = ParamAttrsList::get(Attrs);
|
||||
Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
|
||||
PFTy = PointerType::get(Ty);
|
||||
}
|
||||
|
||||
@ -2796,9 +2811,11 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
|
||||
// Pull out the types of all of the arguments...
|
||||
std::vector<const Type*> ParamTypes;
|
||||
ParamAttrsList ParamAttrs;
|
||||
if ($8 != ParamAttr::None)
|
||||
ParamAttrs.addAttributes(0, $8);
|
||||
ParamAttrsVector Attrs;
|
||||
if ($8 != ParamAttr::None) {
|
||||
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
|
||||
Attrs.push_back(PAWI);
|
||||
}
|
||||
unsigned index = 1;
|
||||
ValueRefList::iterator I = $6->begin(), E = $6->end();
|
||||
for (; I != E; ++I, ++index) {
|
||||
@ -2806,15 +2823,17 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
if (Ty == Type::VoidTy)
|
||||
GEN_ERROR("Short call syntax cannot be used with varargs");
|
||||
ParamTypes.push_back(Ty);
|
||||
if (I->Attrs != ParamAttr::None)
|
||||
ParamAttrs.addAttributes(index, I->Attrs);
|
||||
if (I->Attrs != ParamAttr::None) {
|
||||
ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
|
||||
Attrs.push_back(PAWI);
|
||||
}
|
||||
}
|
||||
|
||||
ParamAttrsList *Attrs = 0;
|
||||
if (!ParamAttrs.empty())
|
||||
Attrs = new ParamAttrsList(ParamAttrs);
|
||||
ParamAttrsList *PAL = 0;
|
||||
if (!Attrs.empty())
|
||||
PAL = ParamAttrsList::get(Attrs);
|
||||
|
||||
Ty = FunctionType::get($3->get(), ParamTypes, false, Attrs);
|
||||
Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
|
||||
PFTy = PointerType::get(Ty);
|
||||
}
|
||||
|
||||
|
@ -1078,16 +1078,18 @@ const Type *BytecodeReader::ParseType() {
|
||||
|
||||
ParamAttrsList *BytecodeReader::ParseParamAttrsList() {
|
||||
unsigned NumAttrs = read_vbr_uint();
|
||||
ParamAttrsList *Attrs = 0;
|
||||
ParamAttrsList *PAL = 0;
|
||||
if (NumAttrs) {
|
||||
Attrs = new ParamAttrsList();
|
||||
ParamAttrsVector Attrs;
|
||||
ParamAttrsWithIndex PAWI;
|
||||
while (NumAttrs--) {
|
||||
uint16_t index = read_vbr_uint();
|
||||
uint16_t attrs = read_vbr_uint();
|
||||
Attrs->addAttributes(index, attrs);
|
||||
PAWI.index = read_vbr_uint();
|
||||
PAWI.attrs = read_vbr_uint();
|
||||
Attrs.push_back(PAWI);
|
||||
}
|
||||
PAL = ParamAttrsList::get(Attrs);
|
||||
}
|
||||
return Attrs;
|
||||
return PAL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1383,6 +1383,17 @@ void Value::dump() const { print(*cerr.stream()); cerr << '\n'; }
|
||||
// Located here because so much of the needed functionality is here.
|
||||
void Type::dump() const { print(*cerr.stream()); cerr << '\n'; }
|
||||
|
||||
void
|
||||
ParamAttrsList::dump() const {
|
||||
cerr << "PAL[ ";
|
||||
for (unsigned i = 0; i < attrs.size(); ++i) {
|
||||
uint16_t index = getParamIndex(i);
|
||||
uint16_t attrs = getParamAttrs(index);
|
||||
cerr << "{" << index << "," << attrs << "} ";
|
||||
}
|
||||
cerr << "]\n";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SlotMachine Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "llvm/ParameterAttributes.h"
|
||||
#include "llvm/IntrinsicInst.h"
|
||||
#include "llvm/Support/LeakDetector.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "SymbolTableListTraitsImpl.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
using namespace llvm;
|
||||
@ -103,35 +104,29 @@ ParamAttrsList::getParamAttrsText(uint16_t Attrs) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
void
|
||||
ParamAttrsList::addAttributes(uint16_t Index, uint16_t Attrs) {
|
||||
// First, try to replace an existing one
|
||||
for (unsigned i = 0; i < attrs.size(); ++i)
|
||||
if (attrs[i].index == Index) {
|
||||
attrs[i].attrs |= Attrs;
|
||||
return;
|
||||
}
|
||||
|
||||
// If not found, add a new one
|
||||
ParamAttrsWithIndex Val;
|
||||
Val.attrs = Attrs;
|
||||
Val.index = Index;
|
||||
attrs.push_back(Val);
|
||||
void
|
||||
ParamAttrsList::Profile(FoldingSetNodeID &ID) const {
|
||||
for (unsigned i = 0; i < attrs.size(); ++i) {
|
||||
unsigned val = attrs[i].attrs << 16 | attrs[i].index;
|
||||
ID.AddInteger(val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ParamAttrsList::removeAttributes(uint16_t Index, uint16_t Attrs) {
|
||||
// Find the index from which to remove the attributes
|
||||
for (unsigned i = 0; i < attrs.size(); ++i)
|
||||
if (attrs[i].index == Index) {
|
||||
attrs[i].attrs &= ~Attrs;
|
||||
if (attrs[i].attrs == ParamAttr::None)
|
||||
attrs.erase(&attrs[i]);
|
||||
return;
|
||||
}
|
||||
static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists;
|
||||
|
||||
// The index wasn't found above
|
||||
assert(0 && "Index not found for removeAttributes");
|
||||
ParamAttrsList *
|
||||
ParamAttrsList::get(const ParamAttrsVector &attrVec) {
|
||||
assert(!attrVec.empty() && "Illegal to create empty ParamAttrsList");
|
||||
ParamAttrsList key(attrVec);
|
||||
FoldingSetNodeID ID;
|
||||
key.Profile(ID);
|
||||
void *InsertPos;
|
||||
ParamAttrsList* PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos);
|
||||
if (!PAL) {
|
||||
PAL = new ParamAttrsList(attrVec);
|
||||
ParamAttrsLists->InsertNode(PAL, InsertPos);
|
||||
}
|
||||
return PAL;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -186,7 +186,6 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
|
||||
|
||||
CallInst::~CallInst() {
|
||||
delete [] OperandList;
|
||||
delete ParamAttrs; // FIXME: ParamAttrsList should be uniqued!
|
||||
}
|
||||
|
||||
void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
|
||||
@ -354,7 +353,6 @@ CallInst::CallInst(const CallInst &CI)
|
||||
|
||||
InvokeInst::~InvokeInst() {
|
||||
delete [] OperandList;
|
||||
delete ParamAttrs; // FIXME: ParamAttrsList should be uniqued!
|
||||
}
|
||||
|
||||
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
|
||||
|
@ -643,20 +643,13 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
|
||||
return false;
|
||||
const ParamAttrsList *Attrs1 = FTy->getParamAttrs();
|
||||
const ParamAttrsList *Attrs2 = FTy2->getParamAttrs();
|
||||
if ((!Attrs1 && Attrs2 && !Attrs2->empty()) ||
|
||||
(!Attrs2 && Attrs1 && !Attrs1->empty()) ||
|
||||
if ((!Attrs1 && Attrs2) || (!Attrs2 && Attrs1) ||
|
||||
(Attrs1 && Attrs2 && (Attrs1->size() != Attrs2->size() ||
|
||||
(Attrs1->size() > 0 &&
|
||||
Attrs1->getParamAttrs(0) != Attrs2->getParamAttrs(0)))))
|
||||
(Attrs1->getParamAttrs(0) != Attrs2->getParamAttrs(0)))))
|
||||
return false;
|
||||
ParamAttrsList PAL1;
|
||||
if (Attrs1)
|
||||
PAL1 = *Attrs1;
|
||||
ParamAttrsList PAL2;
|
||||
if (Attrs2)
|
||||
PAL2 = *Attrs2;
|
||||
|
||||
for (unsigned i = 0, e = FTy2->getNumParams(); i != e; ++i) {
|
||||
if (PAL1.getParamAttrs(i+1) != PAL2.getParamAttrs(i+1))
|
||||
if (Attrs1 && Attrs1->getParamAttrs(i+1) != Attrs2->getParamAttrs(i+1))
|
||||
return false;
|
||||
if (!TypesEqual(FTy->getParamType(i), FTy2->getParamType(i), EqTypes))
|
||||
return false;
|
||||
@ -1065,15 +1058,10 @@ public:
|
||||
if (ParamAttrs)
|
||||
if (MTV.ParamAttrs)
|
||||
return *ParamAttrs < *MTV.ParamAttrs;
|
||||
else if (ParamAttrs->empty())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
else if (MTV.ParamAttrs)
|
||||
if (MTV.ParamAttrs->empty())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@ -1100,26 +1088,20 @@ FunctionType *FunctionType::get(const Type *ReturnType,
|
||||
ParamAttrsList *Attrs) {
|
||||
|
||||
FunctionValType VT(ReturnType, Params, isVarArg, Attrs);
|
||||
FunctionType *MT = FunctionTypes->get(VT);
|
||||
if (MT) {
|
||||
delete Attrs; // not needed any more
|
||||
return MT;
|
||||
FunctionType *FT = FunctionTypes->get(VT);
|
||||
if (FT) {
|
||||
return FT;
|
||||
}
|
||||
|
||||
|
||||
MT = (FunctionType*) new char[sizeof(FunctionType) +
|
||||
FT = (FunctionType*) new char[sizeof(FunctionType) +
|
||||
sizeof(PATypeHandle)*(Params.size()+1)];
|
||||
new (MT) FunctionType(ReturnType, Params, isVarArg, Attrs);
|
||||
FunctionTypes->add(VT, MT);
|
||||
new (FT) FunctionType(ReturnType, Params, isVarArg, Attrs);
|
||||
FunctionTypes->add(VT, FT);
|
||||
|
||||
#ifdef DEBUG_MERGE_TYPES
|
||||
DOUT << "Derived new type: " << MT << "\n";
|
||||
DOUT << "Derived new type: " << FT << "\n";
|
||||
#endif
|
||||
return MT;
|
||||
}
|
||||
|
||||
FunctionType::~FunctionType() {
|
||||
delete ParamAttrs;
|
||||
return FT;
|
||||
}
|
||||
|
||||
bool FunctionType::isStructReturn() const {
|
||||
|
@ -1,5 +1,7 @@
|
||||
; For PR1187
|
||||
; RUN: llvm-upgrade < %s > /dev/null
|
||||
; XFAIL: *
|
||||
; Un-XFAIL this when PR1146 is fixed.
|
||||
|
||||
%mystruct = type { int, double }
|
||||
%glob = global %mystruct { int 3, double 42.0 }
|
||||
|
@ -1,4 +1,6 @@
|
||||
; RUN: llvm-upgrade < %s | llvm-as | opt -simplifycfg -disable-output
|
||||
; XFAIL: *
|
||||
; Un-XFAIL this when PR1146 is finished.
|
||||
|
||||
%struct..4._102 = type { %struct.QVectorData* }
|
||||
%struct..5._125 = type { %struct.QMapData* }
|
||||
|
@ -62,6 +62,7 @@ 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.
|
||||
@ -380,19 +381,18 @@ static bool FuncTysDifferOnlyBySRet(const FunctionType *F1,
|
||||
if (F1->getReturnType() != F2->getReturnType() ||
|
||||
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))
|
||||
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) ||
|
||||
unsigned(PAL1.getParamAttrs(i+1)) & SRetMask !=
|
||||
unsigned(PAL2.getParamAttrs(i+1)) & SRetMask)
|
||||
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;
|
||||
@ -1460,6 +1460,10 @@ upgradeIntrinsicCall(const Type* RetTy, const ValID &ID,
|
||||
std::vector<Value*>& Args) {
|
||||
|
||||
std::string Name = ID.Type == ValID::NameVal ? ID.Name : "";
|
||||
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") {
|
||||
@ -2006,17 +2010,17 @@ OptLinkage
|
||||
;
|
||||
|
||||
OptCallingConv
|
||||
: /*empty*/ { $$ = OldCallingConv::C; }
|
||||
| CCC_TOK { $$ = OldCallingConv::C; }
|
||||
| CSRETCC_TOK { $$ = OldCallingConv::CSRet; }
|
||||
| FASTCC_TOK { $$ = OldCallingConv::Fast; }
|
||||
| COLDCC_TOK { $$ = OldCallingConv::Cold; }
|
||||
| X86_STDCALLCC_TOK { $$ = OldCallingConv::X86_StdCall; }
|
||||
| X86_FASTCALLCC_TOK { $$ = OldCallingConv::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;
|
||||
}
|
||||
;
|
||||
|
||||
@ -2146,8 +2150,17 @@ UpRTypes
|
||||
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
||||
if (isVarArg) Params.pop_back();
|
||||
|
||||
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, 0);
|
||||
FunctionType::get($1.PAT->get(), Params, isVarArg, PAL);
|
||||
|
||||
$$.PAT = new PATypeHolder( HandleUpRefs(FTy, $$.S) );
|
||||
delete $1.PAT; // Delete the return type handle
|
||||
@ -2930,15 +2943,17 @@ FunctionHeaderH
|
||||
|
||||
// Convert the CSRet calling convention into the corresponding parameter
|
||||
// attribute.
|
||||
ParamAttrsList *ParamAttrs = 0;
|
||||
ParamAttrsList *PAL = 0;
|
||||
if ($1 == OldCallingConv::CSRet) {
|
||||
ParamAttrs = new ParamAttrsList();
|
||||
ParamAttrs->addAttributes(0, ParamAttr::None); // result
|
||||
ParamAttrs->addAttributes(1, ParamAttr::StructRet); // first arg
|
||||
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, ParamTyList, isVarArg, ParamAttrs);
|
||||
FunctionType::get(RetTy, ParamTyList, isVarArg, PAL);
|
||||
const PointerType *PFT = PointerType::get(FT);
|
||||
delete $2.PAT;
|
||||
|
||||
@ -3076,6 +3091,7 @@ FunctionHeaderH
|
||||
}
|
||||
delete $5; // We're now done with the argument list
|
||||
}
|
||||
lastCallingConv = OldCallingConv::C;
|
||||
}
|
||||
;
|
||||
|
||||
@ -3324,15 +3340,17 @@ BBTerminatorInst
|
||||
FTySign.add(I->S);
|
||||
}
|
||||
}
|
||||
ParamAttrsList *ParamAttrs = 0;
|
||||
ParamAttrsList *PAL = 0;
|
||||
if ($2 == OldCallingConv::CSRet) {
|
||||
ParamAttrs = new ParamAttrsList();
|
||||
ParamAttrs->addAttributes(0, ParamAttr::None); // Function result
|
||||
ParamAttrs->addAttributes(1, ParamAttr::StructRet); // first param
|
||||
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.PAT->get(), ParamTypes, isVarArg, ParamAttrs);
|
||||
Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, PAL);
|
||||
PFTy = PointerType::get(Ty);
|
||||
$$.S.copy($3.S);
|
||||
} else {
|
||||
@ -3375,6 +3393,7 @@ BBTerminatorInst
|
||||
cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2));
|
||||
delete $3.PAT;
|
||||
delete $6;
|
||||
lastCallingConv = OldCallingConv::C;
|
||||
}
|
||||
| Unwind {
|
||||
$$.TI = new UnwindInst();
|
||||
@ -3729,14 +3748,16 @@ InstVal
|
||||
error("Functions cannot return aggregate types");
|
||||
|
||||
// Deal with CSRetCC
|
||||
ParamAttrsList *ParamAttrs = 0;
|
||||
ParamAttrsList *PAL = 0;
|
||||
if ($2 == OldCallingConv::CSRet) {
|
||||
ParamAttrs = new ParamAttrsList();
|
||||
ParamAttrs->addAttributes(0, ParamAttr::None); // function result
|
||||
ParamAttrs->addAttributes(1, ParamAttr::StructRet); // first parameter
|
||||
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, ParamAttrs);
|
||||
FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, PAL);
|
||||
PFTy = PointerType::get(FTy);
|
||||
$$.S.copy($3.S);
|
||||
} else {
|
||||
@ -3792,6 +3813,7 @@ InstVal
|
||||
}
|
||||
delete $3.PAT;
|
||||
delete $6;
|
||||
lastCallingConv = OldCallingConv::C;
|
||||
}
|
||||
| MemoryInst {
|
||||
$$ = $1;
|
||||
|
@ -461,13 +461,14 @@ CppWriter::printTypeInternal(const Type* Ty) {
|
||||
const ParamAttrsList *PAL = FT->getParamAttrs();
|
||||
Out << "ParamAttrsList *" << typeName << "_PAL = 0;";
|
||||
nl(Out);
|
||||
if (PAL && !PAL->empty()) {
|
||||
Out << typeName << "_PAL = new ParamAttrsList();";
|
||||
nl(Out);
|
||||
if (PAL) {
|
||||
Out << '{'; in(); nl(Out);
|
||||
Out << "ParamAttrsVector Attrs;"; nl(Out);
|
||||
Out << "ParamAttrsWithIndex PAWI;"; nl(Out);
|
||||
for (unsigned i = 0; i < PAL->size(); ++i) {
|
||||
uint16_t index = PAL->getParamIndex(i);
|
||||
uint16_t attrs = PAL->getParamAttrs(index);
|
||||
Out << typeName << "_PAL->addAttributes(" << index << ", 0";
|
||||
Out << "PAWI.index = " << index << "; PAWI.attrs = 0 ";
|
||||
if (attrs & ParamAttr::SExt)
|
||||
Out << " | ParamAttr::SExt";
|
||||
if (attrs & ParamAttr::ZExt)
|
||||
@ -480,9 +481,15 @@ CppWriter::printTypeInternal(const Type* Ty) {
|
||||
Out << " | ParamAttr::NoReturn";
|
||||
if (attrs & ParamAttr::NoUnwind)
|
||||
Out << " | ParamAttr::NoUnwind";
|
||||
Out << ");";
|
||||
Out << ";";
|
||||
nl(Out);
|
||||
Out << "Attrs.push_back(PAWI);";
|
||||
nl(Out);
|
||||
}
|
||||
Out << typeName << "_PAL = ParamAttrsList::get(Attrs);";
|
||||
nl(Out);
|
||||
out(); nl(Out);
|
||||
Out << '}'; nl(Out);
|
||||
}
|
||||
bool isForward = printTypeInternal(FT->getReturnType());
|
||||
std::string retTypeName(getCppName(FT->getReturnType()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user