mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 00:55:49 +03:00
Apply TargetMachine options as function attributes in IR. Needed for LTO.
This commit is contained in:
parent
197c81439d
commit
00dfb4d138
3 changed files with 78 additions and 12 deletions
|
@ -18,6 +18,7 @@
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
#include "statement.h"
|
#include "statement.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
#include "driver/cl_options.h"
|
||||||
#include "gen/abi.h"
|
#include "gen/abi.h"
|
||||||
#include "gen/arrays.h"
|
#include "gen/arrays.h"
|
||||||
#include "gen/classes.h"
|
#include "gen/classes.h"
|
||||||
|
@ -42,6 +43,8 @@
|
||||||
#include "ir/irmodule.h"
|
#include "ir/irmodule.h"
|
||||||
#include "llvm/IR/Intrinsics.h"
|
#include "llvm/IR/Intrinsics.h"
|
||||||
#include "llvm/IR/CFG.h"
|
#include "llvm/IR/CFG.h"
|
||||||
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
#include "llvm/Target/TargetOptions.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
|
llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
|
||||||
|
@ -419,19 +422,55 @@ void applyParamAttrsToLLFunc(TypeFunction *f, IrFuncTy &irFty,
|
||||||
func->setAttributes(newAttrs);
|
func->setAttributes(newAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyDefaultMathAttributes(IrFunction *irFunc) {
|
/// Applies TargetMachine options as function attributes in the IR (options for
|
||||||
|
/// which attributes exist).
|
||||||
|
/// This is e.g. needed for LTO: it tells the linker/LTO-codegen what settings
|
||||||
|
/// to use.
|
||||||
|
/// It is also needed because "unsafe-fp-math" is not properly reset in LLVM
|
||||||
|
/// between function definitions, i.e. if a function does not define a value for
|
||||||
|
/// "unsafe-fp-math" it will be compiled using the value of the previous
|
||||||
|
/// function. Therefore, each function must explicitly define the value (clang
|
||||||
|
/// does the same). See https://llvm.org/bugs/show_bug.cgi?id=23172
|
||||||
|
void applyTargetMachineAttributes(llvm::Function &func,
|
||||||
|
const llvm::TargetMachine &target) {
|
||||||
|
const llvm::TargetOptions &TO = target.Options;
|
||||||
|
|
||||||
// TODO: implement commandline switches to change the default values.
|
// TODO: implement commandline switches to change the default values.
|
||||||
|
|
||||||
// "unsafe-fp-math" is not properly reset in LLVM between function
|
// Target CPU capabilities
|
||||||
// definitions, i.e. if a function does not define a value for
|
func.addFnAttr("target-cpu", target.getTargetCPU());
|
||||||
// "unsafe-fp-math" it will be compiled using the value of the previous
|
auto featStr = target.getTargetFeatureString();
|
||||||
// function. Therefore, each function must explicitly define the value (clang
|
if (!featStr.empty())
|
||||||
// does the same).
|
func.addFnAttr("target-features", featStr);
|
||||||
// See https://llvm.org/bugs/show_bug.cgi?id=23172
|
|
||||||
irFunc->func->addFnAttr("unsafe-fp-math", "false");
|
// Floating point settings
|
||||||
}
|
func.addFnAttr("unsafe-fp-math", TO.UnsafeFPMath ? "true" : "false");
|
||||||
|
func.addFnAttr("less-precise-fpmad",
|
||||||
|
TO.LessPreciseFPMADOption ? "true" : "false");
|
||||||
|
func.addFnAttr("no-infs-fp-math", TO.NoInfsFPMath ? "true" : "false");
|
||||||
|
func.addFnAttr("no-nans-fp-math", TO.NoNaNsFPMath ? "true" : "false");
|
||||||
|
#if LDC_LLVM_VER < 307
|
||||||
|
func.addFnAttr("use-soft-float", TO.UseSoftFloat ? "true" : "false");
|
||||||
|
#else
|
||||||
|
switch (TO.FloatABIType) {
|
||||||
|
case llvm::FloatABI::Default:
|
||||||
|
break;
|
||||||
|
case llvm::FloatABI::Soft:
|
||||||
|
func.addFnAttr("use-soft-float", "true");
|
||||||
|
break;
|
||||||
|
case llvm::FloatABI::Hard:
|
||||||
|
func.addFnAttr("use-soft-float", "false");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Frame pointer elimination
|
||||||
|
func.addFnAttr("no-frame-pointer-elim",
|
||||||
|
opts::disableFpElim ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void DtoDeclareFunction(FuncDeclaration *fdecl) {
|
void DtoDeclareFunction(FuncDeclaration *fdecl) {
|
||||||
|
@ -523,9 +562,9 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default math function attributes here, such that they can be overridden
|
// First apply the TargetMachine attributes, such that they can be overridden
|
||||||
// by UDAs.
|
// by UDAs.
|
||||||
applyDefaultMathAttributes(irFunc);
|
applyTargetMachineAttributes(*func, *gTargetMachine);
|
||||||
applyFuncDeclUDAs(fdecl, irFunc);
|
applyFuncDeclUDAs(fdecl, irFunc);
|
||||||
|
|
||||||
// main
|
// main
|
||||||
|
|
27
tests/codegen/attr_targetoptions.d
Normal file
27
tests/codegen/attr_targetoptions.d
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Tests that our TargetMachine options are added as function attributes
|
||||||
|
|
||||||
|
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix=DEFAULT < %t.ll
|
||||||
|
// RUN: %ldc -c -output-ll -of=%t.ll %s -disable-fp-elim && FileCheck %s --check-prefix=FRAMEPTR < %t.ll
|
||||||
|
// RUN: %ldc -c -output-ll -of=%t.ll %s -mattr=test && FileCheck %s --check-prefix=ATTR < %t.ll
|
||||||
|
|
||||||
|
// DEFAULT: define{{.*}} @{{.*}}3fooFZv{{.*}} #[[KEYVALUE:[0-9]+]]
|
||||||
|
// FRAMEPTR: define{{.*}} @{{.*}}3fooFZv{{.*}} #[[KEYVALUE:[0-9]+]]
|
||||||
|
// ATTR: define{{.*}} @{{.*}}3fooFZv{{.*}} #[[KEYVALUE:[0-9]+]]
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEFAULT: attributes #[[KEYVALUE]]
|
||||||
|
// DEFAULT-DAG: "target-cpu"=
|
||||||
|
// DEFAULT-DAG: "use-soft-float"="{{(true|false)}}"
|
||||||
|
// DEFAULT-DAG: "no-frame-pointer-elim"="false"
|
||||||
|
// DEFAULT-DAG: "unsafe-fp-math"="false"
|
||||||
|
// DEFAULT-DAG: "less-precise-fpmad"="false"
|
||||||
|
// DEFAULT-DAG: "no-infs-fp-math"="false"
|
||||||
|
// DEFAULT-DAG: "no-nans-fp-math"="false"
|
||||||
|
|
||||||
|
// FRAMEPTR: attributes #[[KEYVALUE]]
|
||||||
|
// FRAMEPTR-DAG: "no-frame-pointer-elim"="true"
|
||||||
|
|
||||||
|
// ATTR: attributes #[[KEYVALUE]]
|
||||||
|
// ATTR-DAG: "target-features"="{{.*}}+test{{.*}}"
|
|
@ -113,4 +113,4 @@ double neverInlinedEnclosingFunction()
|
||||||
// LLVM-DAG: attributes #[[UNSAFEFPMATH]] ={{.*}} "unsafe-fp-math"="true"
|
// LLVM-DAG: attributes #[[UNSAFEFPMATH]] ={{.*}} "unsafe-fp-math"="true"
|
||||||
// LLVM-DAG: attributes #[[UNSAFEFPMATH2]] ={{.*}} "unsafe-fp-math"="true"
|
// LLVM-DAG: attributes #[[UNSAFEFPMATH2]] ={{.*}} "unsafe-fp-math"="true"
|
||||||
// LLVM-DAG: attributes #[[UNSAFEFPMATH3]] ={{.*}} "unsafe-fp-math"="false"
|
// LLVM-DAG: attributes #[[UNSAFEFPMATH3]] ={{.*}} "unsafe-fp-math"="false"
|
||||||
// LLVM-DAG: attributes #[[FEAT]] ={{.*}} "target-features"="+fma"
|
// LLVM-DAG: attributes #[[FEAT]] ={{.*}} "target-features"="{{.*}}+fma{{.*}}"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue