Reimplement the parameter attributes support, phase #1. hilights:

1. There is now a "PAListPtr" class, which is a smart pointer around
   the underlying uniqued parameter attribute list object, and manages
   its refcount.  It is now impossible to mess up the refcount.
2. PAListPtr is now the main interface to the underlying object, and
   the underlying object is now completely opaque.
3. Implementation details like SmallVector and FoldingSet are now no
   longer part of the interface.
4. You can create a PAListPtr with an arbitrary sequence of
   ParamAttrsWithIndex's, no need to make a SmallVector of a specific 
   size (you can just use an array or scalar or vector if you wish).
5. All the client code that had to check for a null pointer before
   dereferencing the pointer is simplified to just access the 
   PAListPtr directly.
6. The interfaces for adding attrs to a list and removing them is a
   bit simpler.

Phase #2 will rename some stuff (e.g. PAListPtr) and do other less 
invasive changes.

llvm-svn: 48289
This commit is contained in:
Chris Lattner 2008-03-12 17:45:29 +00:00
parent b327e49047
commit 8a923e7c28
34 changed files with 1320 additions and 1630 deletions

View File

@ -27,7 +27,6 @@
namespace llvm {
class FunctionType;
class ParamAttrsList;
// Traits for intrusive list of instructions...
template<> struct ilist_traits<BasicBlock>
@ -69,7 +68,7 @@ private:
BasicBlockListType BasicBlocks; ///< The basic blocks
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
const ParamAttrsList *ParamAttrs; ///< Parameter attributes
PAListPtr ParamAttrs; ///< Parameter attributes
// The Calling Convention is stored in Value::SubclassData.
/*unsigned CallingConvention;*/
@ -145,16 +144,11 @@ public:
SubclassData = (SubclassData & 1) | (CC << 1);
}
/// Obtains a constant pointer to the ParamAttrsList object which holds the
/// parameter attributes information, if any.
/// @returns 0 if no parameter attributes have been set.
/// @brief Get the parameter attributes.
const ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
/// getParamAttrs - Return the parameter attributes for this function.
const PAListPtr &getParamAttrs() const { return ParamAttrs; }
/// Sets the parameter attributes for this Function. To construct a
/// ParamAttrsList, see ParameterAttributes.h
/// @brief Set the parameter attributes.
void setParamAttrs(const ParamAttrsList *attrs);
/// setParamAttrs - Set the parameter attributes for this Function.
void setParamAttrs(const PAListPtr &attrs) { ParamAttrs = attrs; }
/// hasCollector/getCollector/setCollector/clearCollector - The name of the
/// garbage collection algorithm to use during code generation.

View File

@ -30,7 +30,6 @@ class PointerType;
class VectorType;
class ConstantRange;
class APInt;
class ParamAttrsList;
//===----------------------------------------------------------------------===//
// AllocationInst Class
@ -851,7 +850,7 @@ public:
///
class CallInst : public Instruction {
const ParamAttrsList *ParamAttrs; ///< parameter attributes for call
PAListPtr ParamAttrs; ///< parameter attributes for call
CallInst(const CallInst &CI);
void init(Value *Func, Value* const *Params, unsigned NumParams);
void init(Value *Func, Value *Actual1, Value *Actual2);
@ -927,16 +926,12 @@ public:
SubclassData = (SubclassData & 1) | (CC << 1);
}
/// Obtains a pointer to the ParamAttrsList object which holds the
/// parameter attributes information, if any.
/// @returns 0 if no attributes have been set.
/// @brief Get the parameter attributes.
const ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
/// getParamAttrs - Return the PAListPtr for the parameter attributes of this
/// call.
const PAListPtr &getParamAttrs() const { return ParamAttrs; }
/// Sets the parameter attributes for this CallInst. To construct a
/// ParamAttrsList, see ParameterAttributes.h
/// @brief Set the parameter attributes.
void setParamAttrs(const ParamAttrsList *attrs);
/// setParamAttrs - Sets the parameter attributes for this CallInst.
void setParamAttrs(const PAListPtr &Attrs) { ParamAttrs = Attrs; }
/// @brief Determine whether the call or the callee has the given attribute.
bool paramHasAttr(uint16_t i, unsigned attr) const;
@ -1678,7 +1673,7 @@ private:
/// calling convention of the call.
///
class InvokeInst : public TerminatorInst {
const ParamAttrsList *ParamAttrs;
PAListPtr ParamAttrs;
InvokeInst(const InvokeInst &BI);
void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs);
@ -1745,16 +1740,13 @@ public:
SubclassData = CC;
}
/// Obtains a pointer to the ParamAttrsList object which holds the
/// parameter attributes information, if any.
/// @returns 0 if no attributes have been set.
/// @brief Get the parameter attributes.
const ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
/// getParamAttrs - Return the parameter attribute list for this invoke.
///
const PAListPtr &getParamAttrs() const { return ParamAttrs; }
/// Sets the parameter attributes for this InvokeInst. To construct a
/// ParamAttrsList, see ParameterAttributes.h
/// @brief Set the parameter attributes.
void setParamAttrs(const ParamAttrsList *attrs);
/// setParamAttrs - Set the parameter attribute list for this invoke.
///
void setParamAttrs(const PAListPtr &Attrs) { ParamAttrs = Attrs; }
/// @brief Determine whether the call or the callee has the given attribute.
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;

View File

