diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -97,12 +97,21 @@ "derived from non-exact functions via cloning"), cl::init(false)); +// These options can only used for debug builds. +#ifndef NDEBUG static cl::list SeedAllowList("attributor-seed-allow-list", cl::Hidden, - cl::desc("Comma seperated list of attrbute names that are " + cl::desc("Comma seperated list of attribute names that are " "allowed to be seeded."), cl::ZeroOrMore, cl::CommaSeparated); +static cl::list FunctionSeedAllowList( + "attributor-function-seed-allow-list", cl::Hidden, + cl::desc("Comma seperated list of function names that are " + "allowed to be seeded."), + cl::ZeroOrMore, cl::CommaSeparated); +#endif + static cl::opt DumpDepGraph("attributor-dump-dep-graph", cl::Hidden, cl::desc("Dump the dependency graph to dot files."), @@ -1568,9 +1577,17 @@ } bool Attributor::shouldSeedAttribute(AbstractAttribute &AA) { - if (SeedAllowList.size() == 0) - return true; - return std::count(SeedAllowList.begin(), SeedAllowList.end(), AA.getName()); + bool Result = true; +#ifndef NDEBUG + if (SeedAllowList.size() != 0) + Result = + std::count(SeedAllowList.begin(), SeedAllowList.end(), AA.getName()); + Function *Fn = AA.getAnchorScope(); + if (FunctionSeedAllowList.size() != 0 && Fn) + Result &= std::count(FunctionSeedAllowList.begin(), + FunctionSeedAllowList.end(), Fn->getName()); +#endif + return Result; } ChangeStatus Attributor::rewriteFunctionSignatures( diff --git a/llvm/test/Transforms/Attributor/allow_list.ll b/llvm/test/Transforms/Attributor/allow_list.ll --- a/llvm/test/Transforms/Attributor/allow_list.ll +++ b/llvm/test/Transforms/Attributor/allow_list.ll @@ -2,6 +2,13 @@ ; RUN: opt -S -passes=attributor --attributor-seed-allow-list asd < %s | FileCheck %s --check-prefixes=CHECK_DISABLED ; RUN: opt -S -passes=attributor --attributor-seed-allow-list AAValueSimplify < %s | FileCheck %s --check-prefixes=CHECK_ENABLED +; RUN: opt -S -passes=attributor --attributor-function-seed-allow-list asd < %s | FileCheck %s --check-prefixes=CHECK_DISABLED_FUNCTION + +; RUN: opt -S -passes=attributor --attributor-function-seed-allow-list range_use1 < %s | FileCheck %s --check-prefixes=CHECK_ENABLED_FUNCTION + + + + target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; Function Attrs: nounwind uwtable @@ -12,6 +19,17 @@ ; CHECK_DISABLED-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A]], 100 ; CHECK_DISABLED-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i32 ; CHECK_DISABLED-NEXT: ret i32 [[TMP2]] +; +; CHECK_DISABLED_FUNCTION: Function Attrs: noinline nounwind uwtable +; CHECK_DISABLED_FUNCTION-LABEL: define {{[^@]+}}@range_test +; CHECK_DISABLED_FUNCTION-SAME: (i32 [[A:%.*]]) +; CHECK_DISABLED_FUNCTION-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A]], 100 +; CHECK_DISABLED_FUNCTION-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i32 +; CHECK_DISABLED_FUNCTION-NEXT: ret i32 [[TMP2]] +; +; CHECK_ENABLED_FUNCTION: Function Attrs: noinline nounwind readnone uwtable +; CHECK_ENABLED_FUNCTION-LABEL: define {{[^@]+}}@range_test() +; CHECK_ENABLED_FUNCTION-NEXT: ret i32 1 ; %1 = icmp sgt i32 %a, 100 %2 = zext i1 %1 to i32 @@ -19,15 +37,49 @@ } ; Function Attrs: nounwind uwtable -define i32 @range_use() #0 { +define i32 @range_use1() #0 { ; CHECK_DISABLED: Function Attrs: noinline nounwind uwtable -; CHECK_DISABLED-LABEL: define {{[^@]+}}@range_use() +; CHECK_DISABLED-LABEL: define {{[^@]+}}@range_use1() ; CHECK_DISABLED-NEXT: [[TMP1:%.*]] = call i32 @range_test(i32 123) ; CHECK_DISABLED-NEXT: ret i32 [[TMP1]] ; ; CHECK_ENABLED: Function Attrs: noinline nounwind uwtable -; CHECK_ENABLED-LABEL: define {{[^@]+}}@range_use() +; CHECK_ENABLED-LABEL: define {{[^@]+}}@range_use1() ; CHECK_ENABLED-NEXT: ret i32 1 +; +; CHECK_DISABLED_FUNCTION: Function Attrs: noinline nounwind uwtable +; CHECK_DISABLED_FUNCTION-LABEL: define {{[^@]+}}@range_use1() +; CHECK_DISABLED_FUNCTION-NEXT: [[TMP1:%.*]] = call i32 @range_test(i32 123) +; CHECK_DISABLED_FUNCTION-NEXT: ret i32 [[TMP1]] +; +; CHECK_ENABLED_FUNCTION: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn +; CHECK_ENABLED_FUNCTION-LABEL: define {{[^@]+}}@range_use1() +; CHECK_ENABLED_FUNCTION-NEXT: ret i32 1 +; + %1 = call i32 @range_test(i32 123) + ret i32 %1 +} + +; Function Attrs: nounwind uwtable +define i32 @range_use2() #0 { +; CHECK_DISABLED: Function Attrs: noinline nounwind uwtable +; CHECK_DISABLED-LABEL: define {{[^@]+}}@range_use2() +; CHECK_DISABLED-NEXT: [[TMP1:%.*]] = call i32 @range_test(i32 123) +; CHECK_DISABLED-NEXT: ret i32 [[TMP1]] +; +; CHECK_ENABLED: Function Attrs: noinline nounwind uwtable +; CHECK_ENABLED-LABEL: define {{[^@]+}}@range_use2() +; CHECK_ENABLED-NEXT: ret i32 1 +; +; CHECK_DISABLED_FUNCTION: Function Attrs: noinline nounwind uwtable +; CHECK_DISABLED_FUNCTION-LABEL: define {{[^@]+}}@range_use2() +; CHECK_DISABLED_FUNCTION-NEXT: [[TMP1:%.*]] = call i32 @range_test(i32 123) +; CHECK_DISABLED_FUNCTION-NEXT: ret i32 [[TMP1]] +; +; CHECK_ENABLED_FUNCTION: Function Attrs: noinline nounwind uwtable +; CHECK_ENABLED_FUNCTION-LABEL: define {{[^@]+}}@range_use2() +; CHECK_ENABLED_FUNCTION-NEXT: [[TMP1:%.*]] = call i32 @range_test() +; CHECK_ENABLED_FUNCTION-NEXT: ret i32 [[TMP1]] ; %1 = call i32 @range_test(i32 123) ret i32 %1