diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2009-05-16 00:33:53 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2009-05-16 00:33:53 +0000 |
commit | 48872e0d84b47769be6c13ae98bf88468b59d921 (patch) | |
tree | 8f2ebd00a53ab7743265cf4e646e128e0c39b798 /lib/CodeGen/LLVMTargetMachine.cpp | |
parent | 3b00162fa1574e4aab6df15ef757bb36b8d4b958 (diff) |
Pass to verify generated machine code.
The following is checked:
* Operand counts: All explicit operands must be present.
* Register classes: All physical and virtual register operands must be
compatible with the register class required by the instruction descriptor.
* Register live intervals: Registers must be defined only once, and must be
defined before use.
The machine code verifier is enabled with the command-line option
'-verify-machineinstrs', or by defining the environment variable
LLVM_VERIFY_MACHINEINSTRS to the name of a file that will receive all the
verifier errors.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71918 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LLVMTargetMachine.cpp')
-rw-r--r-- | lib/CodeGen/LLVMTargetMachine.cpp | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index cf16a652fb..580f5f9f2f 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -37,6 +37,9 @@ static cl::opt<bool> PrintEmittedAsm("print-emitted-asm", cl::Hidden, cl::desc("Dump emitter generated instructions as assembly")); static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden, cl::desc("Dump garbage collector data")); +static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden, + cl::desc("Verify generated machine code"), + cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL)); // When this works it will be on by default. static cl::opt<bool> @@ -132,6 +135,15 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, return false; // success! } +static void printAndVerify(PassManagerBase &PM, + bool allowDoubleDefs = false) { + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(cerr)); + + if (VerifyMachineCode) + PM.add(createMachineVerifierPass(allowDoubleDefs)); +} + /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for both /// emitting to assembly files or machine code output. /// @@ -176,17 +188,17 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, return true; // Print the instruction selected machine code... - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM, /* allowDoubleDefs= */ true); if (OptLevel != CodeGenOpt::None) { PM.add(createMachineLICMPass()); PM.add(createMachineSinkingPass()); + printAndVerify(PM, /* allowDoubleDefs= */ true); } // Run pre-ra passes. - if (addPreRegAlloc(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + if (addPreRegAlloc(PM, OptLevel)) + printAndVerify(PM); // Perform register allocation. PM.add(createRegisterAllocator()); @@ -195,46 +207,33 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, if (OptLevel != CodeGenOpt::None) PM.add(createStackSlotColoringPass(OptLevel >= CodeGenOpt::Aggressive)); - if (PrintMachineCode) // Print the register-allocated code - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); // Print the register-allocated code // Run post-ra passes. - if (addPostRegAlloc(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + if (addPostRegAlloc(PM, OptLevel)) + printAndVerify(PM); PM.add(createLowerSubregsPass()); - - if (PrintMachineCode) // Print the subreg lowered code - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); // Insert prolog/epilog code. Eliminate abstract frame index references... PM.add(createPrologEpilogCodeInserter()); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); // Second pass scheduler. if (OptLevel != CodeGenOpt::None && !DisablePostRAScheduler) { PM.add(createPostRAScheduler()); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); } // Branch folding must be run after regalloc and prolog/epilog insertion. - if (OptLevel != CodeGenOpt::None) + if (OptLevel != CodeGenOpt::None) { PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); + } PM.add(createGCMachineCodeAnalysisPass()); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); if (PrintGCInfo) PM.add(createGCInfoPrinter(*cerr)); |