mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-29 22:50:55 +00:00
Verifier: Simplify and fix issue where we were not verifying unmaterialized functions.
Arrange to call verify(Function &) on each function, followed by verify(Module &), whether the verifier is being used from the pass or from verifyModule(). As a side effect, this fixes an issue that caused us not to call verify(Function &) on unmaterialized functions from verifyModule(). Differential Revision: http://reviews.llvm.org/D21042 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271956 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d97680dbf0
commit
052c9ee80b
@ -314,17 +314,10 @@ public:
|
|||||||
Context = &M.getContext();
|
Context = &M.getContext();
|
||||||
Broken = false;
|
Broken = false;
|
||||||
|
|
||||||
// Scan through, checking all of the external function's linkage now...
|
// Collect all declarations of the llvm.experimental.deoptimize intrinsic.
|
||||||
for (const Function &F : M) {
|
for (const Function &F : M)
|
||||||
visitGlobalValue(F);
|
|
||||||
|
|
||||||
// Check to make sure function prototypes are okay.
|
|
||||||
if (F.isDeclaration()) {
|
|
||||||
visitFunction(F);
|
|
||||||
if (F.getIntrinsicID() == Intrinsic::experimental_deoptimize)
|
if (F.getIntrinsicID() == Intrinsic::experimental_deoptimize)
|
||||||
DeoptimizeDeclarations.push_back(&F);
|
DeoptimizeDeclarations.push_back(&F);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now that we've visited every function, verify that we never asked to
|
// Now that we've visited every function, verify that we never asked to
|
||||||
// recover a frame index that wasn't escaped.
|
// recover a frame index that wasn't escaped.
|
||||||
@ -1866,6 +1859,8 @@ void Verifier::verifySiblingFuncletUnwinds() {
|
|||||||
// visitFunction - Verify that a function is ok.
|
// visitFunction - Verify that a function is ok.
|
||||||
//
|
//
|
||||||
void Verifier::visitFunction(const Function &F) {
|
void Verifier::visitFunction(const Function &F) {
|
||||||
|
visitGlobalValue(F);
|
||||||
|
|
||||||
// Check function arguments.
|
// Check function arguments.
|
||||||
FunctionType *FT = F.getFunctionType();
|
FunctionType *FT = F.getFunctionType();
|
||||||
unsigned NumArgs = F.arg_size();
|
unsigned NumArgs = F.arg_size();
|
||||||
@ -4427,7 +4422,6 @@ void Verifier::verifyDeoptimizeCallingConvs() {
|
|||||||
|
|
||||||
bool llvm::verifyFunction(const Function &f, raw_ostream *OS) {
|
bool llvm::verifyFunction(const Function &f, raw_ostream *OS) {
|
||||||
Function &F = const_cast<Function &>(f);
|
Function &F = const_cast<Function &>(f);
|
||||||
assert(!F.isDeclaration() && "Cannot verify external functions");
|
|
||||||
|
|
||||||
// Don't use a raw_null_ostream. Printing IR is expensive.
|
// Don't use a raw_null_ostream. Printing IR is expensive.
|
||||||
Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/true);
|
Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/true);
|
||||||
@ -4444,7 +4438,6 @@ bool llvm::verifyModule(const Module &M, raw_ostream *OS,
|
|||||||
|
|
||||||
bool Broken = false;
|
bool Broken = false;
|
||||||
for (const Function &F : M)
|
for (const Function &F : M)
|
||||||
if (!F.isDeclaration() && !F.isMaterializable())
|
|
||||||
Broken |= !V.verify(F);
|
Broken |= !V.verify(F);
|
||||||
|
|
||||||
Broken |= !V.verify(M);
|
Broken |= !V.verify(M);
|
||||||
@ -4482,7 +4475,12 @@ struct VerifierLegacyPass : public FunctionPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool doFinalization(Module &M) override {
|
bool doFinalization(Module &M) override {
|
||||||
bool HasErrors = !V.verify(M);
|
bool HasErrors = false;
|
||||||
|
for (Function &F : M)
|
||||||
|
if (F.isDeclaration())
|
||||||
|
HasErrors |= !V.verify(F);
|
||||||
|
|
||||||
|
HasErrors |= !V.verify(M);
|
||||||
if (FatalErrors) {
|
if (FatalErrors) {
|
||||||
if (HasErrors)
|
if (HasErrors)
|
||||||
report_fatal_error("Broken module found, compilation aborted!");
|
report_fatal_error("Broken module found, compilation aborted!");
|
||||||
|
@ -2253,7 +2253,12 @@ TEST_F(FunctionAttachmentTest, Verifier) {
|
|||||||
// be verified directly, so check that the module fails to verify).
|
// be verified directly, so check that the module fails to verify).
|
||||||
EXPECT_TRUE(verifyModule(*F->getParent()));
|
EXPECT_TRUE(verifyModule(*F->getParent()));
|
||||||
|
|
||||||
|
// Nor can materializable functions.
|
||||||
|
F->setIsMaterializable(true);
|
||||||
|
EXPECT_TRUE(verifyModule(*F->getParent()));
|
||||||
|
|
||||||
// Functions with a body can.
|
// Functions with a body can.
|
||||||
|
F->setIsMaterializable(false);
|
||||||
(void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F));
|
(void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F));
|
||||||
EXPECT_FALSE(verifyModule(*F->getParent()));
|
EXPECT_FALSE(verifyModule(*F->getParent()));
|
||||||
EXPECT_FALSE(verifyFunction(*F));
|
EXPECT_FALSE(verifyFunction(*F));
|
||||||
|
Loading…
Reference in New Issue
Block a user