@ -22,7 +22,7 @@ class Type;
class FunctionType;
class Function;
class Module;
class ParamAttrsList;
class PAListPtr;
/// Intrinsic Namespace - This namespace contains an enum with a value for
/// every intrinsic/builtin function known by LLVM. These enum values are
@ -49,7 +49,7 @@ namespace Intrinsic {
/// Intrinsic::getParamAttrs(ID) - Return the attributes for an intrinsic.
///
const ParamAttrsList *getParamAttrs(ID id);
PAListPtr getParamAttrs(ID id);
/// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function
/// declaration for an intrinsic, and return it.

View File

@ -1,226 +0,0 @@
//===-- llvm/ParamAttrsList.h - List and Vector of ParamAttrs ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains classes used to represent the parameter attributes
// associated with functions and their calls.
//
// The implementation of ParamAttrsList is in VMCore/ParameterAttributes.cpp.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_PARAM_ATTRS_LIST_H
#define LLVM_PARAM_ATTRS_LIST_H
#include "llvm/ParameterAttributes.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/FoldingSet.h"
namespace llvm {
/// @brief A vector of attribute/index pairs.
typedef SmallVector<ParamAttrsWithIndex,4> ParamAttrsVector;
/// This class represents a list of attribute/index pairs for parameter
/// attributes. Each entry in the list contains the index of a function
/// parameter and the associated ParameterAttributes. If a parameter's index is
/// not present in the list, then no attributes are set for that parameter. The
/// list may also be empty, but this does not occur in practice. An item in
/// the list with an index of 0 refers to the function as a whole or its result.
/// To construct a ParamAttrsList, you must first fill a ParamAttrsVector with
/// the attribute/index pairs you wish to set. The list of attributes can be
/// turned into a string of mnemonics suitable for LLVM Assembly output.
/// Various accessors are provided to obtain information about the attributes.
/// Note that objects of this class are "uniqued". The \p get method can return
/// the pointer of an existing and identical instance. Consequently, reference
/// counting is necessary in order to determine when the last reference to a
/// ParamAttrsList of a given shape is dropped. Users of this class should use
/// the addRef and dropRef methods to add/drop references. When the reference
/// count goes to zero, the ParamAttrsList object is deleted.
/// This class is used by Function, CallInst and InvokeInst to represent their
/// sets of parameter attributes.
/// @brief A List of ParameterAttributes.
class ParamAttrsList : public FoldingSetNode {
/// @name Construction
/// @{
private:
// ParamAttrsList is uniqued, these should not be publicly available
void operator=(const ParamAttrsList &); // Do not implement
ParamAttrsList(const ParamAttrsList &); // Do not implement
~ParamAttrsList(); // Private implementation
/// Only the \p get method can invoke this when it wants to create a
/// new instance.
/// @brief Construct an ParamAttrsList from a ParamAttrsVector
explicit ParamAttrsList(const ParamAttrsVector &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 index values must be in strictly
/// increasing order and ParamAttr::None is not allowed. The vector is
/// used to construct 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.
static const ParamAttrsList *get(const ParamAttrsVector &attrVec);
/// Returns the ParamAttrsList obtained by modifying PAL using the supplied
/// list of attribute/index pairs. Any existing attributes for the given
/// index are replaced by the given attributes. If there were no attributes
/// then the new ones are inserted. Attributes can be deleted by replacing
/// them with ParamAttr::None. Index values must be strictly increasing.
/// @brief Get a new ParamAttrsList instance by modifying an existing one.
static const ParamAttrsList *getModified(const ParamAttrsList *PAL,
const ParamAttrsVector &modVec);
/// @brief Add the specified attributes to those in PAL at index idx.
static const ParamAttrsList *includeAttrs(const ParamAttrsList *PAL,
uint16_t idx,
ParameterAttributes attrs);
/// @brief Remove the specified attributes from those in PAL at index idx.
static const ParamAttrsList *excludeAttrs(const ParamAttrsList *PAL,
uint16_t idx,
ParameterAttributes attrs);
/// @}
/// @name Accessors
/// @{
public:
/// The parameter attributes for the \p indexth parameter are returned.
/// The 0th parameter refers to the return type of the function. Note that
/// the \p param_index is an index into the function's parameters, not an
/// index into this class's list of attributes. The result of getParamIndex
/// is always suitable input to this function.
/// @returns The all the ParameterAttributes for the \p indexth parameter
/// as a uint16_t of enumeration values OR'd together.
/// @brief Get the attributes for a parameter
ParameterAttributes getParamAttrs(uint16_t param_index) const;
/// This checks to see if the \p ith function parameter has the parameter
/// attribute given by \p attr set.
/// @returns true if the parameter attribute is set
/// @brief Determine if a ParameterAttributes is set
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const {
return getParamAttrs(i) & attr;
}
/// This extracts the alignment for the \p ith function parameter.
/// @returns 0 if unknown, else the alignment in bytes
/// @brief Extract the Alignment
uint16_t getParamAlignment(uint16_t i) const {
return (getParamAttrs(i) & ParamAttr::Alignment) >> 16;
}
/// This returns whether the given attribute is set for at least one
/// parameter or for the return value.
/// @returns true if the parameter attribute is set somewhere
/// @brief Determine if a ParameterAttributes is set somewhere
bool hasAttrSomewhere(ParameterAttributes attr) const;
/// The set of ParameterAttributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out
/// the mnemonics for the assembly writer.
/// @brief Convert parameter attribute bits to text
static std::string getParamAttrsText(ParameterAttributes Attributes);
/// The \p Indexth parameter attribute is converted to string.
/// @brief Get the text for the parmeter attributes for one parameter.
std::string getParamAttrsTextByIndex(uint16_t Index) const {
return getParamAttrsText(getParamAttrs(Index));
}
/// @brief Comparison operator for ParamAttrsList
bool operator < (const ParamAttrsList& that) const {
if (this->attrs.size() < that.attrs.size())
return true;
if (this->attrs.size() > that.attrs.size())
return false;
for (unsigned i = 0; i < attrs.size(); ++i) {
if (attrs[i].index < that.attrs[i].index)
return true;
if (attrs[i].index > that.attrs[i].index)
return false;
if (attrs[i].attrs < that.attrs[i].attrs)
return true;
if (attrs[i].attrs > that.attrs[i].attrs)
return false;
}
return false;
}
/// Returns the parameter index of a particular parameter attribute in this
/// list of attributes. Note that the attr_index is an index into this
/// class's list of attributes, not the index of a parameter. The result
/// is the index of the parameter. Clients generally should not use this
/// method. It is used internally by LLVM.
/// @brief Get a parameter index
uint16_t getParamIndex(unsigned attr_index) const {
return attrs[attr_index].index;
}
ParameterAttributes getParamAttrsAtIndex(unsigned attr_index) const {
return attrs[attr_index].attrs;
}
/// Determines how many parameter attributes are set in this ParamAttrsList.
/// This says nothing about how many parameters the function has. It also
/// says nothing about the highest parameter index that has attributes.
/// Clients generally should not use this method. It is used internally by
/// LLVM.
/// @returns the number of parameter attributes in this ParamAttrsList.
/// @brief Return the number of parameter attributes this type has.
unsigned size() const { return attrs.size(); }
/// @brief Return the number of references to this ParamAttrsList.
unsigned numRefs() const { return refCount; }
/// @}
/// @name Mutators
/// @{
public:
/// Classes retaining references to ParamAttrsList objects should call this
/// method to increment the reference count. This ensures that the
/// ParamAttrsList object will not disappear until the class drops it.
/// @brief Add a reference to this instance.
void addRef() const { refCount++; }
/// Classes retaining references to ParamAttrsList objects should call this
/// method to decrement the reference count and possibly delete the
/// ParamAttrsList object. This ensures that ParamAttrsList objects are
/// cleaned up only when the last reference to them is dropped.
/// @brief Drop a reference to this instance.
void dropRef() const {
assert(refCount != 0 && "dropRef without addRef");
if (--refCount == 0)
delete this;
}
/// @}
/// @name Implementation Details
/// @{
public:
void Profile(FoldingSetNodeID &ID) const {
Profile(ID, attrs);
}
static void Profile(FoldingSetNodeID &ID, const ParamAttrsVector &Attrs);
void dump() const;
/// @}
/// @name Data
/// @{
private:
ParamAttrsVector attrs; ///< The list of attributes
mutable unsigned refCount; ///< The number of references to this object
/// @}
};
} // End llvm namespace
#endif

View File

@ -15,12 +15,14 @@
#ifndef LLVM_PARAMETER_ATTRIBUTES_H
#define LLVM_PARAMETER_ATTRIBUTES_H
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <string>
namespace llvm {
class Type;
/// ParameterAttributes - A bitset of attributes for a parameter.
typedef unsigned ParameterAttributes;
namespace ParamAttr {
/// Function parameters and results can have attributes to indicate how they
@ -28,9 +30,7 @@ namespace ParamAttr {
/// lists the attributes that can be associated with parameters or function
/// results.
/// @brief Function parameter attributes.
/// @brief A more friendly way to reference the attributes.
typedef uint32_t Attributes;
typedef ParameterAttributes Attributes;
const Attributes None = 0; ///< No attributes have been set
const Attributes ZExt = 1<<0; ///< Zero extended before/after call
@ -64,33 +64,141 @@ const Attributes MutuallyIncompatible[3] = {
};
/// @brief Which attributes cannot be applied to a type.
Attributes typeIncompatible (const Type *Ty);
Attributes typeIncompatible(const Type *Ty);
/// This turns an int alignment (a power of 2, normally) into the
/// form used internally in ParameterAttributes.
ParamAttr::Attributes inline constructAlignmentFromInt(uint32_t i) {
ParamAttr::Attributes inline constructAlignmentFromInt(unsigned i) {
return (i << 16);
}
/// The set of ParameterAttributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out
/// the mnemonics for the assembly writer.
/// @brief Convert parameter attribute bits to text
std::string getAsString(ParameterAttributes Attrs);
} // end namespace ParamAttr
/// @brief A more friendly way to reference the attributes.
typedef ParamAttr::Attributes ParameterAttributes;
/// 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 {
ParameterAttributes attrs; ///< The attributes that are set, or'd together
uint16_t index; ///< Index of the parameter for which the attributes apply
ParameterAttributes Attrs; ///< The attributes that are set, or'd together.
unsigned Index; ///< Index of the parameter for which the attributes apply.
static ParamAttrsWithIndex get(uint16_t idx, ParameterAttributes attrs) {
static ParamAttrsWithIndex get(unsigned Idx, ParameterAttributes Attrs) {
ParamAttrsWithIndex P;
P.index = idx;
P.attrs = attrs;
P.Index = Idx;
P.Attrs = Attrs;
return P;
}
};
//===----------------------------------------------------------------------===//
// PAListPtr Smart Pointer
//===----------------------------------------------------------------------===//
class ParamAttributeListImpl;
/// PAListPtr - This class manages the ref count for the opaque
/// ParamAttributeListImpl object and provides accessors for it.
class PAListPtr {
/// PAList - The parameter attributes that we are managing. This can be null
/// to represent the empty parameter attributes list.
ParamAttributeListImpl *PAList;
public:
PAListPtr() : PAList(0) {}
PAListPtr(const PAListPtr &P);
const PAListPtr &operator=(const PAListPtr &RHS);
~PAListPtr();
//===--------------------------------------------------------------------===//
// Parameter Attribute List Construction and Mutation
//===--------------------------------------------------------------------===//
/// get - Return a ParamAttrs list with the specified parameter in it.
static PAListPtr get(const ParamAttrsWithIndex *Attr, unsigned NumAttrs);
/// get - Return a ParamAttr list with the parameters specified by the
/// consequtive random access iterator range.
template <typename Iter>
static PAListPtr get(const Iter &I, const Iter &E) {
if (I == E) return PAListPtr(); // Empty list.
return get(&*I, E-I);
}
/// addAttr - Add the specified attribute at the specified index to this
/// attribute list. Since parameter attribute lists are immutable, this
/// returns the new list.
PAListPtr addAttr(unsigned Idx, ParameterAttributes Attrs) const;
/// removeAttr - Remove the specified attribute at the specified index from
/// this attribute list. Since parameter attribute lists are immutable, this
/// returns the new list.
PAListPtr removeAttr(unsigned Idx, ParameterAttributes Attrs) const;
//===--------------------------------------------------------------------===//
// Parameter Attribute List Accessors
//===--------------------------------------------------------------------===//
/// getParamAttrs - The parameter attributes for the specified parameter are
/// returned. Parameters for the result are denoted with Idx = 0.
ParameterAttributes getParamAttrs(unsigned Idx) const;
/// paramHasAttr - Return true if the specified parameter index has the
/// specified attribute set.
bool paramHasAttr(unsigned Idx, ParameterAttributes Attr) const {
return getParamAttrs(Idx) & Attr;
}
/// getParamAlignment - Return the alignment for the specified function
/// parameter.
unsigned getParamAlignment(unsigned Idx) const {
return (getParamAttrs(Idx) & ParamAttr::Alignment) >> 16;
}
/// hasAttrSomewhere - Return true if the specified attribute is set for at
/// least one parameter or for the return value.
bool hasAttrSomewhere(ParameterAttributes Attr) const;
/// operator< - Provide an ordering for parameter attribute lists.
bool operator==(const PAListPtr &RHS) const { return PAList == RHS.PAList; }
bool operator!=(const PAListPtr &RHS) const { return PAList != RHS.PAList; }
void dump() const;
//===--------------------------------------------------------------------===//
// Parameter Attribute List Introspection
//===--------------------------------------------------------------------===//
/// getRawPointer - Return a raw pointer that uniquely identifies this
/// parameter attribute list.
void *getRawPointer() const {
return PAList;
}
// Parameter attributes are stored as a dense set of slots, where there is one
// slot for each argument that has an attribute. This allows walking over the
// dense set instead of walking the sparse list of attributes.
/// isEmpty - Return true if no parameters have an attribute.
///
bool isEmpty() const {
return PAList == 0;
}
/// getNumSlots - Return the number of slots used in this attribute list.
/// This is the number of arguments that have an attribute set on them
/// (including the function itself).
unsigned getNumSlots() const;
/// getSlot - Return the ParamAttrsWithIndex at the specified slot. This
/// holds a parameter number plus a set of attributes.
const ParamAttrsWithIndex &getSlot(unsigned Slot) const;
private:
explicit PAListPtr(ParamAttributeListImpl *L);
};
} // End llvm namespace

View File

@ -28,7 +28,6 @@ namespace llvm {
class CallInst;
class InvokeInst;
class ParamAttrsList;
class CallSite {
Instruction *I;
@ -62,8 +61,8 @@ public:
/// getParamAttrs/setParamAttrs - get or set the parameter attributes of
/// the call.
const ParamAttrsList *getParamAttrs() const;
void setParamAttrs(const ParamAttrsList *PAL);
const PAListPtr &getParamAttrs() const;
void setParamAttrs(const PAListPtr &PAL);
/// paramHasAttr - whether the call or the callee has the given attribute.
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;

File diff suppressed because it is too large Load Diff

View File

@ -346,7 +346,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 951 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y"
#line 950 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y"
{
llvm::Module *ModuleVal;
llvm::Function *FunctionVal;
@ -393,7 +393,7 @@ typedef union YYSTYPE
llvm::ICmpInst::Predicate IPredicate;
llvm::FCmpInst::Predicate FPredicate;
}
/* Line 1489 of yacc.c. */
/* Line 1529 of yacc.c. */
#line 398 "llvmAsmParser.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */

View File

@ -25,7 +25,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Streams.h"
#include "llvm/ParamAttrsList.h"
#include <algorithm>
#include <list>
#include <map>
@ -2256,13 +2255,9 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
std::vector<const Type*> ParamTypeList;
ParamAttrsVector Attrs;
if ($7 != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = 0;
PAWI.attrs = $7;
Attrs.push_back(PAWI);
}
SmallVector<ParamAttrsWithIndex, 8> Attrs;
if ($7 != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(0, $7));
if ($5) { // If there are arguments...
unsigned index = 1;
for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
@ -2270,22 +2265,17 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty))
GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
ParamTypeList.push_back(Ty);
if (Ty != Type::VoidTy)
if (I->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = I->Attrs;
Attrs.push_back(PAWI);
}
if (Ty != Type::VoidTy && I->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, I->Attrs));
}
}
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
if (isVarArg) ParamTypeList.pop_back();
const ParamAttrsList *PAL = 0;
PAListPtr PAL;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
const PointerType *PFT = PointerType::getUnqual(FT);
@ -2304,7 +2294,8 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
// Move the function to the end of the list, from whereever it was
// previously inserted.
Fn = cast<Function>(FWRef);
assert(!Fn->getParamAttrs() && "Forward reference has parameter attributes!");
assert(Fn->getParamAttrs().isEmpty() &&
"Forward reference has parameter attributes!");
CurModule.CurrentModule->getFunctionList().remove(Fn);
CurModule.CurrentModule->getFunctionList().push_back(Fn);
} else if (!FunctionName.empty() && // Merge with an earlier prototype?
@ -2669,11 +2660,9 @@ BBTerminatorInst :
BasicBlock *Except = getBBVal($14);
CHECK_FOR_ERROR
ParamAttrsVector Attrs;
if ($8 != ParamAttr::None) {
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
Attrs.push_back(PAWI);
}
SmallVector<ParamAttrsWithIndex, 8> Attrs;
if ($8 != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(0, $8));
// Check the arguments
ValueList Args;
@ -2695,35 +2684,27 @@ BBTerminatorInst :
GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
(*I)->getDescription() + "'");
Args.push_back(ArgI->Val);
if (ArgI->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = ArgI->Attrs;
Attrs.push_back(PAWI);
}
if (ArgI->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
}
if (Ty->isVarArg()) {
if (I == E)
for (; ArgI != ArgE; ++ArgI, ++index) {
Args.push_back(ArgI->Val); // push the remaining varargs
if (ArgI->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = ArgI->Attrs;
Attrs.push_back(PAWI);
}
if (ArgI->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
}
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
const ParamAttrsList *PAL = 0;
PAListPtr PAL;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
// Create the InvokeInst
InvokeInst *II = new InvokeInst(V, Normal, Except, Args.begin(), Args.end());
InvokeInst *II = new InvokeInst(V, Normal, Except, Args.begin(),Args.end());
II->setCallingConv($2);
II->setParamAttrs(PAL);
$$ = II;
@ -3007,13 +2988,9 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
}
// Set up the ParamAttrs for the function
ParamAttrsVector Attrs;
if ($8 != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = 0;
PAWI.attrs = $8;
Attrs.push_back(PAWI);
}
SmallVector<ParamAttrsWithIndex, 8> Attrs;
if ($8 != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(0, $8));
// Check the arguments
ValueList Args;
if ($6->empty()) { // Has no arguments?
@ -3034,32 +3011,24 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
(*I)->getDescription() + "'");
Args.push_back(ArgI->Val);
if (ArgI->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = ArgI->Attrs;
Attrs.push_back(PAWI);
}
if (ArgI->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
}
if (Ty->isVarArg()) {
if (I == E)
for (; ArgI != ArgE; ++ArgI, ++index) {
Args.push_back(ArgI->Val); // push the remaining varargs
if (ArgI->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = ArgI->Attrs;
Attrs.push_back(PAWI);
}
if (ArgI->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
}
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
// Finish off the ParamAttrs and check them
const ParamAttrsList *PAL = 0;
PAListPtr PAL;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
// Create the call node
CallInst *CI = new CallInst(V, Args.begin(), Args.end());

View File

@ -25,7 +25,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Streams.h"
#include "llvm/ParamAttrsList.h"
#include <algorithm>
#include <list>
#include <map>
@ -2256,13 +2255,9 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
std::vector<const Type*> ParamTypeList;
ParamAttrsVector Attrs;
if ($7 != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = 0;
PAWI.attrs = $7;
Attrs.push_back(PAWI);
}
SmallVector<ParamAttrsWithIndex, 8> Attrs;
if ($7 != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(0, $7));
if ($5) { // If there are arguments...
unsigned index = 1;
for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
@ -2270,22 +2265,17 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty))
GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
ParamTypeList.push_back(Ty);
if (Ty != Type::VoidTy)
if (I->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = I->Attrs;
Attrs.push_back(PAWI);
}
if (Ty != Type::VoidTy && I->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, I->Attrs));
}
}
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
if (isVarArg) ParamTypeList.pop_back();
const ParamAttrsList *PAL = 0;
PAListPtr PAL;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
const PointerType *PFT = PointerType::getUnqual(FT);
@ -2304,7 +2294,8 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
// Move the function to the end of the list, from whereever it was
// previously inserted.
Fn = cast<Function>(FWRef);
assert(!Fn->getParamAttrs() && "Forward reference has parameter attributes!");
assert(Fn->getParamAttrs().isEmpty() &&
"Forward reference has parameter attributes!");
CurModule.CurrentModule->getFunctionList().remove(Fn);
CurModule.CurrentModule->getFunctionList().push_back(Fn);
} else if (!FunctionName.empty() && // Merge with an earlier prototype?
@ -2669,11 +2660,9 @@ BBTerminatorInst :
BasicBlock *Except = getBBVal($14);
CHECK_FOR_ERROR
ParamAttrsVector Attrs;
if ($8 != ParamAttr::None) {
ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
Attrs.push_back(PAWI);
}
SmallVector<ParamAttrsWithIndex, 8> Attrs;
if ($8 != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(0, $8));
// Check the arguments
ValueList Args;
@ -2695,35 +2684,27 @@ BBTerminatorInst :
GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
(*I)->getDescription() + "'");
Args.push_back(ArgI->Val);
if (ArgI->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = ArgI->Attrs;
Attrs.push_back(PAWI);
}
if (ArgI->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
}
if (Ty->isVarArg()) {
if (I == E)
for (; ArgI != ArgE; ++ArgI, ++index) {
Args.push_back(ArgI->Val); // push the remaining varargs
if (ArgI->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = ArgI->Attrs;
Attrs.push_back(PAWI);
}
if (ArgI->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
}
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
const ParamAttrsList *PAL = 0;
PAListPtr PAL;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
// Create the InvokeInst
InvokeInst *II = new InvokeInst(V, Normal, Except, Args.begin(), Args.end());
InvokeInst *II = new InvokeInst(V, Normal, Except, Args.begin(),Args.end());
II->setCallingConv($2);
II->setParamAttrs(PAL);
$$ = II;
@ -3007,13 +2988,9 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
}
// Set up the ParamAttrs for the function
ParamAttrsVector Attrs;
if ($8 != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = 0;
PAWI.attrs = $8;
Attrs.push_back(PAWI);
}
SmallVector<ParamAttrsWithIndex, 8> Attrs;
if ($8 != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(0, $8));
// Check the arguments
ValueList Args;
if ($6->empty()) { // Has no arguments?
@ -3034,32 +3011,24 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
(*I)->getDescription() + "'");
Args.push_back(ArgI->Val);
if (ArgI->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = ArgI->Attrs;
Attrs.push_back(PAWI);
}
if (ArgI->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
}
if (Ty->isVarArg()) {
if (I == E)
for (; ArgI != ArgE; ++ArgI, ++index) {
Args.push_back(ArgI->Val); // push the remaining varargs
if (ArgI->Attrs != ParamAttr::None) {
ParamAttrsWithIndex PAWI;
PAWI.index = index;
PAWI.attrs = ArgI->Attrs;
Attrs.push_back(PAWI);
}
if (ArgI->Attrs != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
}
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
// Finish off the ParamAttrs and check them
const ParamAttrsList *PAL = 0;
PAListPtr PAL;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
// Create the call node
CallInst *CI = new CallInst(V, Args.begin(), Args.end());

View File

@ -18,7 +18,6 @@
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/AutoUpgrade.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@ -32,11 +31,7 @@ void BitcodeReader::FreeState() {
std::vector<PATypeHolder>().swap(TypeList);
ValueList.clear();
// Drop references to ParamAttrs.
for (unsigned i = 0, e = ParamAttrs.size(); i != e; ++i)
ParamAttrs[i]->dropRef();
std::vector<const ParamAttrsList*>().swap(ParamAttrs);
std::vector<PAListPtr>().swap(ParamAttrs);
std::vector<BasicBlock*>().swap(FunctionBBs);
std::vector<Function*>().swap(FunctionsWithBodies);
DeferredFunctionInfo.clear();
@ -205,7 +200,7 @@ bool BitcodeReader::ParseParamAttrBlock() {
SmallVector<uint64_t, 64> Record;
ParamAttrsVector Attrs;
SmallVector<ParamAttrsWithIndex, 8> Attrs;
// Read all the records.
while (1) {
@ -242,13 +237,8 @@ bool BitcodeReader::ParseParamAttrBlock() {
if (Record[i+1] != ParamAttr::None)
Attrs.push_back(ParamAttrsWithIndex::get(Record[i], Record[i+1]));
}
if (Attrs.empty()) {
ParamAttrs.push_back(0);
} else {
ParamAttrs.push_back(ParamAttrsList::get(Attrs));
ParamAttrs.back()->addRef();
}
ParamAttrs.push_back(PAListPtr::get(Attrs.begin(), Attrs.end()));
Attrs.clear();
break;
}
@ -1062,8 +1052,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
Func->setCallingConv(Record[1]);
bool isProto = Record[2];
Func->setLinkage(GetDecodedLinkage(Record[3]));
const ParamAttrsList *PAL = getParamAttrs(Record[4]);
Func->setParamAttrs(PAL);
Func->setParamAttrs(getParamAttrs(Record[4]));
Func->setAlignment((1 << Record[5]) >> 1);
if (Record[6]) {
@ -1427,7 +1416,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_INVOKE: {
// INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
if (Record.size() < 4) return Error("Invalid INVOKE record");
const ParamAttrsList *PAL = getParamAttrs(Record[0]);
PAListPtr PAL = getParamAttrs(Record[0]);
unsigned CCInfo = Record[1];
BasicBlock *NormalBB = getBasicBlock(Record[2]);
BasicBlock *UnwindBB = getBasicBlock(Record[3]);
@ -1565,7 +1554,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
if (Record.size() < 3)
return Error("Invalid CALL record");
const ParamAttrsList *PAL = getParamAttrs(Record[0]);
PAListPtr PAL = getParamAttrs(Record[0]);
unsigned CCInfo = Record[1];
unsigned OpNum = 2;

View File

@ -15,6 +15,7 @@
#define BITCODE_READER_H
#include "llvm/ModuleProvider.h"
#include "llvm/ParameterAttributes.h"
#include "llvm/Type.h"
#include "llvm/User.h"
#include "llvm/Bitcode/BitstreamReader.h"
@ -24,7 +25,6 @@
namespace llvm {
class MemoryBuffer;
class ParamAttrsList;
class BitcodeReaderValueList : public User {
std::vector<Use> Uses;
@ -93,7 +93,7 @@ class BitcodeReader : public ModuleProvider {
/// ParamAttrs - The set of parameter attributes by index. Index zero in the
/// file is for null, and is thus not represented here. As such all indices
/// are off by one.
std::vector<const ParamAttrsList*> ParamAttrs;
std::vector<PAListPtr> ParamAttrs;
/// FunctionBBs - While parsing a function body, this is a list of the basic
/// blocks for the function.
@ -156,10 +156,10 @@ private:
if (ID >= FunctionBBs.size()) return 0; // Invalid ID
return FunctionBBs[ID];
}
const ParamAttrsList *getParamAttrs(unsigned i) const {
PAListPtr getParamAttrs(unsigned i) const {
if (i-1 < ParamAttrs.size())
return ParamAttrs[i-1];
return 0;
return PAListPtr();
}
/// getValueTypePair - Read a value/type pair out of the specified record from

View File

@ -20,7 +20,6 @@
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Support/MathExtras.h"
@ -109,17 +108,18 @@ static void WriteStringRecord(unsigned Code, const std::string &Str,
// Emit information about parameter attributes.
static void WriteParamAttrTable(const ValueEnumerator &VE,
BitstreamWriter &Stream) {
const std::vector<const ParamAttrsList*> &Attrs = VE.getParamAttrs();
const std::vector<PAListPtr> &Attrs = VE.getParamAttrs();
if (Attrs.empty()) return;
Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
SmallVector<uint64_t, 64> Record;
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
const ParamAttrsList *A = Attrs[i];
for (unsigned op = 0, e = A->size(); op != e; ++op) {
Record.push_back(A->getParamIndex(op));
Record.push_back(A->getParamAttrsAtIndex(op));
const PAListPtr &A = Attrs[i];
for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) {
const ParamAttrsWithIndex &PAWI = A.getSlot(i);
Record.push_back(PAWI.Index);
Record.push_back(PAWI.Attrs);
}
Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);

View File

@ -245,10 +245,10 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) {
}
}
void ValueEnumerator::EnumerateParamAttrs(const ParamAttrsList *PAL) {
if (PAL == 0) return; // null is always 0.
void ValueEnumerator::EnumerateParamAttrs(const PAListPtr &PAL) {
if (PAL.isEmpty()) return; // null is always 0.
// Do a lookup.
unsigned &Entry = ParamAttrMap[PAL];
unsigned &Entry = ParamAttrMap[PAL.getRawPointer()];
if (Entry == 0) {
// Never saw this before, add it.
ParamAttrs.push_back(PAL);

View File

@ -15,6 +15,7 @@
#define VALUE_ENUMERATOR_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ParameterAttributes.h"
#include <vector>
namespace llvm {
@ -24,7 +25,7 @@ class Value;
class BasicBlock;
class Function;
class Module;
class ParamAttrsList;
class PAListPtr;
class TypeSymbolTable;
class ValueSymbolTable;
@ -44,9 +45,9 @@ private:
ValueMapType ValueMap;
ValueList Values;
typedef DenseMap<const ParamAttrsList*, unsigned> ParamAttrMapType;
typedef DenseMap<void*, unsigned> ParamAttrMapType;
ParamAttrMapType ParamAttrMap;
std::vector<const ParamAttrsList*> ParamAttrs;
std::vector<PAListPtr> ParamAttrs;
/// BasicBlocks - This contains all the basic blocks for the currently
/// incorporated function. Their reverse mapping is stored in ValueMap.
@ -75,9 +76,9 @@ public:
return I->second-1;
}
unsigned getParamAttrID(const ParamAttrsList *PAL) const {
if (PAL == 0) return 0; // Null maps to zero.
ParamAttrMapType::const_iterator I = ParamAttrMap.find(PAL);
unsigned getParamAttrID(const PAListPtr &PAL) const {
if (PAL.isEmpty()) return 0; // Null maps to zero.
ParamAttrMapType::const_iterator I = ParamAttrMap.find(PAL.getRawPointer());
assert(I != ParamAttrMap.end() && "ParamAttr not in ValueEnumerator!");
return I->second;
}
@ -94,7 +95,7 @@ public:
const std::vector<const BasicBlock*> &getBasicBlocks() const {
return BasicBlocks;
}
const std::vector<const ParamAttrsList*> &getParamAttrs() const {
const std::vector<PAListPtr> &getParamAttrs() const {
return ParamAttrs;
}
@ -115,7 +116,7 @@ private:
void EnumerateValue(const Value *V);
void EnumerateType(const Type *T);
void EnumerateOperandType(const Value *V);
void EnumerateParamAttrs(const ParamAttrsList *PAL);
void EnumerateParamAttrs(const PAListPtr &PAL);
void EnumerateTypeSymbolTable(const TypeSymbolTable &ST);
void EnumerateValueSymbolTable(const ValueSymbolTable &ST);

View File

@ -18,7 +18,6 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/TypeSymbolTable.h"
@ -131,13 +130,13 @@ namespace {
bool isSigned = false,
const std::string &VariableName = "",
bool IgnoreName = false,
const ParamAttrsList *PAL = 0);
const PAListPtr &PAL = PAListPtr());
std::ostream &printSimpleType(std::ostream &Out, const Type *Ty,
bool isSigned,
const std::string &NameSoFar = "");
void printStructReturnPointerFunctionType(std::ostream &Out,
const ParamAttrsList *PAL,
const PAListPtr &PAL,
const PointerType *Ty);
/// writeOperandDeref - Print the result of dereferencing the specified
@ -395,7 +394,7 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) {
/// return type, except, instead of printing the type as void (*)(Struct*, ...)
/// print it as "Struct (*)(...)", for struct return functions.
void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
const ParamAttrsList *PAL,
const PAListPtr &PAL,
const PointerType *TheTy) {
const FunctionType *FTy = cast<FunctionType>(TheTy->getElementType());
std::stringstream FunctionInnards;
@ -409,12 +408,12 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
if (PrintedType)
FunctionInnards << ", ";
const Type *ArgTy = *I;
if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) {
if (PAL.paramHasAttr(Idx, ParamAttr::ByVal)) {
assert(isa<PointerType>(ArgTy));
ArgTy = cast<PointerType>(ArgTy)->getElementType();
}
printType(FunctionInnards, ArgTy,
/*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), "");
/*isSigned=*/PAL.paramHasAttr(Idx, ParamAttr::SExt), "");
PrintedType = true;
}
if (FTy->isVarArg()) {
@ -426,7 +425,7 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
FunctionInnards << ')';
std::string tstr = FunctionInnards.str();
printType(Out, RetTy,
/*isSigned=*/PAL && PAL->paramHasAttr(0, ParamAttr::SExt), tstr);
/*isSigned=*/PAL.paramHasAttr(0, ParamAttr::SExt), tstr);
}
std::ostream &
@ -477,7 +476,7 @@ CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned,
//
std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
bool isSigned, const std::string &NameSoFar,
bool IgnoreName, const ParamAttrsList* PAL) {
bool IgnoreName, const PAListPtr &PAL) {
if (Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) {
printSimpleType(Out, Ty, isSigned, NameSoFar);
return Out;
@ -498,14 +497,14 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I) {
const Type *ArgTy = *I;
if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) {
if (PAL.paramHasAttr(Idx, ParamAttr::ByVal)) {
assert(isa<PointerType>(ArgTy));
ArgTy = cast<PointerType>(ArgTy)->getElementType();
}
if (I != FTy->param_begin())
FunctionInnards << ", ";
printType(FunctionInnards, ArgTy,
/*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), "");
/*isSigned=*/PAL.paramHasAttr(Idx, ParamAttr::SExt), "");
++Idx;
}
if (FTy->isVarArg()) {
@ -517,7 +516,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
FunctionInnards << ')';
std::string tstr = FunctionInnards.str();
printType(Out, FTy->getReturnType(),
/*isSigned=*/PAL && PAL->paramHasAttr(0, ParamAttr::SExt), tstr);
/*isSigned=*/PAL.paramHasAttr(0, ParamAttr::SExt), tstr);
return Out;
}
case Type::StructTyID: {
@ -544,7 +543,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
isa<VectorType>(PTy->getElementType()))
ptrName = "(" + ptrName + ")";
if (PAL)
if (!PAL.isEmpty())
// Must be a function ptr cast!
return printType(Out, PTy->getElementType(), false, ptrName, true, PAL);
return printType(Out, PTy->getElementType(), false, ptrName);
@ -1920,7 +1919,7 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
// Loop over the arguments, printing them...
const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
const ParamAttrsList *PAL = F->getParamAttrs();
const PAListPtr &PAL = F->getParamAttrs();
std::stringstream FunctionInnards;
@ -1949,12 +1948,12 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
else
ArgName = "";
const Type *ArgTy = I->getType();
if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) {
if (PAL.paramHasAttr(Idx, ParamAttr::ByVal)) {
ArgTy = cast<PointerType>(ArgTy)->getElementType();
ByValParams.insert(I);
}
printType(FunctionInnards, ArgTy,
/*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt),
/*isSigned=*/PAL.paramHasAttr(Idx, ParamAttr::SExt),
ArgName);
PrintedArg = true;
++Idx;
@ -1976,12 +1975,12 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
for (; I != E; ++I) {
if (PrintedArg) FunctionInnards << ", ";
const Type *ArgTy = *I;
if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) {
if (PAL.paramHasAttr(Idx, ParamAttr::ByVal)) {
assert(isa<PointerType>(ArgTy));
ArgTy = cast<PointerType>(ArgTy)->getElementType();
}
printType(FunctionInnards, ArgTy,
/*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt));
/*isSigned=*/PAL.paramHasAttr(Idx, ParamAttr::SExt));
PrintedArg = true;
++Idx;
}
@ -2009,7 +2008,7 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
// Print out the return type and the signature built above.
printType(Out, RetTy,
/*isSigned=*/ PAL && PAL->paramHasAttr(0, ParamAttr::SExt),
/*isSigned=*/PAL.paramHasAttr(0, ParamAttr::SExt),
FunctionInnards.str());
}
@ -2582,7 +2581,7 @@ void CWriter::visitCallInst(CallInst &I) {
// If this is a call to a struct-return function, assign to the first
// parameter instead of passing it to the call.
const ParamAttrsList *PAL = I.getParamAttrs();
const PAListPtr &PAL = I.getParamAttrs();
bool hasByVal = I.hasByValArgument();
bool isStructRet = I.hasStructRetAttr();
if (isStructRet) {
@ -2650,7 +2649,7 @@ void CWriter::visitCallInst(CallInst &I) {
(*AI)->getType() != FTy->getParamType(ArgNo)) {
Out << '(';
printType(Out, FTy->getParamType(ArgNo),
/*isSigned=*/PAL && PAL->paramHasAttr(ArgNo+1, ParamAttr::SExt));
/*isSigned=*/PAL.paramHasAttr(ArgNo+1, ParamAttr::SExt));
Out << ')';
}
// Check if the argument is expected to be passed by value.

View File

@ -39,7 +39,6 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ParamAttrsList.h"
using namespace llvm;
X86TargetLowering::X86TargetLowering(TargetMachine &TM)
@ -5251,15 +5250,15 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
// Check that ECX wasn't needed by an 'inreg' parameter.
const FunctionType *FTy = Func->getFunctionType();
const ParamAttrsList *Attrs = Func->getParamAttrs();
const PAListPtr &Attrs = Func->getParamAttrs();
if (Attrs && !Func->isVarArg()) {
if (!Attrs.isEmpty() && !Func->isVarArg()) {
unsigned InRegCount = 0;
unsigned Idx = 1;
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I, ++Idx)
if (Attrs->paramHasAttr(Idx, ParamAttr::InReg))
if (Attrs.paramHasAttr(Idx, ParamAttr::InReg))
// FIXME: should only count parameters that are lowered to integers.
InRegCount += (getTargetData()->getTypeSizeInBits(*I) + 31) / 32;

View File

@ -35,7 +35,6 @@
#include "llvm/Module.h"
#include "llvm/CallGraphSCCPass.h"
#include "llvm/Instructions.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Target/TargetData.h"
@ -401,11 +400,11 @@ Function *ArgPromotion::DoPromotion(Function *F,
// ParamAttrs - Keep track of the parameter attributes for the arguments
// that we are *not* promoting. For the ones that we do promote, the parameter
// attributes are lost
ParamAttrsVector ParamAttrsVec;
const ParamAttrsList *PAL = F->getParamAttrs();
SmallVector<ParamAttrsWithIndex, 8> ParamAttrsVec;
const PAListPtr &PAL = F->getParamAttrs();
// Add any return attributes.
if (ParameterAttributes attrs = PAL ? PAL->getParamAttrs(0) : ParamAttr::None)
if (ParameterAttributes attrs = PAL.getParamAttrs(0))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, attrs));
unsigned ArgIndex = 1;
@ -420,8 +419,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
++NumByValArgsPromoted;
} else if (!ArgsToPromote.count(I)) {
Params.push_back(I->getType());
if (ParameterAttributes attrs = PAL ? PAL->getParamAttrs(ArgIndex) :
ParamAttr::None)
if (ParameterAttributes attrs = PAL.getParamAttrs(ArgIndex))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(), attrs));
} else if (I->use_empty()) {
++NumArgumentsDead;
@ -476,8 +474,8 @@ Function *ArgPromotion::DoPromotion(Function *F,
// Recompute the parameter attributes list based on the new arguments for
// the function.
NF->setParamAttrs(ParamAttrsList::get(ParamAttrsVec));
ParamAttrsVec.clear(); PAL = 0;
NF->setParamAttrs(PAListPtr::get(ParamAttrsVec.begin(), ParamAttrsVec.end()));
ParamAttrsVec.clear();
if (F->hasCollector())
NF->setCollector(F->getCollector());
@ -494,11 +492,10 @@ Function *ArgPromotion::DoPromotion(Function *F,
while (!F->use_empty()) {
CallSite CS = CallSite::get(F->use_back());
Instruction *Call = CS.getInstruction();
PAL = CS.getParamAttrs();
const PAListPtr &CallPAL = CS.getParamAttrs();
// Add any return attributes.
if (ParameterAttributes attrs = PAL ? PAL->getParamAttrs(0) :
ParamAttr::None)
if (ParameterAttributes attrs = CallPAL.getParamAttrs(0))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, attrs));
// Loop over the operands, inserting GEP and loads in the caller as
@ -510,8 +507,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
if (!ArgsToPromote.count(I) && !ByValArgsToTransform.count(I)) {
Args.push_back(*AI); // Unmodified argument
if (ParameterAttributes Attrs = PAL ? PAL->getParamAttrs(ArgIndex) :
ParamAttr::None)
if (ParameterAttributes Attrs = CallPAL.getParamAttrs(ArgIndex))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Args.size(), Attrs));
} else if (ByValArgsToTransform.count(I)) {
@ -550,8 +546,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
// Push any varargs arguments on the list
for (; AI != CS.arg_end(); ++AI, ++ArgIndex) {
Args.push_back(*AI);
if (ParameterAttributes Attrs = PAL ? PAL->getParamAttrs(ArgIndex) :
ParamAttr::None)
if (ParameterAttributes Attrs = CallPAL.getParamAttrs(ArgIndex))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Args.size(), Attrs));
}
@ -560,11 +555,13 @@ Function *ArgPromotion::DoPromotion(Function *F,
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
cast<InvokeInst>(New)->setParamAttrs(ParamAttrsList::get(ParamAttrsVec));
cast<InvokeInst>(New)->setParamAttrs(PAListPtr::get(ParamAttrsVec.begin(),
ParamAttrsVec.end()));
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
cast<CallInst>(New)->setParamAttrs(ParamAttrsList::get(ParamAttrsVec));
cast<CallInst>(New)->setParamAttrs(PAListPtr::get(ParamAttrsVec.begin(),
ParamAttrsVec.end()));
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
}

View File

@ -26,9 +26,9 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
#include <set>
@ -176,16 +176,12 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
Args.assign(CS.arg_begin(), CS.arg_begin()+NumArgs);
// Drop any attributes that were on the vararg arguments.
const ParamAttrsList *PAL = CS.getParamAttrs();
if (PAL && PAL->getParamIndex(PAL->size() - 1) > NumArgs) {
ParamAttrsVector ParamAttrsVec;
for (unsigned i = 0; PAL->getParamIndex(i) <= NumArgs; ++i) {
ParamAttrsWithIndex PAWI;
PAWI = ParamAttrsWithIndex::get(PAL->getParamIndex(i),
PAL->getParamAttrsAtIndex(i));
ParamAttrsVec.push_back(PAWI);
}
PAL = ParamAttrsList::get(ParamAttrsVec);
PAListPtr PAL = CS.getParamAttrs();
if (!PAL.isEmpty() && PAL.getSlot(PAL.getNumSlots() - 1).Index > NumArgs) {
SmallVector<ParamAttrsWithIndex, 8> ParamAttrsVec;
for (unsigned i = 0; PAL.getSlot(i).Index <= NumArgs; ++i)
ParamAttrsVec.push_back(PAL.getSlot(i));
PAL = PAListPtr::get(ParamAttrsVec.begin(), ParamAttrsVec.end());
}
Instruction *New;
@ -508,11 +504,11 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
std::vector<const Type*> Params;
// Set up to build a new list of parameter attributes
ParamAttrsVector ParamAttrsVec;
const ParamAttrsList *PAL = F->getParamAttrs();
SmallVector<ParamAttrsWithIndex, 8> ParamAttrsVec;
const PAListPtr &PAL = F->getParamAttrs();
// The existing function return attributes.
ParameterAttributes RAttrs = PAL ? PAL->getParamAttrs(0) : ParamAttr::None;
ParameterAttributes RAttrs = PAL.getParamAttrs(0);
// Make the function return void if the return value is dead.
const Type *RetTy = FTy->getReturnType();
@ -532,14 +528,13 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
++I, ++index)
if (!DeadArguments.count(I)) {
Params.push_back(I->getType());
ParameterAttributes Attrs = PAL ? PAL->getParamAttrs(index) :
ParamAttr::None;
if (Attrs)
if (ParameterAttributes Attrs = PAL.getParamAttrs(index))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(), Attrs));
}
// Reconstruct the ParamAttrsList based on the vector we constructed.
PAL = ParamAttrsList::get(ParamAttrsVec);
PAListPtr NewPAL = PAListPtr::get(ParamAttrsVec.begin(), ParamAttrsVec.end());
// Work around LLVM bug PR56: the CWriter cannot emit varargs functions which
// have zero fixed arguments.
@ -556,7 +551,7 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
// Create the new function body and insert it into the module...
Function *NF = new Function(NFTy, F->getLinkage());
NF->setCallingConv(F->getCallingConv());
NF->setParamAttrs(PAL);
NF->setParamAttrs(NewPAL);
if (F->hasCollector())
NF->setCollector(F->getCollector());
F->getParent()->getFunctionList().insert(F, NF);
@ -570,10 +565,10 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
CallSite CS = CallSite::get(F->use_back());
Instruction *Call = CS.getInstruction();
ParamAttrsVec.clear();
PAL = CS.getParamAttrs();
const PAListPtr &CallPAL = CS.getParamAttrs();
// The call return attributes.
ParameterAttributes RAttrs = PAL ? PAL->getParamAttrs(0) : ParamAttr::None;
ParameterAttributes RAttrs = CallPAL.getParamAttrs(0);
// Adjust in case the function was changed to return void.
RAttrs &= ~ParamAttr::typeIncompatible(NF->getReturnType());
if (RAttrs)
@ -586,9 +581,7 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
I != E; ++I, ++AI, ++index)
if (!DeadArguments.count(I)) { // Remove operands for dead arguments
Args.push_back(*AI);
ParameterAttributes Attrs = PAL ? PAL->getParamAttrs(index) :
ParamAttr::None;
if (Attrs)
if (ParameterAttributes Attrs = CallPAL.getParamAttrs(index))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Args.size(), Attrs));
}
@ -598,25 +591,24 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
// Push any varargs arguments on the list. Don't forget their attributes.
for (; AI != CS.arg_end(); ++AI) {
Args.push_back(*AI);
ParameterAttributes Attrs = PAL ? PAL->getParamAttrs(index++) :
ParamAttr::None;
if (Attrs)
if (ParameterAttributes Attrs = CallPAL.getParamAttrs(index++))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Args.size(), Attrs));
}
// Reconstruct the ParamAttrsList based on the vector we constructed.
PAL = ParamAttrsList::get(ParamAttrsVec);
PAListPtr NewCallPAL = PAListPtr::get(ParamAttrsVec.begin(),
ParamAttrsVec.end());
Instruction *New;
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
cast<InvokeInst>(New)->setParamAttrs(PAL);
cast<InvokeInst>(New)->setParamAttrs(NewCallPAL);
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
cast<CallInst>(New)->setParamAttrs(PAL);
cast<CallInst>(New)->setParamAttrs(NewCallPAL);
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
}

