mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 00:55:49 +03:00
Simplify working with LLVM attributes
This commit is contained in:
parent
3d803c7a1c
commit
90197d6c72
16 changed files with 67 additions and 83 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue