llvm-reduce
用来简化 IR 级别的用例。
其根据 执行命令的成功与失败来对用例进行简化。
使用很简单:
写好执行命令
$cat run.sh
#!/bin/bash
llc $1 2>&1 | grep "build failed"
执行
$llvm-reduce --test=run.sh test.ll
**** SUCCESS | lines: 0
Saved new best reduction to reduced.ll
Couldn't increase anymore.
Done reducing! Reduced testcase: reduced.ll
最后输出简化后用例到 reduced.ll
遇到的问题:
1 起初我把脚本中的 “llc $1” 改为 “llc test.ll”,但llvm-reduce 命令行还是不能省略test.ll。
而且即便加了test.ll 居然没有作用。
起初的失败demo:
$cat run.sh
#!/bin/bash
llc test.ll 2>&1 | grep "build failed"
$llvm-reduce --test=run.sh // fail
$llvm-reduce --test=run.sh test.ll // output fail
llvm-reduce options
llvm-reduce --help
OVERVIEW: LLVM automatic testcase reducer.
USAGE: llvm-reduce [options] <input llvm ll/bc file>
OPTIONS:
Color Options:
--color - Use colors in output (default=autodetect)
Generic Options:
--help - Display available options (--help-hidden for more)
--help-list - Display list of available options (--help-list-hidden for more)
--version - Display the version of this program
llvm-reduce options:
--abort-on-invalid-reduction - Abort if any reduction results in invalid IR
--delta-passes=<string> - Delta passes to run, separated by commas. By default, run all delta passes.
--in-place - WARNING: This option will replace your input file with the reduced version!
--ir-passes=<string> - A textual description of the pass pipeline, same as what's passed to `opt -passes`.
-j <uint> - Maximum number of threads to use to process chunks. Set to 1 to disable parallelism.
--max-pass-iterations=<int> - Maximum number of times to run the full set of delta passes (default=5)
--mtriple=<string> - Set the target triple
--preserve-debug-environment - Don't disable features used for crash debugging (crash reports, llvm-symbolizer and core dumps)
--print-delta-passes - Print list of delta passes, passable to --delta-passes as a comma separated list
--skip-delta-passes=<string> - Delta passes to not run, separated by commas. By default, run all delta passes.
--starting-granularity-level=<uint> - Number of times to divide chunks prior to first test
--test=<string> - Name of the interesting-ness test to be run
--test-arg=<string> - Arguments passed onto the interesting-ness test
--verbose - Print extra debugging information
--write-tmp-files-as-bitcode - Always write temporary files as bitcode instead of textual IR
-x=<value> - Input language ('ir' or 'mir')
=ir
=mir
run 个别 passes
比如我们只想run function-bodies,instructions 这2个passes,可以
llvm-reduce --delta-passes="function-bodies,instructions" --test=run.sh test.ll
llvm-reduce的pass 主要有
// llvm/tools/llvm-reduce/DeltaManager.cpp
#define DELTA_PASSES \
do { \
DELTA_PASS("strip-debug-info", stripDebugInfoDeltaPass) \
DELTA_PASS("functions", reduceFunctionsDeltaPass) \
DELTA_PASS("function-bodies", reduceFunctionBodiesDeltaPass) \
DELTA_PASS("special-globals", reduceSpecialGlobalsDeltaPass) \
DELTA_PASS("aliases", reduceAliasesDeltaPass) \
DELTA_PASS("ifuncs", reduceIFuncsDeltaPass) \
DELTA_PASS("simplify-conditionals-true", reduceConditionalsTrueDeltaPass) \
DELTA_PASS("simplify-conditionals-false", \
reduceConditionalsFalseDeltaPass) \
DELTA_PASS("invokes", reduceInvokesDeltaPass) \
DELTA_PASS("unreachable-basic-blocks", \
reduceUnreachableBasicBlocksDeltaPass) \
DELTA_PASS("basic-blocks", reduceBasicBlocksDeltaPass) \
DELTA_PASS("simplify-cfg", reduceUsingSimplifyCFGDeltaPass) \
DELTA_PASS("function-data", reduceFunctionDataDeltaPass) \
DELTA_PASS("global-values", reduceGlobalValuesDeltaPass) \
DELTA_PASS("global-objects", reduceGlobalObjectsDeltaPass) \
DELTA_PASS("global-initializers", reduceGlobalsInitializersDeltaPass) \
DELTA_PASS("global-variables", reduceGlobalsDeltaPass) \
DELTA_PASS("di-metadata", reduceDIMetadataDeltaPass) \
DELTA_PASS("dpvalues", reduceDPValuesDeltaPass) \
DELTA_PASS("metadata", reduceMetadataDeltaPass) \
DELTA_PASS("named-metadata", reduceNamedMetadataDeltaPass) \
DELTA_PASS("arguments", reduceArgumentsDeltaPass) \
DELTA_PASS("instructions", reduceInstructionsDeltaPass) \
DELTA_PASS("simplify-instructions", simplifyInstructionsDeltaPass) \
DELTA_PASS("ir-passes", runIRPassesDeltaPass) \
DELTA_PASS("operands-zero", reduceOperandsZeroDeltaPass) \
DELTA_PASS("operands-one", reduceOperandsOneDeltaPass) \
DELTA_PASS("operands-nan", reduceOperandsNaNDeltaPass) \
DELTA_PASS("operands-to-args", reduceOperandsToArgsDeltaPass) \
DELTA_PASS("operands-skip", reduceOperandsSkipDeltaPass) \
DELTA_PASS("operand-bundles", reduceOperandBundesDeltaPass) \
DELTA_PASS("attributes", reduceAttributesDeltaPass) \
DELTA_PASS("module-data", reduceModuleDataDeltaPass) \
DELTA_PASS("opcodes", reduceOpcodesDeltaPass) \
DELTA_PASS("volatile", reduceVolatileInstructionsDeltaPass) \
DELTA_PASS("atomic-ordering", reduceAtomicOrderingDeltaPass) \
DELTA_PASS("syncscopes", reduceAtomicSyncScopesDeltaPass) \
DELTA_PASS("instruction-flags", reduceInstructionFlagsDeltaPass) \
} while (false)
#define DELTA_PASSES_MIR \
do { \
DELTA_PASS("instructions", reduceInstructionsMIRDeltaPass) \
DELTA_PASS("ir-instruction-references", \
reduceIRInstructionReferencesDeltaPass) \
DELTA_PASS("ir-block-references", reduceIRBlockReferencesDeltaPass) \
DELTA_PASS("ir-function-references", reduceIRFunctionReferencesDeltaPass) \
DELTA_PASS("instruction-flags", reduceInstructionFlagsMIRDeltaPass) \
DELTA_PASS("register-uses", reduceRegisterUsesMIRDeltaPass) \
DELTA_PASS("register-defs", reduceRegisterDefsMIRDeltaPass) \
DELTA_PASS("register-hints", reduceVirtualRegisterHintsDeltaPass) \
DELTA_PASS("register-masks", reduceRegisterMasksMIRDeltaPass) \
} while (false)
定制化llvm-reduce
此外我们还可以修改llvm-reduce的code来定制化我们的reduce,比如不想在reduce时删除 带meta为range的指令:
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp b/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
index 30bf612fe969..73fb2cd2fd00 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp
@@ -21,11 +21,15 @@
using namespace llvm;
static bool shouldKeepDebugIntrinsicMetadata(Instruction &I, MDNode &MD) {
+ const MDNode *Range = I.getMetadata(LLVMContext::MD_range);
+ if (Range)
+ return true;
return isa<DILocation>(MD) && isa<DbgInfoIntrinsic>(I);
}