mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-01 08:47:42 +00:00
[bugpoint][PR29027] Reduce function attributes
Summary: In addition to reducing the functions in an LLVM module, bugpoint now reduces the function attributes associated with each of the remaining functions. To test this, add a -bugpoint-crashfuncattr test pass, which crashes if a function in the module has a "bugpoint-crash" attribute. A test case demonstrates that the IR is reduced to just that one attribute. Reviewers: MatzeB, silvas, davide, reames Reviewed By: reames Subscribers: reames, llvm-commits Differential Revision: https://reviews.llvm.org/D55216 llvm-svn: 349601
This commit is contained in:
parent
329ea467f2
commit
dd4a470df3
11
test/BugPoint/func-attrs-keyval.ll
Normal file
11
test/BugPoint/func-attrs-keyval.ll
Normal file
@ -0,0 +1,11 @@
|
||||
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashfuncattr -silence-passes
|
||||
; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
|
||||
; REQUIRES: loadable_module
|
||||
|
||||
; CHECK: f() #[[ATTRS:[0-9]+]]
|
||||
define void @f() #0 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: attributes #[[ATTRS]] = { "bugpoint-crash"="sure" }
|
||||
attributes #0 = { "bugpoint-crash"="sure" noreturn "no-frame-pointer-elim-non-leaf" }
|
11
test/BugPoint/func-attrs.ll
Normal file
11
test/BugPoint/func-attrs.ll
Normal file
@ -0,0 +1,11 @@
|
||||
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashfuncattr -silence-passes
|
||||
; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
|
||||
; REQUIRES: loadable_module
|
||||
|
||||
; CHECK: f() #[[ATTRS:[0-9]+]]
|
||||
define void @f() #0 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: attributes #[[ATTRS]] = { "bugpoint-crash" }
|
||||
attributes #0 = { noinline "bugpoint-crash" "no-frame-pointer-elim-non-leaf" }
|
@ -123,3 +123,28 @@ char CrashOnTooManyCUs::ID = 0;
|
||||
static RegisterPass<CrashOnTooManyCUs>
|
||||
A("bugpoint-crash-too-many-cus",
|
||||
"BugPoint Test Pass - Intentionally crash on too many CUs");
|
||||
|
||||
namespace {
|
||||
class CrashOnFunctionAttribute : public FunctionPass {
|
||||
public:
|
||||
static char ID; // Pass ID, replacement for typeid
|
||||
CrashOnFunctionAttribute() : FunctionPass(ID) {}
|
||||
|
||||
private:
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
AttributeSet A = F.getAttributes().getFnAttributes();
|
||||
if (A.hasAttribute("bugpoint-crash"))
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
char CrashOnFunctionAttribute::ID = 0;
|
||||
static RegisterPass<CrashOnFunctionAttribute>
|
||||
B("bugpoint-crashfuncattr", "BugPoint Test Pass - Intentionally crash on "
|
||||
"function attribute 'bugpoint-crash'");
|
||||
|
@ -314,6 +314,66 @@ bool ReduceCrashingFunctions::TestFuncs(std::vector<Function *> &Funcs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// ReduceCrashingFunctionAttributes reducer - This works by removing
|
||||
/// attributes on a particular function and seeing if the program still crashes.
|
||||
/// If it does, then keep the newer, smaller program.
|
||||
///
|
||||
class ReduceCrashingFunctionAttributes : public ListReducer<Attribute> {
|
||||
BugDriver &BD;
|
||||
std::string FnName;
|
||||
BugTester TestFn;
|
||||
|
||||
public:
|
||||
ReduceCrashingFunctionAttributes(BugDriver &bd, const std::string &FnName,
|
||||
BugTester testFn)
|
||||
: BD(bd), FnName(FnName), TestFn(testFn) {}
|
||||
|
||||
Expected<TestResult> doTest(std::vector<Attribute> &Prefix,
|
||||
std::vector<Attribute> &Kept) override {
|
||||
if (!Kept.empty() && TestFuncAttrs(Kept))
|
||||
return KeepSuffix;
|
||||
if (!Prefix.empty() && TestFuncAttrs(Prefix))
|
||||
return KeepPrefix;
|
||||
return NoFailure;
|
||||
}
|
||||
|
||||
bool TestFuncAttrs(std::vector<Attribute> &Attrs);
|
||||
};
|
||||
}
|
||||
|
||||
bool ReduceCrashingFunctionAttributes::TestFuncAttrs(
|
||||
std::vector<Attribute> &Attrs) {
|
||||
// Clone the program to try hacking it apart...
|
||||
std::unique_ptr<Module> M = CloneModule(BD.getProgram());
|
||||
Function *F = M->getFunction(FnName);
|
||||
|
||||
// Build up an AttributeList from the attributes we've been given by the
|
||||
// reducer.
|
||||
AttrBuilder AB;
|
||||
for (auto A : Attrs)
|
||||
AB.addAttribute(A);
|
||||
AttributeList NewAttrs;
|
||||
NewAttrs =
|
||||
NewAttrs.addAttributes(BD.getContext(), AttributeList::FunctionIndex, AB);
|
||||
|
||||
// Set this new list of attributes on the function.
|
||||
F->setAttributes(NewAttrs);
|
||||
|
||||
// Try running on the hacked up program...
|
||||
if (TestFn(BD, M.get())) {
|
||||
BD.setNewProgram(std::move(M)); // It crashed, keep the trimmed version...
|
||||
|
||||
// Pass along the set of attributes that caused the crash.
|
||||
Attrs.clear();
|
||||
for (Attribute A : NewAttrs.getFnAttributes()) {
|
||||
Attrs.push_back(A);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// Simplify the CFG without completely destroying it.
|
||||
/// This is not well defined, but basically comes down to "try to eliminate
|
||||
@ -1056,6 +1116,38 @@ static Error DebugACrash(BugDriver &BD, BugTester TestFn) {
|
||||
BD.EmitProgressBitcode(BD.getProgram(), "reduced-function");
|
||||
}
|
||||
|
||||
// For each remaining function, try to reduce that function's attributes.
|
||||
std::vector<std::string> FunctionNames;
|
||||
for (Function &F : BD.getProgram())
|
||||
FunctionNames.push_back(F.getName());
|
||||
|
||||
if (!FunctionNames.empty() && !BugpointIsInterrupted) {
|
||||
outs() << "\n*** Attempting to reduce the number of function attributes in "
|
||||
"the testcase\n";
|
||||
|
||||
unsigned OldSize = 0;
|
||||
unsigned NewSize = 0;
|
||||
for (std::string &Name : FunctionNames) {
|
||||
Function *Fn = BD.getProgram().getFunction(Name);
|
||||
assert(Fn && "Could not find funcion?");
|
||||
|
||||
std::vector<Attribute> Attrs;
|
||||
for (Attribute A : Fn->getAttributes().getFnAttributes())
|
||||
Attrs.push_back(A);
|
||||
|
||||
OldSize += Attrs.size();
|
||||
Expected<bool> Result =
|
||||
ReduceCrashingFunctionAttributes(BD, Name, TestFn).reduceList(Attrs);
|
||||
if (Error E = Result.takeError())
|
||||
return E;
|
||||
|
||||
NewSize += Attrs.size();
|
||||
}
|
||||
|
||||
if (OldSize < NewSize)
|
||||
BD.EmitProgressBitcode(BD.getProgram(), "reduced-function-attributes");
|
||||
}
|
||||
|
||||
// Attempt to change conditional branches into unconditional branches to
|
||||
// eliminate blocks.
|
||||
if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user