diff --git a/.github/workflows/libclang-abi-tests.yml b/.github/workflows/libclang-abi-tests.yml index 5681c7c8166e..6d3d12b8ac8b 100644 --- a/.github/workflows/libclang-abi-tests.yml +++ b/.github/workflows/libclang-abi-tests.yml @@ -1,16 +1,18 @@ name: libclang ABI Tests -on: - push: - branches: - - 'release/**' - paths: - - 'clang/**' - - '.github/workflows/libclang-abi-tests.yml' - pull_request: - paths: - - 'clang/**' - - '.github/workflows/libclang-abi-tests.yml' +# TODO: Enable this test based on OpenCilk Clang changes. + +# on: +# push: +# branches: +# - 'release/**' +# paths: +# - 'clang/**' +# - '.github/workflows/libclang-abi-tests.yml' +# pull_request: +# paths: +# - 'clang/**' +# - '.github/workflows/libclang-abi-tests.yml' jobs: abi-dump-setup: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 788b7c7b72b0..9aa113cfe8dd 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1174,6 +1174,10 @@ def fcsi_EQ : Joined<["-"], "fcsi=">, Group, def fcilktool_EQ : Joined<["-"], "fcilktool=">, Group, MetaVarName<"">, HelpText<"Turn on the designated Cilk tool">; +def shared_libcilktool : Flag<["-"], "shared-libcilktool">, + HelpText<"Dynamically link the cilktool runtime">; +def static_libcilktool : Flag<["-"], "static-libcilktool">, + HelpText<"Statically link the cilktool runtime">; } // end -f[no-]sanitize* flags diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 52c29cbac70e..56f13f349ccf 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -895,7 +895,11 @@ bool tools::addCilktoolRuntime(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { if (Arg *A = Args.getLastArg(options::OPT_fcilktool_EQ)) { StringRef Val = A->getValue(); - CmdArgs.push_back(TC.getCompilerRTArgString(Args, Val)); + bool Shared = Args.hasArg(options::OPT_shared) || + Args.hasFlag(options::OPT_shared_libcilktool, + options::OPT_static_libcilktool, false); + CmdArgs.push_back(TC.getCompilerRTArgString( + Args, Val, Shared ? ToolChain::FT_Shared : ToolChain::FT_Static)); // Link in the C++ standard library TC.AddCXXStdlibLibArgs(Args, CmdArgs); return true; diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 800d38986597..1bcd375be226 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1241,8 +1241,12 @@ void DarwinClang::AddCilktoolRTLibs(const ArgList &Args, ArgStringList &CmdArgs) const { if (Arg *A = Args.getLastArg(options::OPT_fcilktool_EQ)) { StringRef Val = A->getValue(); - auto RLO = RuntimeLinkOptions(RLO_AlwaysLink); - AddLinkRuntimeLib(Args, CmdArgs, Val, RLO); + bool Shared = Args.hasArg(options::OPT_shared) || + Args.hasFlag(options::OPT_shared_libcilktool, + options::OPT_static_libcilktool, false); + auto RLO = + RuntimeLinkOptions(RLO_AlwaysLink | (Shared ? RLO_AddRPath : 0U)); + AddLinkRuntimeLib(Args, CmdArgs, Val, RLO, Shared); // Link in the C++ standard library AddCXXStdlibLibArgs(Args, CmdArgs); } diff --git a/llvm/lib/Transforms/Instrumentation/CilkSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/CilkSanitizer.cpp index 0aa687e567d3..67e54296d59c 100644 --- a/llvm/lib/Transforms/Instrumentation/CilkSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/CilkSanitizer.cpp @@ -2192,8 +2192,10 @@ Value *CilkSanitizerImpl::Instrumentor::getMAAPValue(Instruction *I, if (!LocalMAAPs.count(Obj)) { LLVM_DEBUG(dbgs() << "No local MAAP found for obj " << *Obj << "\n"); if (RD.Racer.isValid()) - return getMAAPIRValue(IRB, LocalRaceVal); - return DefaultMAAP; + MV = IRB.CreateOr(MV, getMAAPIRValue(IRB, LocalRaceVal)); + else + MV = IRB.CreateOr(MV, DefaultMAAP); + continue; } Value *FlagLoad = readMAAPVal(LocalMAAPs[Obj], IRB); @@ -2270,7 +2272,8 @@ Value *CilkSanitizerImpl::Instrumentor::getMAAPValue(Instruction *I, // then there's nothing to check. if (!LocalMAAPs.count(&Arg)) { LLVM_DEBUG(dbgs() << "No local MAAP found for arg " << Arg << "\n"); - return DefaultMAAP; + MV = IRB.CreateOr(MV, DefaultMAAP); + continue; } // These two objects may alias, based on static analysis. Check the @@ -3371,6 +3374,10 @@ bool CilkSanitizerImpl::instrumentFunctionUsingRI(Function &F) { const Function *CF = CB->getCalledFunction(); if (FunctionRaceType.count(CF)) { FuncRT = RaceInfo::unionRaceTypes(FuncRT, FunctionRaceType[CF]); + // Preserve the local-race marking if the callsite itself is involved in + // a local race. + if (RaceInfo::isLocalRace(RI.getRaceType(I))) + FuncRT = RaceInfo::unionRaceTypes(FuncRT, RaceInfo::Local); continue; } } diff --git a/llvm/lib/Transforms/Tapir/OpenCilkABI.cpp b/llvm/lib/Transforms/Tapir/OpenCilkABI.cpp index 0437bcc3ea5c..b35d73d05fda 100644 --- a/llvm/lib/Transforms/Tapir/OpenCilkABI.cpp +++ b/llvm/lib/Transforms/Tapir/OpenCilkABI.cpp @@ -78,6 +78,23 @@ enum { #define CILKRTS_FUNC(name) Get__cilkrts_##name() +/// Helper to find a function with the given name, creating it if it doesn't +/// already exist. Returns false if the function was inserted, indicating that +/// the body of the function has yet to be defined. +static bool GetOrCreateFunction(Module &M, const StringRef FnName, + FunctionType *FTy, Function *&Fn) { + // If the function already exists then let the caller know. + if ((Fn = M.getFunction(FnName))) + return true; + + // Otherwise we have to create it. + Fn = cast(M.getOrInsertFunction(FnName, FTy).getCallee()); + + // Let the caller know that the function is incomplete and the body still + // needs to be added. + return false; +} + OpenCilkABI::OpenCilkABI(Module &M) : TapirTarget(M) {} void OpenCilkABI::prepareModule() { @@ -130,6 +147,30 @@ void OpenCilkABI::prepareModule() { PointerType *StackFramePtrTy = PointerType::getUnqual(StackFrameTy); PointerType *WorkerPtrTy = PointerType::getUnqual(WorkerTy); ArrayType *ContextTy = ArrayType::get(VoidPtrTy, 5); + if (UseOpenCilkRuntimeBC) { + Type *VoidTy = Type::getVoidTy(C); + FunctionType *CilkRTSFnTy = + FunctionType::get(VoidTy, {StackFramePtrTy}, false); + SmallVector, 5> CilkRTSFunctions({ + std::make_pair("__cilkrts_enter_frame", CilkRTSFnTy), + std::make_pair("__cilkrts_enter_frame_fast", CilkRTSFnTy), + std::make_pair("__cilkrts_detach", CilkRTSFnTy), + std::make_pair("__cilkrts_pop_frame", CilkRTSFnTy), + std::make_pair("__cilkrts_save_fp_ctrl_state", CilkRTSFnTy), + }); + + // Add attributes to internalized functions + for (auto CilkRTSFnProto : CilkRTSFunctions) { + Function *Fn; + if (GetOrCreateFunction(M, CilkRTSFnProto.first, CilkRTSFnProto.second, + Fn)) { + Fn->setLinkage(Function::AvailableExternallyLinkage); + Fn->setDoesNotThrow(); + if (!DebugABICalls && !UseExternalABIFunctions) + Fn->addFnAttr(Attribute::AlwaysInline); + } + } + } Triple T(M.getTargetTriple()); bool HasSSE = T.getArch() == Triple::x86 || T.getArch() == Triple::x86_64; @@ -408,23 +449,6 @@ static Value *LoadSTyField( return L; } -/// Helper to find a function with the given name, creating it if it doesn't -/// already exist. Returns false if the function was inserted, indicating that -/// the body of the function has yet to be defined. -static bool GetOrCreateFunction(Module &M, const StringRef FnName, - FunctionType *FTy, Function *&Fn) { - // If the function already exists then let the caller know. - if ((Fn = M.getFunction(FnName))) - return true; - - // Otherwise we have to create it. - Fn = cast(M.getOrInsertFunction(FnName, FTy).getCallee()); - - // Let the caller know that the function is incomplete and the body still - // needs to be added. - return false; -} - /// Emit a call to the CILK_SETJMP function. CallInst *OpenCilkABI::EmitCilkSetJmp(IRBuilder<> &B, Value *SF) { LLVMContext &Ctx = M.getContext(); @@ -480,13 +504,8 @@ Function *OpenCilkABI::Get__cilkrts_pop_frame() { Function *Fn = nullptr; if (GetOrCreateFunction(M, "__cilkrts_pop_frame", FunctionType::get(VoidTy, {StackFramePtrTy}, false), - Fn)) { - Fn->setLinkage(Function::AvailableExternallyLinkage); - Fn->setDoesNotThrow(); - if (!DebugABICalls && !UseExternalABIFunctions) - Fn->addFnAttr(Attribute::AlwaysInline); + Fn)) return Fn; - } // Create the body of __cilkrts_pop_frame. const DataLayout &DL = M.getDataLayout(); @@ -556,13 +575,8 @@ Function *OpenCilkABI::Get__cilkrts_detach() { Function *Fn = nullptr; if (GetOrCreateFunction(M, "__cilkrts_detach", FunctionType::get(VoidTy, {StackFramePtrTy}, false), - Fn)) { - Fn->setLinkage(Function::AvailableExternallyLinkage); - Fn->setDoesNotThrow(); - if (!DebugABICalls && !UseExternalABIFunctions) - Fn->addFnAttr(Attribute::AlwaysInline); + Fn)) return Fn; - } // Create the body of __cilkrts_detach. const DataLayout &DL = M.getDataLayout(); @@ -630,13 +644,8 @@ Function *OpenCilkABI::Get__cilkrts_save_fp_ctrl_state() { Function *Fn = nullptr; if (GetOrCreateFunction(M, "__cilkrts_save_fp_ctrl_state", FunctionType::get(VoidTy, {StackFramePtrTy}, false), - Fn)) { - Fn->setLinkage(Function::AvailableExternallyLinkage); - Fn->setDoesNotThrow(); - if (!DebugABICalls && !UseExternalABIFunctions) - Fn->addFnAttr(Attribute::AlwaysInline); + Fn)) return Fn; - } Function::arg_iterator Args = Fn->arg_begin(); Value *SF = &*Args; @@ -967,19 +976,10 @@ Function *OpenCilkABI::Get__cilkrts_enter_frame() { Type *VoidTy = Type::getVoidTy(Ctx); PointerType *StackFramePtrTy = PointerType::getUnqual(StackFrameTy); Function *Fn = nullptr; - // NOTE(TFK): If the function was imported from the opencilk bitcode file - // then it will not have the requisite attributes. It is perhaps - // better to set these attributes when creating the opencilk bitcode - // file... for now I set them here. if (GetOrCreateFunction(M, "__cilkrts_enter_frame", FunctionType::get(VoidTy, {StackFramePtrTy}, false), - Fn)) { - Fn->setLinkage(Function::AvailableExternallyLinkage); - Fn->setDoesNotThrow(); - if (!DebugABICalls && !UseExternalABIFunctions) - Fn->addFnAttr(Attribute::AlwaysInline); + Fn)) return Fn; - } // Create the body of __cilkrts_enter_frame. const DataLayout &DL = M.getDataLayout(); @@ -1093,19 +1093,10 @@ Function *OpenCilkABI::Get__cilkrts_enter_frame_fast() { Type *VoidTy = Type::getVoidTy(Ctx); PointerType *StackFramePtrTy = PointerType::getUnqual(StackFrameTy); Function *Fn = nullptr; - // NOTE(TFK): If the function was imported from the opencilk bitcode file - // then it will not have the requisite attributes. It is perhaps - // better to set these attributes when creating the opencilk bitcode - // file... for now I set them here. if (GetOrCreateFunction(M, "__cilkrts_enter_frame_fast", FunctionType::get(VoidTy, {StackFramePtrTy}, false), - Fn)) { - Fn->setLinkage(Function::AvailableExternallyLinkage); - Fn->setDoesNotThrow(); - if (!DebugABICalls && !UseExternalABIFunctions) - Fn->addFnAttr(Attribute::AlwaysInline); + Fn)) return Fn; - } // Create the body of __cilkrts_enter_frame_fast. const DataLayout &DL = M.getDataLayout(); diff --git a/llvm/test/Transforms/Tapir/empty.ll b/llvm/test/Transforms/Tapir/empty.ll new file mode 100644 index 000000000000..0e8224ee9546 --- /dev/null +++ b/llvm/test/Transforms/Tapir/empty.ll @@ -0,0 +1,29 @@ +; Check that the OpenCilk Tapir target always properly marks runtime +; ABI functions so that they are not included in the final object +; file. +; +; RUN: opt < %s -tapir2target -tapir-target=opencilk -use-opencilk-runtime-bc -opencilk-runtime-bc-path=%S/libopencilk-abi.bc -globaldce -S -o - | FileCheck %s +; RUN: opt < %s -passes='tapir2target,globaldce' -tapir-target=opencilk -use-opencilk-runtime-bc -opencilk-runtime-bc-path=%S/libopencilk-abi.bc -S -o - | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + ret i32 0 +} + +attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 11.1.0 (git@github.com:OpenCilk/opencilk-project.git a64c17613c8e15c431484644b758f036b071e92d)"} + +; CHECK-NOT: define {{.*}}@__cilkrts_enter_frame( +; CHECK-NOT: define {{.*}}@__cilkrts_enter_frame_fast( +; CHECK-NOT: define {{.*}}@__cilkrts_detach( +; CHECK-NOT: define {{.*}}@__cilkrts_save_fp_ctrl_state( +; CHECK-NOT: define {{.*}}@__cilkrts_pop_frame(