View File

@ -21,7 +21,6 @@
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Target/TargetData.h"
@ -1592,18 +1591,13 @@ static void ChangeCalleesToFastCall(Function *F) {
}
}
static const ParamAttrsList *StripNest(const ParamAttrsList *Attrs) {
if (!Attrs)
return NULL;
for (unsigned i = 0, e = Attrs->size(); i != e; ++i) {
if ((Attrs->getParamAttrsAtIndex(i) & ParamAttr::Nest) == 0)
static PAListPtr StripNest(const PAListPtr &Attrs) {
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
if ((Attrs.getSlot(i).Attrs & ParamAttr::Nest) == 0)
continue;
Attrs = ParamAttrsList::excludeAttrs(Attrs, Attrs->getParamIndex(i),
ParamAttr::Nest);
// There can be only one.
break;
return Attrs.removeAttr(Attrs.getSlot(i).Index, ParamAttr::Nest);
}
return Attrs;
@ -1640,8 +1634,7 @@ bool GlobalOpt::OptimizeFunctions(Module &M) {
Changed = true;
}
if (F->getParamAttrs() &&
F->getParamAttrs()->hasAttrSomewhere(ParamAttr::Nest) &&
if (F->getParamAttrs().hasAttrSomewhere(ParamAttr::Nest) &&
OnlyCalledDirectly(F)) {
// The function is not used by a trampoline intrinsic, so it is safe
// to remove the 'nest' attribute.

View File

@ -25,7 +25,6 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ParamAttrsList.h"
#include <set>
#include <algorithm>
using namespace llvm;
@ -131,9 +130,8 @@ bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
if (!SCCMightReturn)
NewAttributes |= ParamAttr::NoReturn;
const ParamAttrsList *PAL = SCC[i]->getFunction()->getParamAttrs();
PAL = ParamAttrsList::includeAttrs(PAL, 0, NewAttributes);
SCC[i]->getFunction()->setParamAttrs(PAL);
const PAListPtr &PAL = SCC[i]->getFunction()->getParamAttrs();
SCC[i]->getFunction()->setParamAttrs(PAL.addAttr(0, NewAttributes));
}
for (unsigned i = 0, e = SCC.size(); i != e; ++i) {

View File

@ -17,7 +17,6 @@
#include "llvm/Module.h"
#include "llvm/CallGraphSCCPass.h"
#include "llvm/Instructions.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
@ -117,7 +116,8 @@ bool SRETPromotion::PromoteReturn(CallGraphNode *CGN) {
SmallVector<Value*, 2> GEPIdx;
GEPIdx.push_back(ConstantInt::get(Type::Int32Ty, 0));
GEPIdx.push_back(ConstantInt::get(Type::Int32Ty, idx));
Value *NGEPI = new GetElementPtrInst(TheAlloca, GEPIdx.begin(), GEPIdx.end(),
Value *NGEPI = new GetElementPtrInst(TheAlloca, GEPIdx.begin(),
GEPIdx.end(),
"mrv.gep", I);
Value *NV = new LoadInst(NGEPI, "mrv.ld", I);
RetVals.push_back(NV);
@ -200,11 +200,11 @@ Function *SRETPromotion::cloneFunctionBody(Function *F,
std::vector<const Type*> Params;
// ParamAttrs - Keep track of the parameter attributes for the arguments.
ParamAttrsVector ParamAttrsVec;
const ParamAttrsList *PAL = F->getParamAttrs();
SmallVector<ParamAttrsWithIndex, 8> ParamAttrsVec;
const PAListPtr &PAL = F->getParamAttrs();
// Add any return attributes.
if (ParameterAttributes attrs = PAL ? PAL->getParamAttrs(0) : ParamAttr::None)
if (ParameterAttributes attrs = PAL.getParamAttrs(0))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, attrs));
// Skip first argument.
@ -215,12 +215,8 @@ Function *SRETPromotion::cloneFunctionBody(Function *F,
unsigned ParamIndex = 2;
while (I != E) {
Params.push_back(I->getType());
if (PAL) {
ParameterAttributes Attrs = PAL->getParamAttrs(ParamIndex);
if (Attrs != ParamAttr::None)
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(ParamIndex - 1,
Attrs));
}
if (ParameterAttributes Attrs = PAL.getParamAttrs(ParamIndex))
ParamAttrsVec.push_back(ParamAttrsWithIndex::get(ParamIndex - 1, Attrs));
++I;
++ParamIndex;
}
@ -228,7 +224,7 @@ Function *SRETPromotion::cloneFunctionBody(Function *F,
FunctionType *NFTy = FunctionType::get(STy, Params, FTy->isVarArg());
Function *NF = new Function(NFTy, F->getLinkage(), F->getName());
NF->setCallingConv(F->getCallingConv());
NF->setParamAttrs(ParamAttrsList::get(ParamAttrsVec));
NF->setParamAttrs(PAListPtr::get(ParamAttrsVec.begin(), ParamAttrsVec.end()));
F->getParent()->getFunctionList().insert(F, NF);
NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
@ -253,16 +249,17 @@ void SRETPromotion::updateCallSites(Function *F, Function *NF) {
SmallVector<Value*, 16> Args;
// ParamAttrs - Keep track of the parameter attributes for the arguments.
ParamAttrsVector ArgAttrsVec;
SmallVector<ParamAttrsWithIndex, 8> ArgAttrsVec;
for (Value::use_iterator FUI = F->use_begin(), FUE = F->use_end(); FUI != FUE;) {
for (Value::use_iterator FUI = F->use_begin(), FUE = F->use_end();
FUI != FUE;) {
CallSite CS = CallSite::get(*FUI);
++FUI;
Instruction *Call = CS.getInstruction();
const ParamAttrsList *PAL = F->getParamAttrs();
const PAListPtr &PAL = F->getParamAttrs();
// Add any return attributes.
if (ParameterAttributes attrs = PAL ? PAL->getParamAttrs(0) : ParamAttr::None)
if (ParameterAttributes attrs = PAL.getParamAttrs(0))
ArgAttrsVec.push_back(ParamAttrsWithIndex::get(0, attrs));
// Copy arguments, however skip first one.
@ -274,27 +271,26 @@ void SRETPromotion::updateCallSites(Function *F, Function *NF) {
unsigned ParamIndex = 2;
while (AI != AE) {
Args.push_back(*AI);
if (PAL) {
ParameterAttributes Attrs = PAL->getParamAttrs(ParamIndex);
if (Attrs != ParamAttr::None)
ArgAttrsVec.push_back(ParamAttrsWithIndex::get(ParamIndex - 1,
Attrs));
}
if (ParameterAttributes Attrs = PAL.getParamAttrs(ParamIndex))
ArgAttrsVec.push_back(ParamAttrsWithIndex::get(ParamIndex - 1, Attrs));
++ParamIndex;
++AI;
}
PAListPtr NewPAL = PAListPtr::get(ArgAttrsVec.begin(), ArgAttrsVec.end());
// Build new call instruction.
Instruction *New;
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
cast<InvokeInst>(New)->setParamAttrs(ParamAttrsList::get(ArgAttrsVec));
cast<InvokeInst>(New)->setParamAttrs(NewPAL);
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
cast<CallInst>(New)->setParamAttrs(ParamAttrsList::get(ArgAttrsVec));
cast<CallInst>(New)->setParamAttrs(NewPAL);
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
}

View File

@ -39,7 +39,6 @@
#include "llvm/Pass.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
@ -8419,7 +8418,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
return false;
Function *Callee = cast<Function>(CE->getOperand(0));
Instruction *Caller = CS.getInstruction();
const ParamAttrsList* CallerPAL = CS.getParamAttrs();
const PAListPtr &CallerPAL = CS.getParamAttrs();
// Okay, this is a cast from a function to a different type. Unless doing so
// would cause a type conversion of one of our arguments, change this call to
@ -8445,8 +8444,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
!CastInst::isCastable(FT->getReturnType(), OldRetTy))
return false; // Cannot transform this return value.
if (CallerPAL && !Caller->use_empty()) {
ParameterAttributes RAttrs = CallerPAL->getParamAttrs(0);
if (!CallerPAL.isEmpty() && !Caller->use_empty()) {
ParameterAttributes RAttrs = CallerPAL.getParamAttrs(0);
if (RAttrs & ParamAttr::typeIncompatible(FT->getReturnType()))
return false; // Attribute not compatible with transformed value.
}
@ -8476,11 +8475,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
if (!CastInst::isCastable(ActTy, ParamTy))
return false; // Cannot transform this parameter value.
if (CallerPAL) {
ParameterAttributes PAttrs = CallerPAL->getParamAttrs(i + 1);
if (PAttrs & ParamAttr::typeIncompatible(ParamTy))
return false; // Attribute not compatible with transformed value.
}
if (CallerPAL.getParamAttrs(i + 1) & ParamAttr::typeIncompatible(ParamTy))
return false; // Attribute not compatible with transformed value.
ConstantInt *c = dyn_cast<ConstantInt>(*AI);
// Some conversions are safe even if we do not have a body.
@ -8496,16 +8492,17 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
if (FT->getNumParams() < NumActualArgs && !FT->isVarArg() &&
Callee->isDeclaration())
return false; // Do not delete arguments unless we have a function body...
return false; // Do not delete arguments unless we have a function body.
if (FT->getNumParams() < NumActualArgs && FT->isVarArg() && CallerPAL)
if (FT->getNumParams() < NumActualArgs && FT->isVarArg() &&
!CallerPAL.isEmpty())
// In this case we have more arguments than the new function type, but we
// won't be dropping them. Check that these extra arguments have attributes
// that are compatible with being a vararg call argument.
for (unsigned i = CallerPAL->size(); i; --i) {
if (CallerPAL->getParamIndex(i - 1) <= FT->getNumParams())
for (unsigned i = CallerPAL.getNumSlots(); i; --i) {
if (CallerPAL.getSlot(i - 1).Index <= FT->getNumParams())
break;
ParameterAttributes PAttrs = CallerPAL->getParamAttrsAtIndex(i - 1);
ParameterAttributes PAttrs = CallerPAL.getSlot(i - 1).Attrs;
if (PAttrs & ParamAttr::VarArgsIncompatible)
return false;
}
@ -8514,12 +8511,11 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
// inserting cast instructions as necessary...
std::vector<Value*> Args;
Args.reserve(NumActualArgs);
ParamAttrsVector attrVec;
SmallVector<ParamAttrsWithIndex, 8> attrVec;
attrVec.reserve(NumCommonArgs);
// Get any return attributes.
ParameterAttributes RAttrs = CallerPAL ? CallerPAL->getParamAttrs(0) :
ParamAttr::None;
ParameterAttributes RAttrs = CallerPAL.getParamAttrs(0);
// If the return value is not being used, the type may not be compatible
// with the existing attributes. Wipe out any problematic attributes.
@ -8542,9 +8538,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
}
// Add any parameter attributes.
ParameterAttributes PAttrs = CallerPAL ? CallerPAL->getParamAttrs(i + 1) :
ParamAttr::None;
if (PAttrs)
if (ParameterAttributes PAttrs = CallerPAL.getParamAttrs(i + 1))
attrVec.push_back(ParamAttrsWithIndex::get(i + 1, PAttrs));
}
@ -8574,10 +8568,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
}
// Add any parameter attributes.
ParameterAttributes PAttrs = CallerPAL ?
CallerPAL->getParamAttrs(i + 1) :
ParamAttr::None;
if (PAttrs)
if (ParameterAttributes PAttrs = CallerPAL.getParamAttrs(i + 1))
attrVec.push_back(ParamAttrsWithIndex::get(i + 1, PAttrs));
}
}
@ -8586,7 +8577,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
if (FT->getReturnType() == Type::VoidTy)
Caller->setName(""); // Void type should not have a name.
const ParamAttrsList* NewCallerPAL = ParamAttrsList::get(attrVec);
const PAListPtr &NewCallerPAL = PAListPtr::get(attrVec.begin(),attrVec.end());
Instruction *NC;
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
@ -8642,11 +8633,11 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
Value *Callee = CS.getCalledValue();
const PointerType *PTy = cast<PointerType>(Callee->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
const ParamAttrsList *Attrs = CS.getParamAttrs();
const PAListPtr &Attrs = CS.getParamAttrs();
// If the call already has the 'nest' attribute somewhere then give up -
// otherwise 'nest' would occur twice after splicing in the chain.
if (Attrs && Attrs->hasAttrSomewhere(ParamAttr::Nest))
if (Attrs.hasAttrSomewhere(ParamAttr::Nest))
return 0;
IntrinsicInst *Tramp =
@ -8657,7 +8648,8 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
const PointerType *NestFPTy = cast<PointerType>(NestF->getType());
const FunctionType *NestFTy = cast<FunctionType>(NestFPTy->getElementType());
if (const ParamAttrsList *NestAttrs = NestF->getParamAttrs()) {
const PAListPtr &NestAttrs = NestF->getParamAttrs();
if (!NestAttrs.isEmpty()) {
unsigned NestIdx = 1;
const Type *NestTy = 0;
ParameterAttributes NestAttr = ParamAttr::None;
@ -8665,10 +8657,10 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
// Look for a parameter marked with the 'nest' attribute.
for (FunctionType::param_iterator I = NestFTy->param_begin(),
E = NestFTy->param_end(); I != E; ++NestIdx, ++I)
if (NestAttrs->paramHasAttr(NestIdx, ParamAttr::Nest)) {
if (NestAttrs.paramHasAttr(NestIdx, ParamAttr::Nest)) {
// Record the parameter type and any other attributes.
NestTy = *I;
NestAttr = NestAttrs->getParamAttrs(NestIdx);
NestAttr = NestAttrs.getParamAttrs(NestIdx);
break;
}
@ -8677,17 +8669,15 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
std::vector<Value*> NewArgs;
NewArgs.reserve(unsigned(CS.arg_end()-CS.arg_begin())+1);
ParamAttrsVector NewAttrs;
NewAttrs.reserve(Attrs ? Attrs->size() + 1 : 1);
SmallVector<ParamAttrsWithIndex, 8> NewAttrs;
NewAttrs.reserve(Attrs.getNumSlots() + 1);
// Insert the nest argument into the call argument list, which may
// mean appending it. Likewise for attributes.
// Add any function result attributes.
ParameterAttributes Attr = Attrs ? Attrs->getParamAttrs(0) :
ParamAttr::None;
if (Attr)
NewAttrs.push_back (ParamAttrsWithIndex::get(0, Attr));
if (ParameterAttributes Attr = Attrs.getParamAttrs(0))
NewAttrs.push_back(ParamAttrsWithIndex::get(0, Attr));
{
unsigned Idx = 1;
@ -8707,8 +8697,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
// Add the original argument and attributes.
NewArgs.push_back(*I);
Attr = Attrs ? Attrs->getParamAttrs(Idx) : 0;
if (Attr)
if (ParameterAttributes Attr = Attrs.getParamAttrs(Idx))
NewAttrs.push_back
(ParamAttrsWithIndex::get(Idx + (Idx >= NestIdx), Attr));
@ -8751,7 +8740,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
FunctionType::get(FTy->getReturnType(), NewTypes, FTy->isVarArg());
Constant *NewCallee = NestF->getType() == PointerType::getUnqual(NewFTy) ?
NestF : ConstantExpr::getBitCast(NestF, PointerType::getUnqual(NewFTy));
const ParamAttrsList *NewPAL = ParamAttrsList::get(NewAttrs);
const PAListPtr &NewPAL = PAListPtr::get(NewAttrs.begin(),NewAttrs.end());
Instruction *NewCaller;
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {

View File

@ -20,7 +20,6 @@
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/InlineAsm.h"
#include "llvm/Instruction.h"
#include "llvm/Instructions.h"
@ -849,7 +848,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand,
printType(Operand->getType());
// Print parameter attributes list
if (Attrs != ParamAttr::None)
Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs);
Out << ' ' << ParamAttr::getAsString(Attrs);
// Print the operand
WriteAsOperandInternal(Out, Operand, TypeNames, &Machine);
}
@ -1074,7 +1073,7 @@ void AssemblyWriter::printFunction(const Function *F) {
}
const FunctionType *FT = F->getFunctionType();
const ParamAttrsList *Attrs = F->getParamAttrs();
const PAListPtr &Attrs = F->getParamAttrs();
printType(F->getReturnType()) << ' ';
if (!F->getName().empty())
Out << getLLVMName(F->getName(), GlobalPrefix);
@ -1092,8 +1091,7 @@ void AssemblyWriter::printFunction(const Function *F) {
I != E; ++I) {
// Insert commas as we go... the first arg doesn't get a comma
if (I != F->arg_begin()) Out << ", ";
printArgument(I, (Attrs ? Attrs->getParamAttrs(Idx)
: ParamAttr::None));
printArgument(I, Attrs.getParamAttrs(Idx));
Idx++;
}
} else {
@ -1105,10 +1103,9 @@ void AssemblyWriter::printFunction(const Function *F) {
// Output type...
printType(FT->getParamType(i));
ParameterAttributes ArgAttrs = ParamAttr::None;
if (Attrs) ArgAttrs = Attrs->getParamAttrs(i+1);
ParameterAttributes ArgAttrs = Attrs.getParamAttrs(i+1);
if (ArgAttrs != ParamAttr::None)
Out << ' ' << ParamAttrsList::getParamAttrsText(ArgAttrs);
Out << ' ' << ParamAttr::getAsString(ArgAttrs);
}
}
@ -1118,8 +1115,9 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << "..."; // Output varargs portion of signature!
}
Out << ')';
if (Attrs && Attrs->getParamAttrs(0) != ParamAttr::None)
Out << ' ' << Attrs->getParamAttrsTextByIndex(0);
ParameterAttributes RetAttrs = Attrs.getParamAttrs(0);
if (RetAttrs != ParamAttr::None)
Out << ' ' << ParamAttr::getAsString(Attrs.getParamAttrs(0));
if (F->hasSection())
Out << " section \"" << F->getSection() << '"';
if (F->getAlignment())
@ -1152,7 +1150,7 @@ void AssemblyWriter::printArgument(const Argument *Arg,
// Output parameter attributes list
if (Attrs != ParamAttr::None)
Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs);
Out << ' ' << ParamAttr::getAsString(Attrs);
// Output name, if available...
if (Arg->hasName())
@ -1321,7 +1319,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
const PointerType *PTy = cast<PointerType>(Operand->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
const Type *RetTy = FTy->getReturnType();
const ParamAttrsList *PAL = CI->getParamAttrs();
const PAListPtr &PAL = CI->getParamAttrs();
// If possible, print out the short form of the call instruction. We can
// only do this if the first argument is a pointer to a nonvararg function,
@ -1339,17 +1337,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) {
if (op > 1)
Out << ',';
writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op) :
ParamAttr::None);
writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op));
}
Out << " )";
if (PAL && PAL->getParamAttrs(0) != ParamAttr::None)
Out << ' ' << PAL->getParamAttrsTextByIndex(0);
if (PAL.getParamAttrs(0) != ParamAttr::None)
Out << ' ' << ParamAttr::getAsString(PAL.getParamAttrs(0));
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
const PointerType *PTy = cast<PointerType>(Operand->getType());
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
const Type *RetTy = FTy->getReturnType();
const ParamAttrsList *PAL = II->getParamAttrs();
const PAListPtr &PAL = II->getParamAttrs();
// Print the calling convention being used.
switch (II->getCallingConv()) {
@ -1378,13 +1375,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) {
if (op > 3)
Out << ',';
writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op-2) :
ParamAttr::None);
writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op-2));
}
Out << " )";
if (PAL && PAL->getParamAttrs(0) != ParamAttr::None)
Out << " " << PAL->getParamAttrsTextByIndex(0);
if (PAL.getParamAttrs(0) != ParamAttr::None)
Out << " " << ParamAttr::getAsString(PAL.getParamAttrs(0));
Out << "\n\t\t\tto";
writeOperand(II->getNormalDest(), true);
Out << " unwind";
@ -1529,18 +1525,6 @@ 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);
ParameterAttributes attrs = getParamAttrs(index);
cerr << "{" << index << "," << attrs << "} ";
}
cerr << "]\n";
}
//===----------------------------------------------------------------------===//
// SlotMachine Implementation
//===----------------------------------------------------------------------===//

