Simplify working with LLVM attributes

This commit is contained in:
Martin 2015-11-01 16:06:45 +01:00
parent 3d803c7a1c
commit 90197d6c72
16 changed files with 67 additions and 83 deletions

View file

@ -8501,7 +8501,7 @@ Lagain:
*/
if (sd->size(loc) > Target::ptrsize * 4 && !t1->needsNested())
#if IN_LLVM
; // FIXME!!!
{} // FIXME!!!
#else
sle->sinit = toInitializer(sd);
#endif

View file

@ -83,8 +83,8 @@ struct PPC64TargetABI : TargetABI {
// the copy is treated as a local variable of the callee
// hence add the NoAlias and NoCapture attributes
arg.attrs.clear()
.add(LDC_ATTRIBUTE(NoAlias))
.add(LDC_ATTRIBUTE(NoCapture));
.add(LLAttribute::NoAlias)
.add(LLAttribute::NoCapture);
}
}
}

View file

@ -155,8 +155,8 @@ void Win64TargetABI::rewriteArgument(IrFuncTy& fty, IrFuncTyArg& arg)
// the copy is treated as a local variable of the callee
// hence add the NoAlias and NoCapture attributes
arg.attrs.clear()
.add(LDC_ATTRIBUTE(NoAlias))
.add(LDC_ATTRIBUTE(NoCapture));
.add(LLAttribute::NoAlias)
.add(LLAttribute::NoCapture);
}
else if (isAggregate(t) && canRewriteAsInt(t) && !IntegerRewrite::isObsoleteFor(originalLType))
{

View file

@ -282,7 +282,7 @@ void X86_64TargetABI::rewriteArgument(IrFuncTyArg& arg, RegCount& regCount) {
IF_LOG Logger::cout() << "Passing implicitly ByVal: " << arg.type->toChars() << " (" << *originalLType << ")\n";
arg.rewrite = &byvalRewrite;
arg.ltype = originalLType->getPointerTo();
arg.attrs.add(LDC_ATTRIBUTE(ByVal));
arg.attrs.add(LLAttribute::ByVal);
}
}

View file

@ -145,21 +145,19 @@ public:
if (fty.arg_this)
{
Logger::println("Putting 'this' in register");
fty.arg_this->attrs.clear()
.add(LDC_ATTRIBUTE(InReg));
fty.arg_this->attrs.clear().add(LLAttribute::InReg);
}
else if (fty.arg_nest)
{
Logger::println("Putting context ptr in register");
fty.arg_nest->attrs.clear()
.add(LDC_ATTRIBUTE(InReg));
fty.arg_nest->attrs.clear().add(LLAttribute::InReg);
}
else if (IrFuncTyArg* sret = fty.arg_sret)
{
Logger::println("Putting sret ptr in register");
// sret and inreg are incompatible, but the ABI requires the
// sret parameter to be in EAX in this situation...
sret->attrs.add(LDC_ATTRIBUTE(InReg)).remove(LDC_ATTRIBUTE(StructRet));
sret->attrs.add(LLAttribute::InReg).remove(LLAttribute::StructRet);
}
// otherwise try to mark the last param inreg
else if (!fty.args.empty())
@ -176,7 +174,7 @@ public:
if (last->byref && !last->isByVal())
{
Logger::println("Putting last (byref) parameter in register");
last->attrs.add(LDC_ATTRIBUTE(InReg));
last->attrs.add(LLAttribute::InReg);
}
else if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) // right?
{
@ -189,7 +187,7 @@ public:
// erase previous attributes
last->attrs.clear();
}
last->attrs.add(LDC_ATTRIBUTE(InReg));
last->attrs.add(LLAttribute::InReg);
}
}

View file

@ -12,67 +12,61 @@
bool AttrBuilder::hasAttributes() const
{
return attrs.hasAttributes();
return builder.hasAttributes();
}
bool AttrBuilder::contains(A attribute) const
bool AttrBuilder::contains(LLAttribute attribute) const
{
return attrs.contains(attribute);
return builder.contains(attribute);
}
AttrBuilder& AttrBuilder::clear()
{
attrs.clear();
builder.clear();
return *this;
}
AttrBuilder& AttrBuilder::add(A attribute)
AttrBuilder& AttrBuilder::add(LLAttribute attribute)
{
// never set 'None' explicitly
if (attribute)
attrs.addAttribute(attribute);
builder.addAttribute(attribute);
return *this;
}
AttrBuilder& AttrBuilder::remove(A attribute)
AttrBuilder& AttrBuilder::remove(LLAttribute attribute)
{
// never remove 'None' explicitly
if (attribute)
attrs.removeAttribute(attribute);
builder.removeAttribute(attribute);
return *this;
}
AttrBuilder& AttrBuilder::merge(const AttrBuilder& other)
{
attrs.merge(other.attrs);
builder.merge(other.builder);
return *this;
}
AttrSet AttrSet::extractFunctionAndReturnAttributes(const llvm::Function* function)
{
AttrSet set;
AttrSet r;
NativeSet old = function->getAttributes();
llvm::AttributeSet old = function->getAttributes();
llvm::AttributeSet existingAttrs[] = { old.getFnAttributes(), old.getRetAttributes() };
set.entries = llvm::AttributeSet::get(gIR->context(), existingAttrs);
r.set = llvm::AttributeSet::get(gIR->context(), existingAttrs);
return set;
return r;
}
AttrSet& AttrSet::add(unsigned index, const AttrBuilder& builder)
{
if (builder.hasAttributes())
{
AttrBuilder mutableBuilderCopy = builder;
llvm::AttributeSet as = llvm::AttributeSet::get(
gIR->context(), index, mutableBuilderCopy.attrs);
entries = entries.addAttributes(gIR->context(), index, as);
gIR->context(), index, builder);
set = set.addAttributes(gIR->context(), index, as);
}
return *this;
}
AttrSet::NativeSet AttrSet::toNativeSet() const
{
return entries;
}

View file

@ -12,47 +12,39 @@
#include "gen/llvm.h"
#include <map>
using LLAttribute = llvm::Attribute::AttrKind;
struct AttrBuilder
class AttrBuilder
{
// A: basic attribute type
// B: builder type
typedef llvm::Attribute::AttrKind A;
typedef llvm::AttrBuilder B;
llvm::AttrBuilder builder;
B attrs;
AttrBuilder() {}
AttrBuilder(const B& attrs) : attrs(attrs) {}
public:
AttrBuilder() = default;
bool hasAttributes() const;
bool contains(A attribute) const;
bool contains(LLAttribute attribute) const;
AttrBuilder& clear();
AttrBuilder& add(A attribute);
AttrBuilder& remove(A attribute);
AttrBuilder& add(LLAttribute attribute);
AttrBuilder& remove(LLAttribute attribute);
AttrBuilder& merge(const AttrBuilder& other);
operator llvm::AttrBuilder&() { return builder; }
operator const llvm::AttrBuilder&() const { return builder; }
};
struct AttrSet
class AttrSet
{
typedef llvm::AttributeSet NativeSet;
NativeSet entries;
llvm::AttributeSet set;
AttrSet() {}
public:
AttrSet() = default;
static AttrSet extractFunctionAndReturnAttributes(const llvm::Function* function);
AttrSet& add(unsigned index, const AttrBuilder& builder);
NativeSet toNativeSet() const;
operator llvm::AttributeSet&() { return set; }
operator const llvm::AttributeSet&() const { return set; }
};
// LDC_ATTRIBUTE(name) helper macro returning:
// * an AttrBuilder::A (enum) value for LLVM 3.2+,
// * or an llvm::Attribute::AttrConst value for LLVM 3.1,
// which can be implicitly converted to AttrBuilder::A
// (i.e., llvm::Attributes)
#define LDC_ATTRIBUTE(name) llvm::Attribute::name
#endif

View file