View File

@ -17,7 +17,7 @@
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/ADT/SmallVector.h"
#include <cstring>
using namespace llvm;
@ -226,18 +226,18 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
case Intrinsic::x86_mmx_psrl_d:
case Intrinsic::x86_mmx_psrl_q:
case Intrinsic::x86_mmx_psrl_w: {
SmallVector<Value*, 2> Operands;
Value *Operands[2];
Operands.push_back(CI->getOperand(1));
Operands[0] = CI->getOperand(1);
// Cast the second parameter to the correct type.
BitCastInst *BC = new BitCastInst(CI->getOperand(2),
NewFn->getFunctionType()->getParamType(1),
"upgraded", CI);
Operands.push_back(BC);
Operands[1] = BC;
// Construct a new CallInst
CallInst *NewCI = new CallInst(NewFn, Operands.begin(), Operands.end(),
CallInst *NewCI = new CallInst(NewFn, Operands, Operands+2,
"upgraded."+CI->getName(), CI);
NewCI->setTailCall(CI->isTailCall());
NewCI->setCallingConv(CI->getCallingConv());
@ -257,7 +257,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
case Intrinsic::cttz:
// Build a small vector of the 1..(N-1) operands, which are the
// parameters.
SmallVector<Value*, 8> Operands(CI->op_begin()+1, CI->op_end());
SmallVector<Value*, 8> Operands(CI->op_begin()+1, CI->op_end());
// Construct a new CallInst
CallInst *NewCI = new CallInst(NewFn, Operands.begin(), Operands.end(),
@ -268,10 +268,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Handle any uses of the old CallInst.
if (!CI->use_empty()) {
// Check for sign extend parameter attributes on the return values.
bool SrcSExt = NewFn->getParamAttrs() &&
NewFn->getParamAttrs()->paramHasAttr(0,ParamAttr::SExt);
bool DestSExt = F->getParamAttrs() &&
F->getParamAttrs()->paramHasAttr(0,ParamAttr::SExt);
bool SrcSExt = NewFn->getParamAttrs().paramHasAttr(0, ParamAttr::SExt);
bool DestSExt = F->getParamAttrs().paramHasAttr(0, ParamAttr::SExt);
// Construct an appropriate cast from the new return type to the old.
CastInst *RetCast = CastInst::create(

View File

@ -14,7 +14,6 @@
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/StringPool.h"
@ -140,12 +139,12 @@ void Function::eraseFromParent() {
/// @brief Determine whether the function has the given attribute.
bool Function::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
return ParamAttrs && ParamAttrs->paramHasAttr(i, attr);
return ParamAttrs.paramHasAttr(i, attr);
}
/// @brief Extract the alignment for a call or parameter (0=unknown).
uint16_t Function::getParamAlignment(uint16_t i) const {
return ParamAttrs ? ParamAttrs->getParamAlignment(i) : 0;
return ParamAttrs.getParamAlignment(i);
}
/// @brief Determine if the function cannot return.
@ -181,8 +180,7 @@ bool Function::hasStructRetAttr() const {
Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
const std::string &name, Module *ParentModule)
: GlobalValue(PointerType::getUnqual(Ty),
Value::FunctionVal, 0, 0, Linkage, name),
ParamAttrs(0) {
Value::FunctionVal, 0, 0, Linkage, name) {
SymTab = new ValueSymbolTable();
assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy
@ -207,10 +205,6 @@ Function::~Function() {
ArgumentList.clear();
delete SymTab;
// Drop our reference to the parameter attributes, if any.
if (ParamAttrs)
ParamAttrs->dropRef();
// Remove the function from the on-the-side collector table.
clearCollector();
}
@ -243,24 +237,6 @@ void Function::setParent(Module *parent) {
LeakDetector::removeGarbageObject(this);
}
void Function::setParamAttrs(const ParamAttrsList *attrs) {
// Avoid deleting the ParamAttrsList if they are setting the
// attributes to the same list.
if (ParamAttrs == attrs)
return;
// Drop reference on the old ParamAttrsList
if (ParamAttrs)
ParamAttrs->dropRef();
// Add reference to the new ParamAttrsList
if (attrs)
attrs->addRef();
// Set the new ParamAttrsList.
ParamAttrs = attrs;
}
// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining. This allows one to
// 'delete' a whole class at a time, even though there may be circular
@ -370,8 +346,7 @@ const FunctionType *Intrinsic::getType(ID id, const Type **Tys,
return FunctionType::get(ResultTy, ArgTys, IsVarArg);
}
const ParamAttrsList *Intrinsic::getParamAttrs(ID id) {
ParamAttrsVector Attrs;
PAListPtr Intrinsic::getParamAttrs(ID id) {
ParameterAttributes Attr = ParamAttr::None;
#define GET_INTRINSIC_ATTRIBUTES
@ -381,8 +356,8 @@ const ParamAttrsList *Intrinsic::getParamAttrs(ID id) {
// Intrinsics cannot throw exceptions.
Attr |= ParamAttr::NoUnwind;
Attrs.push_back(ParamAttrsWithIndex::get(0, Attr));
return ParamAttrsList::get(Attrs);
ParamAttrsWithIndex PAWI = ParamAttrsWithIndex::get(0, Attr);
return PAListPtr::get(&PAWI, 1);
}
Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys,

View File

@ -17,7 +17,6 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/MathExtras.h"
@ -43,13 +42,13 @@ void CallSite::setCallingConv(unsigned CC) {
else
cast<InvokeInst>(I)->setCallingConv(CC);
}
const ParamAttrsList* CallSite::getParamAttrs() const {
const PAListPtr &CallSite::getParamAttrs() const {
if (CallInst *CI = dyn_cast<CallInst>(I))
return CI->getParamAttrs();
else
return cast<InvokeInst>(I)->getParamAttrs();
}
void CallSite::setParamAttrs(const ParamAttrsList *PAL) {
void CallSite::setParamAttrs(const PAListPtr &PAL) {
if (CallInst *CI = dyn_cast<CallInst>(I))
CI->setParamAttrs(PAL);
else
@ -243,12 +242,9 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
CallInst::~CallInst() {
delete [] OperandList;
if (ParamAttrs)
ParamAttrs->dropRef();
}
void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
ParamAttrs = 0;
NumOperands = NumParams+1;
Use *OL = OperandList = new Use[NumParams+1];
OL[0].init(Func, this);
@ -269,7 +265,6 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
}
void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
ParamAttrs = 0;
NumOperands = 3;
Use *OL = OperandList = new Use[3];
OL[0].init(Func, this);
@ -292,7 +287,6 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
}
void CallInst::init(Value *Func, Value *Actual) {
ParamAttrs = 0;
NumOperands = 2;
Use *OL = OperandList = new Use[2];
OL[0].init(Func, this);
@ -311,7 +305,6 @@ void CallInst::init(Value *Func, Value *Actual) {
}
void CallInst::init(Value *Func) {
ParamAttrs = 0;
NumOperands = 1;
Use *OL = OperandList = new Use[1];
OL[0].init(Func, this);
@ -360,8 +353,7 @@ CallInst::CallInst(Value *Func, const std::string &Name,
CallInst::CallInst(const CallInst &CI)
: Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()],
CI.getNumOperands()),
ParamAttrs(0) {
CI.getNumOperands()) {
setParamAttrs(CI.getParamAttrs());
SubclassData = CI.SubclassData;
Use *OL = OperandList;
@ -370,21 +362,8 @@ CallInst::CallInst(const CallInst &CI)
OL[i].init(InOL[i], this);
}
void CallInst::setParamAttrs(const ParamAttrsList *newAttrs) {
if (ParamAttrs == newAttrs)
return;
if (ParamAttrs)
ParamAttrs->dropRef();
if (newAttrs)
newAttrs->addRef();
ParamAttrs = newAttrs;
}
bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
if (ParamAttrs.paramHasAttr(i, attr))
return true;
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
@ -392,11 +371,7 @@ bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
}
uint16_t CallInst::getParamAlignment(uint16_t i) const {
if (ParamAttrs && ParamAttrs->getParamAlignment(i))
return ParamAttrs->getParamAlignment(i);
if (const Function *F = getCalledFunction())
return F->getParamAlignment(i);
return 0;
return ParamAttrs.getParamAlignment(i);
}
/// @brief Determine if the call does not access memory.
@ -428,21 +403,20 @@ bool CallInst::hasStructRetAttr() const {
/// @brief Determine if any call argument is an aggregate passed by value.
bool CallInst::hasByValArgument() const {
if (ParamAttrs && ParamAttrs->hasAttrSomewhere(ParamAttr::ByVal))
if (ParamAttrs.hasAttrSomewhere(ParamAttr::ByVal))
return true;
// Be consistent with other methods and check the callee too.
if (const Function *F = getCalledFunction())
if (const ParamAttrsList *PAL = F->getParamAttrs())
return PAL->hasAttrSomewhere(ParamAttr::ByVal);
return F->getParamAttrs().hasAttrSomewhere(ParamAttr::ByVal);
return false;
}
void CallInst::setDoesNotThrow(bool doesNotThrow) {
const ParamAttrsList *PAL = getParamAttrs();
PAListPtr PAL = getParamAttrs();
if (doesNotThrow)
PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
else
PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
setParamAttrs(PAL);
}
@ -453,13 +427,10 @@ void CallInst::setDoesNotThrow(bool doesNotThrow) {
InvokeInst::~InvokeInst() {
delete [] OperandList;
if (ParamAttrs)
ParamAttrs->dropRef();
}
void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs) {
ParamAttrs = 0;
NumOperands = 3+NumArgs;
Use *OL = OperandList = new Use[3+NumArgs];
OL[0].init(Fn, this);
@ -484,8 +455,7 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
InvokeInst::InvokeInst(const InvokeInst &II)
: TerminatorInst(II.getType(), Instruction::Invoke,
new Use[II.getNumOperands()], II.getNumOperands()),
ParamAttrs(0) {
new Use[II.getNumOperands()], II.getNumOperands()) {
setParamAttrs(II.getParamAttrs());
SubclassData = II.SubclassData;
Use *OL = OperandList, *InOL = II.OperandList;
@ -503,21 +473,8 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) {
return setSuccessor(idx, B);
}
void InvokeInst::setParamAttrs(const ParamAttrsList *newAttrs) {
if (ParamAttrs == newAttrs)
return;
if (ParamAttrs)
ParamAttrs->dropRef();
if (newAttrs)
newAttrs->addRef();
ParamAttrs = newAttrs;
}
bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
if (ParamAttrs.paramHasAttr(i, attr))
return true;
if (const Function *F = getCalledFunction())
return F->paramHasAttr(i, attr);
@ -525,11 +482,7 @@ bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
}
uint16_t InvokeInst::getParamAlignment(uint16_t i) const {
if (ParamAttrs && ParamAttrs->getParamAlignment(i))
return ParamAttrs->getParamAlignment(i);
if (const Function *F = getCalledFunction())
return F->getParamAlignment(i);
return 0;
return ParamAttrs.getParamAlignment(i);
}
/// @brief Determine if the call does not access memory.
@ -553,11 +506,11 @@ bool InvokeInst::doesNotThrow() const {
}
void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
const ParamAttrsList *PAL = getParamAttrs();
PAListPtr PAL = getParamAttrs();
if (doesNotThrow)
PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
else
PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
setParamAttrs(PAL);
}

View File

@ -11,41 +11,19 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/ParamAttrsList.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ParameterAttributes.h"
#include "llvm/Type.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/ManagedStatic.h"
using namespace llvm;
static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists;
//===----------------------------------------------------------------------===//
// ParamAttr Function Definitions
//===----------------------------------------------------------------------===//
ParamAttrsList::ParamAttrsList(const ParamAttrsVector &attrVec)
: attrs(attrVec), refCount(0) {
}
ParamAttrsList::~ParamAttrsList() {
ParamAttrsLists->RemoveNode(this);
}
ParameterAttributes
ParamAttrsList::getParamAttrs(uint16_t Index) const {
unsigned limit = attrs.size();
for (unsigned i = 0; i < limit && attrs[i].index <= Index; ++i)
if (attrs[i].index == Index)
return attrs[i].attrs;
return ParamAttr::None;
}
bool ParamAttrsList::hasAttrSomewhere(ParameterAttributes attr) const {
for (unsigned i = 0, e = attrs.size(); i < e; ++i)
if (attrs[i].attrs & attr)
return true;
return false;
}
std::string
ParamAttrsList::getParamAttrsText(ParameterAttributes Attrs) {
std::string ParamAttr::getAsString(ParameterAttributes Attrs) {
std::string Result;
if (Attrs & ParamAttr::ZExt)
Result += "zeroext ";
@ -77,155 +55,240 @@ ParamAttrsList::getParamAttrsText(ParameterAttributes Attrs) {
return Result;
}
void ParamAttrsList::Profile(FoldingSetNodeID &ID,
const ParamAttrsVector &Attrs) {
for (unsigned i = 0; i < Attrs.size(); ++i)
ID.AddInteger(uint64_t(Attrs[i].attrs) << 16 | unsigned(Attrs[i].index));
ParameterAttributes ParamAttr::typeIncompatible(const Type *Ty) {
ParameterAttributes Incompatible = None;
if (!Ty->isInteger())
// Attributes that only apply to integers.
Incompatible |= SExt | ZExt;
if (!isa<PointerType>(Ty))
// Attributes that only apply to pointers.
Incompatible |= ByVal | Nest | NoAlias | StructRet;
return Incompatible;
}
const ParamAttrsList *
ParamAttrsList::get(const ParamAttrsVector &attrVec) {
// If there are no attributes then return a null ParamAttrsList pointer.
if (attrVec.empty())
return 0;
//===----------------------------------------------------------------------===//
// ParamAttributeListImpl Definition
//===----------------------------------------------------------------------===//
namespace llvm {
class ParamAttributeListImpl : public FoldingSetNode {
unsigned RefCount;
// ParamAttrsList is uniqued, these should not be publicly available
void operator=(const ParamAttributeListImpl &); // Do not implement
ParamAttributeListImpl(const ParamAttributeListImpl &); // Do not implement
~ParamAttributeListImpl(); // Private implementation
public:
SmallVector<ParamAttrsWithIndex, 4> Attrs;
ParamAttributeListImpl(const ParamAttrsWithIndex *Attr, unsigned NumAttrs)
: Attrs(Attr, Attr+NumAttrs) {
RefCount = 0;
}
void AddRef() { ++RefCount; }
void DropRef() { if (--RefCount == 0) delete this; }
void Profile(FoldingSetNodeID &ID) const {
Profile(ID, &Attrs[0], Attrs.size());
}
static void Profile(FoldingSetNodeID &ID, const ParamAttrsWithIndex *Attr,
unsigned NumAttrs) {
for (unsigned i = 0; i != NumAttrs; ++i)
ID.AddInteger(uint64_t(Attr[i].Attrs) << 32 | unsigned(Attr[i].Index));
}
};
}
static ManagedStatic<FoldingSet<ParamAttributeListImpl> > ParamAttrsLists;
ParamAttributeListImpl::~ParamAttributeListImpl() {
ParamAttrsLists->RemoveNode(this);
}
PAListPtr PAListPtr::get(const ParamAttrsWithIndex *Attrs, unsigned NumAttrs) {
// If there are no attributes then return a null ParamAttrsList pointer.
if (NumAttrs == 0)
return PAListPtr();
#ifndef NDEBUG
for (unsigned i = 0, e = attrVec.size(); i < e; ++i) {
assert(attrVec[i].attrs != ParamAttr::None
&& "Pointless parameter attribute!");
assert((!i || attrVec[i-1].index < attrVec[i].index)
&& "Misordered ParamAttrsList!");
for (unsigned i = 0; i != NumAttrs; ++i) {
assert(Attrs[i].Attrs != ParamAttr::None &&
"Pointless parameter attribute!");
assert((!i || Attrs[i-1].Index < Attrs[i].Index) &&
"Misordered ParamAttrsList!");
}
#endif
// Otherwise, build a key to look up the existing attributes.
FoldingSetNodeID ID;
ParamAttrsList::Profile(ID, attrVec);
ParamAttributeListImpl::Profile(ID, Attrs, NumAttrs);
void *InsertPos;
ParamAttrsList *PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos);
ParamAttributeListImpl *PAL =
ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos);
// If we didn't find any existing attributes of the same shape then
// create a new one and insert it.
if (!PAL) {
PAL = new ParamAttrsList(attrVec);
PAL = new ParamAttributeListImpl(Attrs, NumAttrs);
ParamAttrsLists->InsertNode(PAL, InsertPos);
}
// Return the ParamAttrsList that we found or created.
return PAL;
return PAListPtr(PAL);
}
const ParamAttrsList *
ParamAttrsList::getModified(const ParamAttrsList *PAL,
const ParamAttrsVector &modVec) {
if (modVec.empty())
return PAL;
#ifndef NDEBUG
for (unsigned i = 0, e = modVec.size(); i < e; ++i)
assert((!i || modVec[i-1].index < modVec[i].index)
&& "Misordered ParamAttrsList!");
#endif
//===----------------------------------------------------------------------===//
// PAListPtr Method Implementations
//===----------------------------------------------------------------------===//
if (!PAL) {
// Strip any instances of ParamAttr::None from modVec before calling 'get'.
ParamAttrsVector newVec;
newVec.reserve(modVec.size());
for (unsigned i = 0, e = modVec.size(); i < e; ++i)
if (modVec[i].attrs != ParamAttr::None)
newVec.push_back(modVec[i]);
return get(newVec);
}
const ParamAttrsVector &oldVec = PAL->attrs;
ParamAttrsVector newVec;
unsigned oldI = 0;
unsigned modI = 0;
unsigned oldE = oldVec.size();
unsigned modE = modVec.size();
while (oldI < oldE && modI < modE) {
uint16_t oldIndex = oldVec[oldI].index;
uint16_t modIndex = modVec[modI].index;
if (oldIndex < modIndex) {
newVec.push_back(oldVec[oldI]);
++oldI;
} else if (modIndex < oldIndex) {
if (modVec[modI].attrs != ParamAttr::None)
newVec.push_back(modVec[modI]);
++modI;
} else {
// Same index - overwrite or delete existing attributes.
if (modVec[modI].attrs != ParamAttr::None)
newVec.push_back(modVec[modI]);
++oldI;
++modI;
}
}
for (; oldI < oldE; ++oldI)
newVec.push_back(oldVec[oldI]);
for (; modI < modE; ++modI)
if (modVec[modI].attrs != ParamAttr::None)
newVec.push_back(modVec[modI]);
return get(newVec);
PAListPtr::PAListPtr(ParamAttributeListImpl *LI) : PAList(LI) {
if (LI) LI->AddRef();
}
const ParamAttrsList *
ParamAttrsList::includeAttrs(const ParamAttrsList *PAL,
uint16_t idx, ParameterAttributes attrs) {
ParameterAttributes OldAttrs = PAL ? PAL->getParamAttrs(idx) :
ParamAttr::None;
PAListPtr::PAListPtr(const PAListPtr &P) : PAList(P.PAList) {
if (PAList) PAList->AddRef();
}
const PAListPtr &PAListPtr::operator=(const PAListPtr &RHS) {
if (PAList == RHS.PAList) return *this;
if (PAList) PAList->DropRef();
PAList = RHS.PAList;
if (PAList) PAList->AddRef();
return *this;
}
PAListPtr::~PAListPtr() {
if (PAList) PAList->DropRef();
}
/// getNumSlots - Return the number of slots used in this attribute list.
/// This is the number of arguments that have an attribute set on them
/// (including the function itself).
unsigned PAListPtr::getNumSlots() const {
return PAList ? PAList->Attrs.size() : 0;
}
/// getSlot - Return the ParamAttrsWithIndex at the specified slot. This
/// holds a parameter number plus a set of attributes.
const ParamAttrsWithIndex &PAListPtr::getSlot(unsigned Slot) const {
assert(PAList && Slot < PAList->Attrs.size() && "Slot # out of range!");
return PAList->Attrs[Slot];
}
/// getParamAttrs - The parameter attributes for the specified parameter are
/// returned. Parameters for the result are denoted with Idx = 0.
ParameterAttributes PAListPtr::getParamAttrs(unsigned Idx) const {
if (PAList == 0) return ParamAttr::None;
const SmallVector<ParamAttrsWithIndex, 4> &Attrs = PAList->Attrs;
for (unsigned i = 0, e = Attrs.size(); i != e && Attrs[i].Index <= Idx; ++i)
if (Attrs[i].Index == Idx)
return Attrs[i].Attrs;
return ParamAttr::None;
}
/// hasAttrSomewhere - Return true if the specified attribute is set for at
/// least one parameter or for the return value.
bool PAListPtr::hasAttrSomewhere(ParameterAttributes Attr) const {
if (PAList == 0) return false;
const SmallVector<ParamAttrsWithIndex, 4> &Attrs = PAList->Attrs;
for (unsigned i = 0, e = Attrs.size(); i != e; ++i)
if (Attrs[i].Attrs & Attr)
return true;
return false;
}
PAListPtr PAListPtr::addAttr(unsigned Idx, ParameterAttributes Attrs) const {
ParameterAttributes OldAttrs = getParamAttrs(Idx);
#ifndef NDEBUG
// FIXME it is not obvious how this should work for alignment.
// For now, say we can't change a known alignment.
ParameterAttributes OldAlign = OldAttrs & ParamAttr::Alignment;
ParameterAttributes NewAlign = attrs & ParamAttr::Alignment;
ParameterAttributes NewAlign = Attrs & ParamAttr::Alignment;
assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
"Attempt to change alignment!");
#endif
ParameterAttributes NewAttrs = OldAttrs | attrs;
ParameterAttributes NewAttrs = OldAttrs | Attrs;
if (NewAttrs == OldAttrs)
return PAL;
return *this;
SmallVector<ParamAttrsWithIndex, 8> NewAttrList;
if (PAList == 0)
NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs));
else {
const SmallVector<ParamAttrsWithIndex, 4> &OldAttrList = PAList->Attrs;
unsigned i = 0, e = OldAttrList.size();
// Copy attributes for arguments before this one.
for (; i != e && OldAttrList[i].Index < Idx; ++i)
NewAttrList.push_back(OldAttrList[i]);
ParamAttrsVector modVec(1);
modVec[0] = ParamAttrsWithIndex::get(idx, NewAttrs);
return getModified(PAL, modVec);
// If there are attributes already at this index, merge them in.
if (i != e && OldAttrList[i].Index == Idx) {
Attrs |= OldAttrList[i].Attrs;
++i;
}
NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs));
// Copy attributes for arguments after this one.
NewAttrList.insert(NewAttrList.end(),
OldAttrList.begin()+i, OldAttrList.end());
}
return get(&NewAttrList[0], NewAttrList.size());
}
const ParamAttrsList *
ParamAttrsList::excludeAttrs(const ParamAttrsList *PAL,
uint16_t idx, ParameterAttributes attrs) {
PAListPtr PAListPtr::removeAttr(unsigned Idx, ParameterAttributes Attrs) const {
#ifndef NDEBUG
// FIXME it is not obvious how this should work for alignment.
// For now, say we can't pass in alignment, which no current use does.
assert(!(attrs & ParamAttr::Alignment) && "Attempt to exclude alignment!");
assert(!(Attrs & ParamAttr::Alignment) && "Attempt to exclude alignment!");
#endif
ParameterAttributes OldAttrs = PAL ? PAL->getParamAttrs(idx) :
ParamAttr::None;
ParameterAttributes NewAttrs = OldAttrs & ~attrs;
if (PAList == 0) return PAListPtr();
ParameterAttributes OldAttrs = getParamAttrs(Idx);
ParameterAttributes NewAttrs = OldAttrs & ~Attrs;
if (NewAttrs == OldAttrs)
return PAL;
return *this;
ParamAttrsVector modVec(1);
modVec[0] = ParamAttrsWithIndex::get(idx, NewAttrs);
return getModified(PAL, modVec);
SmallVector<ParamAttrsWithIndex, 8> NewAttrList;
const SmallVector<ParamAttrsWithIndex, 4> &OldAttrList = PAList->Attrs;
unsigned i = 0, e = OldAttrList.size();
// Copy attributes for arguments before this one.
for (; i != e && OldAttrList[i].Index < Idx; ++i)
NewAttrList.push_back(OldAttrList[i]);
// If there are attributes already at this index, merge them in.
assert(OldAttrList[i].Index == Idx && "Attribute isn't set?");
Attrs = OldAttrList[i].Attrs & ~Attrs;
++i;
if (Attrs) // If any attributes left for this parameter, add them.
NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs));
// Copy attributes for arguments after this one.
NewAttrList.insert(NewAttrList.end(),
OldAttrList.begin()+i, OldAttrList.end());
return get(&NewAttrList[0], NewAttrList.size());
}
ParameterAttributes ParamAttr::typeIncompatible (const Type *Ty) {
ParameterAttributes Incompatible = None;
if (!Ty->isInteger())
// Attributes that only apply to integers.
Incompatible |= SExt | ZExt;
if (!isa<PointerType>(Ty))
// Attributes that only apply to pointers.
Incompatible |= ByVal | Nest | NoAlias | StructRet;
return Incompatible;
void PAListPtr::dump() const {
cerr << "PAL[ ";
for (unsigned i = 0; i < getNumSlots(); ++i) {
const ParamAttrsWithIndex &PAWI = getSlot(i);
cerr << "{" << PAWI.Index << "," << PAWI.Attrs << "} ";
}
cerr << "]\n";
}

View File

@ -40,18 +40,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
@ -264,7 +263,7 @@ namespace { // Anonymous namespace for class
unsigned Count, ...);
void VerifyAttrs(ParameterAttributes Attrs, const Type *Ty,
bool isReturnValue, const Value *V);
void VerifyFunctionAttrs(const FunctionType *FT, const ParamAttrsList *Attrs,
void VerifyFunctionAttrs(const FunctionType *FT, const PAListPtr &Attrs,
const Value *V);
void WriteValue(const Value *V) {
@ -394,11 +393,11 @@ void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty,
if (isReturnValue) {
ParameterAttributes RetI = Attrs & ParamAttr::ParameterOnly;
Assert1(!RetI, "Attribute " + ParamAttrsList::getParamAttrsText(RetI) +
Assert1(!RetI, "Attribute " + ParamAttr::getAsString(RetI) +
"does not apply to return values!", V);
} else {
ParameterAttributes ParmI = Attrs & ParamAttr::ReturnOnly;
Assert1(!ParmI, "Attribute " + ParamAttrsList::getParamAttrsText(ParmI) +
Assert1(!ParmI, "Attribute " + ParamAttr::getAsString(ParmI) +
"only applies to return values!", V);
}
@ -406,37 +405,44 @@ void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty,
i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) {
ParameterAttributes MutI = Attrs & ParamAttr::MutuallyIncompatible[i];
Assert1(!(MutI & (MutI - 1)), "Attributes " +
ParamAttrsList::getParamAttrsText(MutI) + "are incompatible!", V);
ParamAttr::getAsString(MutI) + "are incompatible!", V);
}
ParameterAttributes TypeI = Attrs & ParamAttr::typeIncompatible(Ty);
Assert1(!TypeI, "Wrong type for attribute " +
ParamAttrsList::getParamAttrsText(TypeI), V);
ParamAttr::getAsString(TypeI), V);
}
// VerifyFunctionAttrs - Check parameter attributes against a function type.
// The value V is printed in error messages.
void Verifier::VerifyFunctionAttrs(const FunctionType *FT,
const ParamAttrsList *Attrs,
const PAListPtr &Attrs,
const Value *V) {
if (!Attrs)
if (Attrs.isEmpty())
return;
bool SawNest = false;
for (unsigned Idx = 0; Idx <= FT->getNumParams(); ++Idx) {
ParameterAttributes Attr = Attrs->getParamAttrs(Idx);
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
const ParamAttrsWithIndex &Attr = Attrs.getSlot(i);
VerifyAttrs(Attr, FT->getParamType(Idx-1), !Idx, V);
const Type *Ty;
if (Attr.Index == 0)
Ty = FT->getReturnType();
else if (Attr.Index-1 < FT->getNumParams())
Ty = FT->getParamType(Attr.Index-1);
else
break; // VarArgs attributes, don't verify.
VerifyAttrs(Attr.Attrs, Ty, Attr.Index == 0, V);
if (Attr & ParamAttr::Nest) {
if (Attr.Attrs & ParamAttr::Nest) {
Assert1(!SawNest, "More than one parameter has attribute nest!", V);
SawNest = true;
}
if (Attr & ParamAttr::StructRet) {
Assert1(Idx == 1, "Attribute sret not on first parameter!", V);
}
if (Attr.Attrs & ParamAttr::StructRet)
Assert1(Attr.Index == 1, "Attribute sret not on first parameter!", V);
}
}
@ -458,11 +464,10 @@ void Verifier::visitFunction(Function &F) {
Assert1(!F.hasStructRetAttr() || F.getReturnType() == Type::VoidTy,
"Invalid struct return type!", &F);
const ParamAttrsList *Attrs = F.getParamAttrs();
const PAListPtr &Attrs = F.getParamAttrs();
Assert1(!Attrs ||
(Attrs->size() &&
Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams()),
Assert1(Attrs.isEmpty() ||
Attrs.getSlot(Attrs.getNumSlots()-1).Index <= FT->getNumParams(),
"Attributes after last parameter!", &F);
// Check function attributes.
@ -712,15 +717,19 @@ void Verifier::visitUIToFPInst(UIToFPInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
bool SrcVec = isa<VectorType>(SrcTy);
bool DstVec = isa<VectorType>(DestTy);
Assert1(SrcVec == DstVec,"UIToFP source and dest must both be vector or scalar", &I);
Assert1(SrcTy->isIntOrIntVector(),"UIToFP source must be integer or integer vector", &I);
Assert1(DestTy->isFPOrFPVector(),"UIToFP result must be FP or FP vector", &I);
Assert1(SrcVec == DstVec,
"UIToFP source and dest must both be vector or scalar", &I);
Assert1(SrcTy->isIntOrIntVector(),
"UIToFP source must be integer or integer vector", &I);
Assert1(DestTy->isFPOrFPVector(),
"UIToFP result must be FP or FP vector", &I);
if (SrcVec && DstVec)
Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(),
Assert1(cast<VectorType>(SrcTy)->getNumElements() ==
cast<VectorType>(DestTy)->getNumElements(),
"UIToFP source and dest vector length mismatch", &I);
visitInstruction(I);
@ -734,12 +743,16 @@ void Verifier::visitSIToFPInst(SIToFPInst &I) {
bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
Assert1(SrcVec == DstVec,"SIToFP source and dest must both be vector or scalar", &I);
Assert1(SrcTy->isIntOrIntVector(),"SIToFP source must be integer or integer vector", &I);
Assert1(DestTy->isFPOrFPVector(),"SIToFP result must be FP or FP vector", &I);
Assert1(SrcVec == DstVec,
"SIToFP source and dest must both be vector or scalar", &I);
Assert1(SrcTy->isIntOrIntVector(),
"SIToFP source must be integer or integer vector", &I);
Assert1(DestTy->isFPOrFPVector(),
"SIToFP result must be FP or FP vector", &I);
if (SrcVec && DstVec)
Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(),
Assert1(cast<VectorType>(SrcTy)->getNumElements() ==
cast<VectorType>(DestTy)->getNumElements(),
"SIToFP source and dest vector length mismatch", &I);
visitInstruction(I);
@ -750,15 +763,18 @@ void Verifier::visitFPToUIInst(FPToUIInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
bool SrcVec = isa<VectorType>(SrcTy);
bool DstVec = isa<VectorType>(DestTy);
Assert1(SrcVec == DstVec,"FPToUI source and dest must both be vector or scalar", &I);
Assert1(SrcTy->isFPOrFPVector(),"FPToUI source must be FP or FP vector", &I);
Assert1(DestTy->isIntOrIntVector(),"FPToUI result must be integer or integer vector", &I);
Assert1(SrcVec == DstVec,
"FPToUI source and dest must both be vector or scalar", &I);
Assert1(SrcTy->isFPOrFPVector(), "FPToUI source must be FP or FP vector", &I);
Assert1(DestTy->isIntOrIntVector(),
"FPToUI result must be integer or integer vector", &I);
if (SrcVec && DstVec)
Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(),
Assert1(cast<VectorType>(SrcTy)->getNumElements() ==
cast<VectorType>(DestTy)->getNumElements(),
"FPToUI source and dest vector length mismatch", &I);
visitInstruction(I);
@ -769,15 +785,19 @@ void Verifier::visitFPToSIInst(FPToSIInst &I) {
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
bool SrcVec = isa<VectorType>(SrcTy);
bool DstVec = isa<VectorType>(DestTy);
Assert1(SrcVec == DstVec,"FPToSI source and dest must both be vector or scalar", &I);
Assert1(SrcTy->isFPOrFPVector(),"FPToSI source must be FP or FP vector", &I);
Assert1(DestTy->isIntOrIntVector(),"FPToSI result must be integer or integer vector", &I);
Assert1(SrcVec == DstVec,
"FPToSI source and dest must both be vector or scalar", &I);
Assert1(SrcTy->isFPOrFPVector(),
"FPToSI source must be FP or FP vector", &I);
Assert1(DestTy->isIntOrIntVector(),
"FPToSI result must be integer or integer vector", &I);
if (SrcVec && DstVec)
Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(),
Assert1(cast<VectorType>(SrcTy)->getNumElements() ==
cast<VectorType>(DestTy)->getNumElements(),
"FPToSI source and dest vector length mismatch", &I);
visitInstruction(I);
@ -871,25 +891,24 @@ void Verifier::VerifyCallSite(CallSite CS) {
"Call parameter type does not match function signature!",
CS.getArgument(i), FTy->getParamType(i), I);
const ParamAttrsList *Attrs = CS.getParamAttrs();
const PAListPtr &Attrs = CS.getParamAttrs();
Assert1(!Attrs ||
(Attrs->size() &&
Attrs->getParamIndex(Attrs->size()-1) <= CS.arg_size()),
"Attributes after last argument!", I);
Assert1(Attrs.isEmpty() ||
Attrs.getSlot(Attrs.getNumSlots()-1).Index <= CS.arg_size(),
"Attributes after last parameter!", I);
// Verify call attributes.
VerifyFunctionAttrs(FTy, Attrs, I);
if (Attrs && FTy->isVarArg())
if (FTy->isVarArg())
// Check attributes on the varargs part.
for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) {
ParameterAttributes Attr = Attrs->getParamAttrs(Idx);
ParameterAttributes Attr = Attrs.getParamAttrs(Idx);
VerifyAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I);
ParameterAttributes VArgI = Attr & ParamAttr::VarArgsIncompatible;
Assert1(!VArgI, "Attribute " + ParamAttrsList::getParamAttrsText(VArgI) +
Assert1(!VArgI, "Attribute " + ParamAttr::getAsString(VArgI) +
"cannot be used for vararg call arguments!", I);
}

File diff suppressed because it is too large Load Diff

View File

@ -346,7 +346,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 1681 "/Volumes/MacOS9/gcc/llvm/tools/llvm-upgrade/UpgradeParser.y"
#line 1680 "/Users/sabre/llvm/tools/llvm-upgrade/UpgradeParser.y"
{
llvm::Module *ModuleVal;
llvm::Function *FunctionVal;

View File

@ -17,7 +17,6 @@
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/ADT/STLExtras.h"
@ -2056,13 +2055,11 @@ UpRTypes
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
if (isVarArg) Params.pop_back();
const ParamAttrsList *PAL = 0;
PAListPtr PAL;
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);
ParamAttrsWithIndex PAWI =
ParamAttrsWithIndex::get(1, ParamAttr::StructRet);
PAL = PAListPtr::get(&PAWI, 1);
}
const FunctionType *FTy =
@ -2974,11 +2971,9 @@ FunctionHeaderH
// Convert the CSRet calling convention into the corresponding parameter
// attribute.
if ($1 == OldCallingConv::CSRet) {
ParamAttrsVector Attrs;
ParamAttrsWithIndex PAWI;
PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
Attrs.push_back(PAWI);
Fn->setParamAttrs(ParamAttrsList::get(Attrs));
ParamAttrsWithIndex PAWI =
ParamAttrsWithIndex::get(1, ParamAttr::StructRet); // first arg
Fn->setParamAttrs(PAListPtr::get(&PAWI, 1));
}
// Add all of the arguments we parsed to the function...
@ -3296,11 +3291,9 @@ BBTerminatorInst
}
cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2));
if ($2 == OldCallingConv::CSRet) {
ParamAttrsVector Attrs;
ParamAttrsWithIndex PAWI;
PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
Attrs.push_back(PAWI);
cast<InvokeInst>($$.TI)->setParamAttrs(ParamAttrsList::get(Attrs));
ParamAttrsWithIndex PAWI =
ParamAttrsWithIndex::get(1, ParamAttr::StructRet); // first arg
cast<InvokeInst>($$.TI)->setParamAttrs(PAListPtr::get(&PAWI, 1));
}
delete $3.PAT;
delete $6;
@ -3715,11 +3708,9 @@ InstVal
}
// Deal with CSRetCC
if ($2 == OldCallingConv::CSRet) {
ParamAttrsVector Attrs;
ParamAttrsWithIndex PAWI;
PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
Attrs.push_back(PAWI);
cast<CallInst>($$.I)->setParamAttrs(ParamAttrsList::get(Attrs));
ParamAttrsWithIndex PAWI =
ParamAttrsWithIndex::get(1, ParamAttr::StructRet); // first arg
cast<CallInst>($$.I)->setParamAttrs(PAListPtr::get(&PAWI, 1));
}
delete $3.PAT;
delete $6;

View File

@ -17,7 +17,6 @@
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/ADT/STLExtras.h"
@ -2056,13 +2055,11 @@ UpRTypes
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
if (isVarArg) Params.pop_back();
const ParamAttrsList *PAL = 0;
PAListPtr PAL;
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);
ParamAttrsWithIndex PAWI =
ParamAttrsWithIndex::get(1, ParamAttr::StructRet);
PAL = PAListPtr::get(&PAWI, 1);
}
const FunctionType *FTy =
@ -2974,11 +2971,9 @@ FunctionHeaderH
// Convert the CSRet calling convention into the corresponding parameter
// attribute.
if ($1 == OldCallingConv::CSRet) {
ParamAttrsVector Attrs;
ParamAttrsWithIndex PAWI;
PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
Attrs.push_back(PAWI);
Fn->setParamAttrs(ParamAttrsList::get(Attrs));
ParamAttrsWithIndex PAWI =
ParamAttrsWithIndex::get(1, ParamAttr::StructRet); // first arg
Fn->setParamAttrs(PAListPtr::get(&PAWI, 1));
}
// Add all of the arguments we parsed to the function...
@ -3296,11 +3291,9 @@ BBTerminatorInst
}
cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2));
if ($2 == OldCallingConv::CSRet) {
ParamAttrsVector Attrs;
ParamAttrsWithIndex PAWI;
PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
Attrs.push_back(PAWI);
cast<InvokeInst>($$.TI)->setParamAttrs(ParamAttrsList::get(Attrs));
ParamAttrsWithIndex PAWI =
ParamAttrsWithIndex::get(1, ParamAttr::StructRet); // first arg
cast<InvokeInst>($$.TI)->setParamAttrs(PAListPtr::get(&PAWI, 1));
}
delete $3.PAT;
delete $6;
@ -3715,11 +3708,9 @@ InstVal
}
// Deal with CSRetCC
if ($2 == OldCallingConv::CSRet) {
ParamAttrsVector Attrs;
ParamAttrsWithIndex PAWI;
PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
Attrs.push_back(PAWI);
cast<CallInst>($$.I)->setParamAttrs(ParamAttrsList::get(Attrs));
ParamAttrsWithIndex PAWI =
ParamAttrsWithIndex::get(1, ParamAttr::StructRet); // first arg
cast<CallInst>($$.I)->setParamAttrs(PAListPtr::get(&PAWI, 1));
}
delete $3.PAT;
delete $6;

View File

@ -18,7 +18,6 @@
#include "llvm/InlineAsm.h"
#include "llvm/Instruction.h"
#include "llvm/Instructions.h"
#include "llvm/ParamAttrsList.h"
#include "llvm/Module.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/ADT/StringExtras.h"
@ -125,7 +124,7 @@ private:
std::string getCppName(const Value* val);
inline void printCppName(const Value* val);
void printParamAttrs(const ParamAttrsList* PAL, const std::string &name);
void printParamAttrs(const PAListPtr &PAL, const std::string &name);
bool printTypeInternal(const Type* Ty);
inline void printType(const Type* Ty);
void printTypes(const Module* M);
@ -438,16 +437,16 @@ CppWriter::printCppName(const Value* val) {
}
void
CppWriter::printParamAttrs(const ParamAttrsList* PAL, const std::string &name) {
Out << "ParamAttrsList *" << name << "_PAL = 0;";
CppWriter::printParamAttrs(const PAListPtr &PAL, const std::string &name) {
Out << "PAListPtr " << name << "_PAL = 0;";
nl(Out);
if (PAL) {
if (!PAL.isEmpty()) {
Out << '{'; in(); nl(Out);
Out << "ParamAttrsVector Attrs;"; nl(Out);
Out << "SmallVector<ParamAttrsWithIndex, 4> Attrs;"; nl(Out);
Out << "ParamAttrsWithIndex PAWI;"; nl(Out);
for (unsigned i = 0; i < PAL->size(); ++i) {
uint16_t index = PAL->getParamIndex(i);
ParameterAttributes attrs = PAL->getParamAttrs(index);
for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
uint16_t index = PAL.getSlot(i).Index;
ParameterAttributes attrs = PAL.getSlot(i).Attrs;
Out << "PAWI.index = " << index << "; PAWI.attrs = 0 ";
if (attrs & ParamAttr::SExt)
Out << " | ParamAttr::SExt";
@ -466,7 +465,7 @@ CppWriter::printParamAttrs(const ParamAttrsList* PAL, const std::string &name) {
Out << "Attrs.push_back(PAWI);";
nl(Out);
}
Out << name << "_PAL = ParamAttrsList::get(Attrs);";
Out << name << "_PAL = PAListPtr::get(Attrs.begin(), Attrs.end());";
nl(Out);
out(); nl(Out);
Out << '}'; nl(Out);
@ -1748,7 +1747,6 @@ void CppWriter::printProgram(
Out << "#include <llvm/BasicBlock.h>\n";
Out << "#include <llvm/Instructions.h>\n";
Out << "#include <llvm/InlineAsm.h>\n";
Out << "#include <llvm/ParamAttrsList.h>\n";
Out << "#include <llvm/Support/MathExtras.h>\n";
Out << "#include <llvm/Pass.h>\n";
Out << "#include <llvm/PassManager.h>\n";