@ -77,7 +77,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
{
// sret return
newIrFty.arg_sret = new IrFuncTyArg(rt, true,
AttrBuilder().add(LDC_ATTRIBUTE(StructRet)).add(LDC_ATTRIBUTE(NoAlias)));
AttrBuilder().add(LLAttribute::StructRet).add(LLAttribute::NoAlias));
rt = Type::tvoid;
++nextLLArgIdx;
}
@ -95,7 +95,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
// Add the this pointer for member functions
AttrBuilder attrBuilder;
if (isCtor)
attrBuilder.add(LDC_ATTRIBUTE(Returned));
attrBuilder.add(LLAttribute::Returned);
newIrFty.arg_this = new IrFuncTyArg(thistype, thistype->toBasetype()->ty == Tstruct, attrBuilder);
++nextLLArgIdx;
}
@ -156,7 +156,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
{
if (abi->passByVal(loweredDType))
{
attrBuilder.add(LDC_ATTRIBUTE(ByVal));
attrBuilder.add(LLAttribute::ByVal);
// byval parameters are also passed as an address
passPointer = true;
}
@ -424,7 +424,7 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
}
// Store the final attribute set
func->setAttributes(newAttrs.toNativeSet());
func->setAttributes(newAttrs);
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -511,7 +511,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
if (!DtoIsIntrinsic(fdecl)) {
set_param_attrs(f, func, fdecl);
if (global.params.disableRedZone) {
func->addFnAttr(LDC_ATTRIBUTE(NoRedZone));
func->addFnAttr(LLAttribute::NoRedZone);
}
}
@ -776,20 +776,20 @@ void DtoDefineFunction(FuncDeclaration* fd)
// TODO: Is this required for Win64 as well?
if (global.params.targetTriple.getArch() == llvm::Triple::x86_64)
{
func->addFnAttr(LDC_ATTRIBUTE(UWTable));
func->addFnAttr(LLAttribute::UWTable);
}
if (opts::sanitize != opts::None) {
// Set the required sanitizer attribute.
if (opts::sanitize == opts::AddressSanitizer) {
func->addFnAttr(LDC_ATTRIBUTE(SanitizeAddress));
func->addFnAttr(LLAttribute::SanitizeAddress);
}
if (opts::sanitize == opts::MemorySanitizer) {
func->addFnAttr(LDC_ATTRIBUTE(SanitizeMemory));
func->addFnAttr(LLAttribute::SanitizeMemory);
}
if (opts::sanitize == opts::ThreadSanitizer) {
func->addFnAttr(LDC_ATTRIBUTE(SanitizeThread));
func->addFnAttr(LLAttribute::SanitizeThread);
}
}

View file

@ -92,6 +92,6 @@ llvm::Function* DtoInlineIRFunction(FuncDeclaration* fdecl)
LLFunction* fun = gIR->module.getFunction(mangled_name);
fun->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
SET_COMDAT(fun, gIR->module);
fun->addFnAttr(LDC_ATTRIBUTE(AlwaysInline));
fun->addFnAttr(LLAttribute::AlwaysInline);
return fun;
}

View file

@ -651,7 +651,7 @@ static void addCoverageAnalysis(Module* m)
// Set function attributes. See functions.cpp:DtoDefineFunction()
if (global.params.targetTriple.getArch() == llvm::Triple::x86_64)
{
ctor->addFnAttr(LDC_ATTRIBUTE(UWTable));
ctor->addFnAttr(LLAttribute::UWTable);
}
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "", ctor);

View file

@ -819,7 +819,7 @@ bool isSafeToStackAllocate(Instruction* Alloc, Value* V, DominatorTree& DT,
CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end();
for (CallSite::arg_iterator A = B; A != E; ++A)
if (A->get() == V) {
if (!CS.paramHasAttr(A - B + 1, LDC_ATTRIBUTE(NoCapture))) {
if (!CS.paramHasAttr(A - B + 1, LLAttribute::NoCapture)) {
// The parameter is not marked 'nocapture' - captured.
return false;
}

View file

@ -916,7 +916,7 @@ static void LLVM_D_BuildRuntimeModule()
assert(dty->ctype);
IrFuncTy &irFty = dty->ctype->getIrFuncTy();
gABI->rewriteFunctionType(dty, irFty);
fn->addAttributes(1, llvm::AttributeSet::get(gIR->context(), 1, irFty.args[0]->attrs.attrs));
fn->addAttributes(1, llvm::AttributeSet::get(gIR->context(), 1, irFty.args[0]->attrs));
fn->setCallingConv(gABI->callingConv(fn->getFunctionType(), LINKd));
}

View file

@ -136,7 +136,7 @@ static void addExplicitArguments(std::vector<LLValue*>& args, AttrSet& attrs,
AttrBuilder initialAttrs;
if (passByVal)
initialAttrs.add(LDC_ATTRIBUTE(ByVal));
initialAttrs.add(LLAttribute::ByVal);
else
initialAttrs.add(DtoShouldExtend(argType));
@ -666,7 +666,7 @@ private:
// verify that sret and/or inreg attributes are set
const AttrBuilder& sretAttrs = irFty.arg_sret->attrs;
assert((sretAttrs.contains(LDC_ATTRIBUTE(StructRet)) || sretAttrs.contains(LDC_ATTRIBUTE(InReg)))
assert((sretAttrs.contains(LLAttribute::StructRet) || sretAttrs.contains(LLAttribute::InReg))
&& "Sret arg not sret or inreg?");
}
@ -970,7 +970,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
}
// set calling convention and parameter attributes
llvm::AttributeSet attrlist = attrs.toNativeSet();
llvm::AttributeSet& attrlist = attrs;
if (dfnval && dfnval->func)
{
LLFunction* llfunc = llvm::dyn_cast<LLFunction>(dfnval->val);

View file

@ -55,7 +55,7 @@ bool DtoIsReturnInArg(CallExp *ce)
return false;
}
AttrBuilder::A DtoShouldExtend(Type* type)
LLAttribute DtoShouldExtend(Type* type)
{
type = type->toBasetype();
if (type->isintegral())
@ -64,11 +64,11 @@ AttrBuilder::A DtoShouldExtend(Type* type)
{
case Tint8:
case Tint16:
return LDC_ATTRIBUTE(SExt);
return LLAttribute::SExt;
case Tuns8:
case Tuns16:
return LDC_ATTRIBUTE(ZExt);
return LLAttribute::ZExt;
default:
// Do not extend.
@ -76,7 +76,7 @@ AttrBuilder::A DtoShouldExtend(Type* type)
}
}
return LDC_ATTRIBUTE(None);
return LLAttribute::None;
}
LLType* DtoType(Type* t)

View file

@ -50,7 +50,7 @@ bool DtoIsPassedByRef(Type* type);
bool DtoIsReturnInArg(CallExp *ce);
// should argument be zero or sign extended
AttrBuilder::A DtoShouldExtend(Type* type);
LLAttribute DtoShouldExtend(Type* type);
// tuple helper
// takes a arguments list and makes a struct type out of them

View file

@ -21,9 +21,9 @@ IrFuncTyArg::IrFuncTyArg(Type* t, bool bref, const AttrBuilder& a)
attrs(a), byref(bref), rewrite(0)
{}
bool IrFuncTyArg::isInReg() const { return attrs.contains(LDC_ATTRIBUTE(InReg)); }
bool IrFuncTyArg::isSRet() const { return attrs.contains(LDC_ATTRIBUTE(StructRet)); }
bool IrFuncTyArg::isByVal() const { return attrs.contains(LDC_ATTRIBUTE(ByVal)); }
bool IrFuncTyArg::isInReg() const { return attrs.contains(LLAttribute::InReg); }
bool IrFuncTyArg::isSRet() const { return attrs.contains(LLAttribute::StructRet); }
bool IrFuncTyArg::isByVal() const { return attrs.contains(LLAttribute::ByVal); }
llvm::Value* IrFuncTy::putRet(DValue* dval)
{