ruby-llvm 16.0.1 → 18.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/ruby-llvm-support/support.cpp +10 -0
- data/lib/llvm/analysis_ffi.rb +1 -1
- data/lib/llvm/config.rb +5 -5
- data/lib/llvm/core/attribute.rb +41 -6
- data/lib/llvm/core/bitcode_ffi.rb +1 -1
- data/lib/llvm/core/builder.rb +8 -8
- data/lib/llvm/core/module.rb +4 -0
- data/lib/llvm/core/pass_manager.rb +2 -3
- data/lib/llvm/core/type.rb +4 -0
- data/lib/llvm/core/value.rb +110 -25
- data/lib/llvm/core.rb +7 -0
- data/lib/llvm/core_ffi.rb +1 -146
- data/lib/llvm/execution_engine_ffi.rb +1 -1
- data/lib/llvm/linker_ffi.rb +1 -1
- data/lib/llvm/lljit.rb +106 -0
- data/lib/llvm/support.rb +1 -0
- data/lib/llvm/target.rb +1 -1
- data/lib/llvm/target_ffi.rb +1 -1
- data/lib/llvm/transforms/ipo.rb +17 -23
- data/lib/llvm/transforms/pass_builder.rb +712 -0
- data/lib/llvm/transforms/{builder.rb → pass_manager_builder.rb} +10 -29
- data/lib/llvm/transforms/scalar.rb +45 -55
- data/lib/llvm/transforms/utils.rb +3 -7
- data/lib/llvm/transforms/vectorize.rb +3 -5
- data/lib/llvm/version.rb +3 -3
- data/lib/llvm.rb +2 -0
- metadata +5 -7
- data/lib/llvm/transforms/builder_ffi.rb +0 -106
- data/lib/llvm/transforms/ipo_ffi.rb +0 -111
- data/lib/llvm/transforms/scalar_ffi.rb +0 -320
- data/lib/llvm/transforms/vectorize_ffi.rb +0 -38
@@ -0,0 +1,712 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LLVM
|
4
|
+
class PassBuilder # rubocop:disable Metrics/ClassLength
|
5
|
+
extend FFI::Library
|
6
|
+
ffi_lib ["libLLVM-18.so.1", "libLLVM.so.18", "LLVM-18"]
|
7
|
+
|
8
|
+
attr_reader :passes
|
9
|
+
attr_accessor :inliner_threshold, :merge_functions
|
10
|
+
|
11
|
+
# rubocop:disable Layout/LineLength
|
12
|
+
OPT_PASSES = {
|
13
|
+
'0' => 'always-inline,coro-cond(coro-early,cgscc(coro-split),coro-cleanup,globaldce),function(annotation-remarks),verify',
|
14
|
+
'1' => 'annotation2metadata,forceattrs,inferattrs,coro-early,function<eager-inv>(lower-expect,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,sroa<modify-cfg>,early-cse<>),openmp-opt,ipsccp,called-value-propagation,globalopt,function<eager-inv>(mem2reg,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),always-inline,require<globals-aa>,function(invalidate<aa>),require<profile-summary>,cgscc(devirt<4>(inline,function-attrs<skip-non-recursive-function-attrs>,function<eager-inv;no-rerun>(sroa<modify-cfg>,early-cse<memssa>,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,libcalls-shrinkwrap,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,reassociate,loop-mssa(loop-instsimplify,loop-simplifycfg,licm<no-allowspeculation>,loop-rotate<header-duplication;no-prepare-for-lto>,licm<allowspeculation>,simple-loop-unswitch<no-nontrivial;trivial>),simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop(loop-idiom,indvars,loop-deletion,loop-unroll-full),sroa<modify-cfg>,memcpyopt,sccp,bdce,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,coro-elide,adce,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>),function-attrs,function(require<should-not-run-function-passes>),coro-split)),deadargelim,coro-cleanup,globalopt,globaldce,elim-avail-extern,rpo-function-attrs,recompute-globalsaa,function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O1>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),globaldce,constmerge,cg-profile,rel-lookup-table-converter,function(annotation-remarks),verify',
|
15
|
+
'2' => 'annotation2metadata,forceattrs,inferattrs,coro-early,function<eager-inv>(lower-expect,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,sroa<modify-cfg>,early-cse<>),openmp-opt,ipsccp,called-value-propagation,globalopt,function<eager-inv>(mem2reg,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),always-inline,require<globals-aa>,function(invalidate<aa>),require<profile-summary>,cgscc(devirt<4>(inline,function-attrs<skip-non-recursive-function-attrs>,openmp-opt-cgscc,function<eager-inv;no-rerun>(sroa<modify-cfg>,early-cse<memssa>,speculative-execution<only-if-divergent-target>,jump-threading,correlated-propagation,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,aggressive-instcombine,libcalls-shrinkwrap,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,reassociate,constraint-elimination,loop-mssa(loop-instsimplify,loop-simplifycfg,licm<no-allowspeculation>,loop-rotate<header-duplication;no-prepare-for-lto>,licm<allowspeculation>,simple-loop-unswitch<no-nontrivial;trivial>),simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop(loop-idiom,indvars,loop-deletion,loop-unroll-full),sroa<modify-cfg>,vector-combine,mldst-motion<no-split-footer-bb>,gvn<>,sccp,bdce,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,jump-threading,correlated-propagation,adce,memcpyopt,dse,move-auto-init,loop-mssa(licm<allowspeculation>),coro-elide,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>),function-attrs,function(require<should-not-run-function-passes>),coro-split)),deadargelim,coro-cleanup,globalopt,globaldce,elim-avail-extern,rpo-function-attrs,recompute-globalsaa,function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),globaldce,constmerge,cg-profile,rel-lookup-table-converter,function(annotation-remarks),verify',
|
16
|
+
'3' => 'annotation2metadata,forceattrs,inferattrs,coro-early,function<eager-inv>(lower-expect,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,sroa<modify-cfg>,early-cse<>,callsite-splitting),openmp-opt,ipsccp,called-value-propagation,globalopt,function<eager-inv>(mem2reg,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),always-inline,require<globals-aa>,function(invalidate<aa>),require<profile-summary>,cgscc(devirt<4>(inline,function-attrs<skip-non-recursive-function-attrs>,argpromotion,openmp-opt-cgscc,function<eager-inv;no-rerun>(sroa<modify-cfg>,early-cse<memssa>,speculative-execution<only-if-divergent-target>,jump-threading,correlated-propagation,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,aggressive-instcombine,libcalls-shrinkwrap,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,reassociate,constraint-elimination,loop-mssa(loop-instsimplify,loop-simplifycfg,licm<no-allowspeculation>,loop-rotate<header-duplication;no-prepare-for-lto>,licm<allowspeculation>,simple-loop-unswitch<nontrivial;trivial>),simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop(loop-idiom,indvars,loop-deletion,loop-unroll-full),sroa<modify-cfg>,vector-combine,mldst-motion<no-split-footer-bb>,gvn<>,sccp,bdce,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,jump-threading,correlated-propagation,adce,memcpyopt,dse,move-auto-init,loop-mssa(licm<allowspeculation>),coro-elide,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>),function-attrs,function(require<should-not-run-function-passes>),coro-split)),deadargelim,coro-cleanup,globalopt,globaldce,elim-avail-extern,rpo-function-attrs,recompute-globalsaa,function<eager-inv>(float2int,lower-constant-intrinsics,chr,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O3>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),globaldce,constmerge,cg-profile,rel-lookup-table-converter,function(annotation-remarks),verify',
|
17
|
+
's' => 'annotation2metadata,forceattrs,inferattrs,coro-early,function<eager-inv>(lower-expect,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,sroa<modify-cfg>,early-cse<>),openmp-opt,ipsccp,called-value-propagation,globalopt,function<eager-inv>(mem2reg,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),always-inline,require<globals-aa>,function(invalidate<aa>),require<profile-summary>,cgscc(devirt<4>(inline,function-attrs<skip-non-recursive-function-attrs>,function<eager-inv;no-rerun>(sroa<modify-cfg>,early-cse<memssa>,speculative-execution<only-if-divergent-target>,jump-threading,correlated-propagation,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,aggressive-instcombine,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,reassociate,constraint-elimination,loop-mssa(loop-instsimplify,loop-simplifycfg,licm<no-allowspeculation>,loop-rotate<header-duplication;no-prepare-for-lto>,licm<allowspeculation>,simple-loop-unswitch<no-nontrivial;trivial>),simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop(loop-idiom,indvars,loop-deletion,loop-unroll-full),sroa<modify-cfg>,vector-combine,mldst-motion<no-split-footer-bb>,gvn<>,sccp,bdce,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,jump-threading,correlated-propagation,adce,memcpyopt,dse,move-auto-init,loop-mssa(licm<allowspeculation>),coro-elide,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>),function-attrs,function(require<should-not-run-function-passes>),coro-split)),deadargelim,coro-cleanup,globalopt,globaldce,elim-avail-extern,rpo-function-attrs,recompute-globalsaa,function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),globaldce,constmerge,cg-profile,rel-lookup-table-converter,function(annotation-remarks),verify',
|
18
|
+
'z' => 'annotation2metadata,forceattrs,inferattrs,coro-early,function<eager-inv>(lower-expect,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,sroa<modify-cfg>,early-cse<>),openmp-opt,ipsccp,called-value-propagation,globalopt,function<eager-inv>(mem2reg,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),always-inline,require<globals-aa>,function(invalidate<aa>),require<profile-summary>,cgscc(devirt<4>(inline,function-attrs<skip-non-recursive-function-attrs>,function<eager-inv;no-rerun>(sroa<modify-cfg>,early-cse<memssa>,speculative-execution<only-if-divergent-target>,jump-threading,correlated-propagation,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,aggressive-instcombine,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,reassociate,constraint-elimination,loop-mssa(loop-instsimplify,loop-simplifycfg,licm<no-allowspeculation>,loop-rotate<no-header-duplication;no-prepare-for-lto>,licm<allowspeculation>,simple-loop-unswitch<no-nontrivial;trivial>),simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop(loop-idiom,indvars,loop-deletion,loop-unroll-full),sroa<modify-cfg>,vector-combine,mldst-motion<no-split-footer-bb>,gvn<>,sccp,bdce,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,jump-threading,correlated-propagation,adce,memcpyopt,dse,move-auto-init,loop-mssa(licm<allowspeculation>),coro-elide,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>),function-attrs,function(require<should-not-run-function-passes>),coro-split)),deadargelim,coro-cleanup,globalopt,globaldce,elim-avail-extern,rpo-function-attrs,recompute-globalsaa,function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<no-header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>),globaldce,constmerge,cg-profile,rel-lookup-table-converter,function(annotation-remarks),verify',
|
19
|
+
}.freeze
|
20
|
+
# rubocop:enable Layout/LineLength
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@passes = []
|
24
|
+
@inliner_threshold = nil
|
25
|
+
@merge_functions = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_function_pass
|
29
|
+
pb = PassBuilder.new
|
30
|
+
if block_given?
|
31
|
+
yield pb
|
32
|
+
end
|
33
|
+
|
34
|
+
add_pass("function(#{pb.pass_string})")
|
35
|
+
end
|
36
|
+
|
37
|
+
# --O0 - Optimization level 0. Similar to clang -O0. Use -passes='default<O0>' for the new PM
|
38
|
+
# --O1 - Optimization level 1. Similar to clang -O1. Use -passes='default<O1>' for the new PM
|
39
|
+
# --O2 - Optimization level 2. Similar to clang -O2. Use -passes='default<O2>' for the new PM
|
40
|
+
# --O3 - Optimization level 3. Similar to clang -O3. Use -passes='default<O3>' for the new PM
|
41
|
+
# --Os - Like -O2 but size-conscious. Similar to clang -Os. Use -passes='default<Os>' for the new PM
|
42
|
+
# --Oz - Like -O2 but optimize for code size above all else. Similar to clang -Oz. Use -passes='default<Oz>' for the new PM
|
43
|
+
# @return self
|
44
|
+
def o!(opt_level = '0', options = {})
|
45
|
+
opt_level = opt_level.to_s
|
46
|
+
expanded_pass = OPT_PASSES[opt_level]
|
47
|
+
|
48
|
+
if expanded_pass.nil?
|
49
|
+
return add_pass("default<O#{opt_level}>")
|
50
|
+
end
|
51
|
+
|
52
|
+
if options[:disable_inline]
|
53
|
+
expanded_pass = expanded_pass.gsub('devirt<4>(inline,', 'devirt<4>(')
|
54
|
+
end
|
55
|
+
if options[:disable_always_inline]
|
56
|
+
expanded_pass = expanded_pass.gsub('always-inline,', '')
|
57
|
+
end
|
58
|
+
add_pass(expanded_pass)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return self
|
62
|
+
def add_pass(pass)
|
63
|
+
passes << pass
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return self
|
68
|
+
def dce!
|
69
|
+
add_pass('dce')
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return self
|
73
|
+
def licm!
|
74
|
+
add_pass('licm')
|
75
|
+
end
|
76
|
+
|
77
|
+
# A pass to simplify and canonicalize the CFG of a function.
|
78
|
+
# This pass iteratively simplifies the entire CFG of a function. It may change
|
79
|
+
# or remove control flow to put the CFG into a canonical form expected by
|
80
|
+
# other passes of the mid-level optimizer. Depending on the specified options,
|
81
|
+
# it may further optimize control-flow to create non-canonical form
|
82
|
+
# https://llvm.org/doxygen/SimplifyCFG_8h_source.html
|
83
|
+
# TODO: takes params
|
84
|
+
# Options: simplifycfg<no-forward-switch-cond;forward-switch-cond;no-switch-range-to-icmp;switch-range-to-icmp;no-switch-to-lookup;switch-to-lookup;no-keep-loops;keep-loops;no-hoist-common-insts;hoist-common-insts;no-sink-common-insts;sink-common-insts;bonus-inst-threshold=N>
|
85
|
+
# @return self
|
86
|
+
def simplifycfg!
|
87
|
+
add_pass('simplifycfg')
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return self
|
91
|
+
def scalarizer!
|
92
|
+
add_pass('scalarizer')
|
93
|
+
end
|
94
|
+
|
95
|
+
# Merged Load Store Motion
|
96
|
+
# @return self
|
97
|
+
def mldst_motion!
|
98
|
+
add_pass('mldst-motion')
|
99
|
+
end
|
100
|
+
|
101
|
+
# Global Value Numbering pass
|
102
|
+
# https://llvm.org/doxygen/GVN_8h_source.html
|
103
|
+
# TODO: takes params
|
104
|
+
# @return self
|
105
|
+
def gvn!
|
106
|
+
add_pass('gvn')
|
107
|
+
end
|
108
|
+
|
109
|
+
# New Global Value Numbering pass
|
110
|
+
# https://llvm.org/doxygen/NewGVN_8cpp.html#details
|
111
|
+
# @return self
|
112
|
+
def newgvn!
|
113
|
+
add_pass('newgvn')
|
114
|
+
end
|
115
|
+
|
116
|
+
# hoists expressions from branches to a common dominator.
|
117
|
+
# https://llvm.org/doxygen/GVNHoist_8cpp_source.html
|
118
|
+
# @return self
|
119
|
+
def gvn_hoist!
|
120
|
+
add_pass('gvn-hoist')
|
121
|
+
end
|
122
|
+
|
123
|
+
# sink instructions into successors
|
124
|
+
# https://llvm.org/doxygen/GVNSink_8cpp_source.html
|
125
|
+
# @return self
|
126
|
+
def gvn_sink!
|
127
|
+
add_pass('gvn-sink')
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return self
|
131
|
+
def jump_threading!
|
132
|
+
add_pass('jump-threading')
|
133
|
+
end
|
134
|
+
|
135
|
+
# @return self
|
136
|
+
def indvars!
|
137
|
+
add_pass('indvars')
|
138
|
+
end
|
139
|
+
|
140
|
+
# @return self
|
141
|
+
def alignment_from_assumptions!
|
142
|
+
add_pass('alignment-from-assumptions')
|
143
|
+
end
|
144
|
+
|
145
|
+
# @return self
|
146
|
+
def loop_deletion!
|
147
|
+
add_pass('loop-deletion')
|
148
|
+
end
|
149
|
+
|
150
|
+
# @return self
|
151
|
+
def loop_idiom!
|
152
|
+
add_pass('loop-idiom')
|
153
|
+
end
|
154
|
+
|
155
|
+
# @return self
|
156
|
+
def loop_rotate!
|
157
|
+
add_pass('loop-rotate')
|
158
|
+
end
|
159
|
+
|
160
|
+
# @return self
|
161
|
+
def loop_reroll!
|
162
|
+
add_pass('loop-reroll')
|
163
|
+
end
|
164
|
+
|
165
|
+
# @return self
|
166
|
+
def loop_unroll!
|
167
|
+
add_pass('loop-unroll')
|
168
|
+
end
|
169
|
+
|
170
|
+
# @return self
|
171
|
+
def loop_unroll_and_jam!
|
172
|
+
add_pass('loop-unroll-and-jam')
|
173
|
+
end
|
174
|
+
|
175
|
+
# @return self
|
176
|
+
def simple_loop_unswitch!
|
177
|
+
add_pass('simple-loop-unswitch')
|
178
|
+
end
|
179
|
+
|
180
|
+
# @return self
|
181
|
+
def loop_unswitch!
|
182
|
+
simple_loop_unswitch!
|
183
|
+
end
|
184
|
+
|
185
|
+
# TODO: takes params
|
186
|
+
# @return self
|
187
|
+
def loop_vectorize!
|
188
|
+
add_pass('loop-vectorize')
|
189
|
+
end
|
190
|
+
|
191
|
+
# @return self
|
192
|
+
def memcpyopt!
|
193
|
+
add_pass('memcpyopt')
|
194
|
+
end
|
195
|
+
|
196
|
+
# @return self
|
197
|
+
def sccp!
|
198
|
+
add_pass('sccp')
|
199
|
+
end
|
200
|
+
|
201
|
+
# Combine instructions to form fewer, simple instructions.
|
202
|
+
# This pass does not modify the CFG.
|
203
|
+
# This pass is where algebraic simplification happens.
|
204
|
+
# https://llvm.org/doxygen/InstructionCombining_8cpp_source.html
|
205
|
+
# https://llvm.org/doxygen/InstCombineInternal_8h_source.html
|
206
|
+
# @return self
|
207
|
+
def instcombine!
|
208
|
+
add_pass('instcombine')
|
209
|
+
end
|
210
|
+
|
211
|
+
# @return self
|
212
|
+
def instsimplify!
|
213
|
+
add_pass('instsimplify')
|
214
|
+
end
|
215
|
+
|
216
|
+
# @return self
|
217
|
+
def loweratomic!
|
218
|
+
add_pass('loweratomic')
|
219
|
+
end
|
220
|
+
|
221
|
+
# @return self
|
222
|
+
def partially_inline_libcalls!
|
223
|
+
add_pass('partially-inline-libcalls')
|
224
|
+
end
|
225
|
+
|
226
|
+
# @return self
|
227
|
+
def reassociate!
|
228
|
+
add_pass('reassociate')
|
229
|
+
end
|
230
|
+
|
231
|
+
# @return self
|
232
|
+
def tailcallelim!
|
233
|
+
add_pass('tailcallelim')
|
234
|
+
end
|
235
|
+
|
236
|
+
# @return self
|
237
|
+
def reg2mem!
|
238
|
+
add_pass('reg2mem')
|
239
|
+
end
|
240
|
+
|
241
|
+
# @return self
|
242
|
+
def mem2reg!
|
243
|
+
add_pass('mem2reg')
|
244
|
+
end
|
245
|
+
|
246
|
+
# @return self
|
247
|
+
def verify!
|
248
|
+
add_pass('verify')
|
249
|
+
end
|
250
|
+
|
251
|
+
# @return self
|
252
|
+
def module_summary!
|
253
|
+
add_pass('require<module-summary>')
|
254
|
+
end
|
255
|
+
|
256
|
+
# @return self
|
257
|
+
def no_op_module!
|
258
|
+
add_pass('no-op-module')
|
259
|
+
end
|
260
|
+
|
261
|
+
# @return self
|
262
|
+
def no_op_cgscc!
|
263
|
+
add_pass('no-op-cgscc')
|
264
|
+
end
|
265
|
+
|
266
|
+
# @return self
|
267
|
+
def no_op_function!
|
268
|
+
add_pass('no-op-function')
|
269
|
+
end
|
270
|
+
|
271
|
+
# @return self
|
272
|
+
def stack_safety!
|
273
|
+
add_pass('require<stack-safety>')
|
274
|
+
end
|
275
|
+
|
276
|
+
# A simple and fast domtree-based CSE pass.
|
277
|
+
#
|
278
|
+
# This pass does a simple depth-first walk over the dominator tree,
|
279
|
+
# eliminating trivially redundant instructions and using instsimplify to
|
280
|
+
# canonicalize things as it goes. It is intended to be fast and catch obvious
|
281
|
+
# cases so that instcombine and other passes are more effective. It is
|
282
|
+
# expected that a later pass of GVN will catch the interesting/hard cases.
|
283
|
+
# https://llvm.org/doxygen/EarlyCSE_8h_source.html
|
284
|
+
# https://llvm.org/doxygen/EarlyCSE_8cpp.html
|
285
|
+
# @return self
|
286
|
+
def early_cse!
|
287
|
+
add_pass('early-cse')
|
288
|
+
end
|
289
|
+
|
290
|
+
# A simple and fast domtree-based CSE pass.
|
291
|
+
# https://llvm.org/doxygen/EarlyCSE_8h_source.html
|
292
|
+
# https://llvm.org/doxygen/EarlyCSE_8cpp.html
|
293
|
+
# @return self
|
294
|
+
def early_cse_memssa!
|
295
|
+
add_pass('early-cse<memssa>')
|
296
|
+
end
|
297
|
+
|
298
|
+
# @return self
|
299
|
+
def lcssa!
|
300
|
+
add_pass('lcssa')
|
301
|
+
end
|
302
|
+
|
303
|
+
# @return self
|
304
|
+
def memoryssa!
|
305
|
+
add_pass('require<memoryssa>')
|
306
|
+
end
|
307
|
+
|
308
|
+
# Scalar Replacement Of Aggregates
|
309
|
+
# https://llvm.org/doxygen/SROA_8h_source.html
|
310
|
+
# https://llvm.org/doxygen/SROA_8cpp.html
|
311
|
+
# @return self
|
312
|
+
def sroa!
|
313
|
+
add_pass('sroa')
|
314
|
+
end
|
315
|
+
|
316
|
+
# @return self
|
317
|
+
def lower_expect!
|
318
|
+
add_pass('lower-expect')
|
319
|
+
end
|
320
|
+
|
321
|
+
# @return self
|
322
|
+
def cvprop!
|
323
|
+
correlated_propagation!
|
324
|
+
end
|
325
|
+
|
326
|
+
# @return self
|
327
|
+
def correlated_propagation!
|
328
|
+
add_pass('correlated-propagation')
|
329
|
+
end
|
330
|
+
|
331
|
+
# @return self
|
332
|
+
def lower_constant_intrinsics!
|
333
|
+
add_pass('lower-constant-intrinsics')
|
334
|
+
end
|
335
|
+
|
336
|
+
# @return self
|
337
|
+
def slp_vectorize!
|
338
|
+
slp_vectorizer!
|
339
|
+
end
|
340
|
+
|
341
|
+
# @return self
|
342
|
+
def slp_vectorizer!
|
343
|
+
add_pass('slp-vectorizer')
|
344
|
+
end
|
345
|
+
|
346
|
+
# @return self
|
347
|
+
def add_discriminators!
|
348
|
+
add_pass('add-discriminators')
|
349
|
+
end
|
350
|
+
|
351
|
+
# @return self
|
352
|
+
def mergereturn!
|
353
|
+
add_pass('mergereturn')
|
354
|
+
end
|
355
|
+
|
356
|
+
# @return self
|
357
|
+
def mergeicmps!
|
358
|
+
add_pass('mergeicmps')
|
359
|
+
end
|
360
|
+
|
361
|
+
# @return self
|
362
|
+
def basic_aa!
|
363
|
+
add_pass('require<basic-aa>')
|
364
|
+
end
|
365
|
+
|
366
|
+
alias basicaa! basic_aa!
|
367
|
+
|
368
|
+
# @return self
|
369
|
+
def objc_arc_aa
|
370
|
+
add_pass('require<objc-arc-aa>')
|
371
|
+
end
|
372
|
+
|
373
|
+
# @return self
|
374
|
+
def scev_aa!
|
375
|
+
add_pass('require<scev-aa>')
|
376
|
+
end
|
377
|
+
|
378
|
+
# @return self
|
379
|
+
def scoped_noalias_aa!
|
380
|
+
add_pass('require<scoped-noalias-aa>')
|
381
|
+
end
|
382
|
+
|
383
|
+
# @return self
|
384
|
+
def tbaa!
|
385
|
+
add_pass('require<tbaa>')
|
386
|
+
end
|
387
|
+
|
388
|
+
# @return self
|
389
|
+
def gobals_aa!
|
390
|
+
add_pass('require<globals-aa>')
|
391
|
+
end
|
392
|
+
|
393
|
+
# @return self
|
394
|
+
def lowerswitch!
|
395
|
+
add_pass('lowerswitch')
|
396
|
+
end
|
397
|
+
|
398
|
+
# Inlines functions marked as "always_inline".
|
399
|
+
# https://llvm.org/doxygen/AlwaysInliner_8h_source.html
|
400
|
+
# https://llvm.org/doxygen/AlwaysInliner_8cpp_source.html
|
401
|
+
# @return self
|
402
|
+
def always_inline!
|
403
|
+
add_pass('always-inline')
|
404
|
+
end
|
405
|
+
|
406
|
+
# This pass looks for equivalent functions that are mergable and folds them.
|
407
|
+
# https://llvm.org/docs/MergeFunctions.html
|
408
|
+
# https://llvm.org/doxygen/MergeFunctions_8cpp_source.html
|
409
|
+
# https://llvm.org/doxygen/MergeFunctions_8h_source.html
|
410
|
+
# @return self
|
411
|
+
def mergefunc!
|
412
|
+
add_pass('mergefunc')
|
413
|
+
end
|
414
|
+
|
415
|
+
# Propagate called values
|
416
|
+
# This file implements a transformation that attaches !callees metadata to
|
417
|
+
# indirect call sites. For a given call site, the metadata, if present,
|
418
|
+
# indicates the set of functions the call site could possibly target at
|
419
|
+
# run-time. This metadata is added to indirect call sites when the set of
|
420
|
+
# possible targets can be determined by analysis and is known to be small. The
|
421
|
+
# analysis driving the transformation is similar to constant propagation and
|
422
|
+
# makes uses of the generic sparse propagation solver.
|
423
|
+
# https://llvm.org/doxygen/CalledValuePropagation_8h_source.html
|
424
|
+
# @return self
|
425
|
+
def called_value_propagation!
|
426
|
+
add_pass('called-value-propagation')
|
427
|
+
end
|
428
|
+
|
429
|
+
# @return self
|
430
|
+
def deadargelim!
|
431
|
+
add_pass('deadargelim')
|
432
|
+
end
|
433
|
+
|
434
|
+
alias dae! deadargelim!
|
435
|
+
|
436
|
+
# ConstantMerge is designed to build up a map of available constants and eliminate duplicates when it is initialized.
|
437
|
+
# https://llvm.org/doxygen/ConstantMerge_8cpp_source.html
|
438
|
+
# https://llvm.org/doxygen/ConstantMerge_8h_source.html
|
439
|
+
# @return self
|
440
|
+
def constmerge!
|
441
|
+
add_pass('constmerge')
|
442
|
+
end
|
443
|
+
|
444
|
+
alias const_merge! constmerge!
|
445
|
+
|
446
|
+
# Aggressive Dead Code Elimination
|
447
|
+
# @return self
|
448
|
+
def adce!
|
449
|
+
add_pass('adce')
|
450
|
+
end
|
451
|
+
|
452
|
+
# @return self
|
453
|
+
def function_attrs!
|
454
|
+
add_pass('function-attrs')
|
455
|
+
end
|
456
|
+
|
457
|
+
alias fun_attrs! function_attrs!
|
458
|
+
|
459
|
+
# @return self
|
460
|
+
def strip!
|
461
|
+
add_pass('strip')
|
462
|
+
end
|
463
|
+
|
464
|
+
# @return self
|
465
|
+
def strip_dead_prototypes!
|
466
|
+
add_pass('strip-dead-prototypes')
|
467
|
+
end
|
468
|
+
|
469
|
+
alias sdp! strip_dead_prototypes!
|
470
|
+
|
471
|
+
# @return self
|
472
|
+
# TODO: test this
|
473
|
+
def internalize!(_all_but_main = true) # rubocop:disable Style/OptionalBooleanParameter
|
474
|
+
add_pass('internalize')
|
475
|
+
end
|
476
|
+
|
477
|
+
# This pass implements interprocedural sparse conditional constant propagation and merging.
|
478
|
+
# https://llvm.org/doxygen/IPO_2SCCP_8h_source.html
|
479
|
+
# https://llvm.org/doxygen/IPO_2SCCP_8cpp_source.html
|
480
|
+
# @return self
|
481
|
+
# @todo accept parameters ipsccp<no-func-spec;func-spec>
|
482
|
+
def ipsccp!
|
483
|
+
add_pass('ipsccp')
|
484
|
+
end
|
485
|
+
|
486
|
+
# @return self
|
487
|
+
def global_opt!
|
488
|
+
add_pass('globalopt')
|
489
|
+
end
|
490
|
+
|
491
|
+
# Global Dead Code Elimination
|
492
|
+
# TODO: takes params
|
493
|
+
# @return self
|
494
|
+
def globaldce!
|
495
|
+
add_pass('globaldce')
|
496
|
+
end
|
497
|
+
|
498
|
+
alias gdce! globaldce!
|
499
|
+
|
500
|
+
# Bit-Tracking Dead Code Elimination pass
|
501
|
+
# @return self
|
502
|
+
def bdce!
|
503
|
+
add_pass('bdce')
|
504
|
+
end
|
505
|
+
|
506
|
+
# Dead Store Elimination
|
507
|
+
# his file implements a trivial dead store elimination that only considers basic-block local redundant stores.
|
508
|
+
# https://llvm.org/doxygen/DeadStoreElimination_8h_source.html
|
509
|
+
# @return self
|
510
|
+
def dse!
|
511
|
+
add_pass('dse')
|
512
|
+
end
|
513
|
+
|
514
|
+
# @return self
|
515
|
+
def argpromotion!
|
516
|
+
add_pass('argpromotion')
|
517
|
+
end
|
518
|
+
|
519
|
+
alias arg_promote! argpromotion!
|
520
|
+
|
521
|
+
# The inliner pass for the new pass manager.
|
522
|
+
# https://llvm.org/doxygen/classllvm_1_1InlinerPass.html
|
523
|
+
# https://llvm.org/doxygen/Inliner_8h_source.html
|
524
|
+
# https://llvm.org/doxygen/Inliner_8cpp_source.html
|
525
|
+
# @return self
|
526
|
+
def inline!
|
527
|
+
add_pass('inline')
|
528
|
+
end
|
529
|
+
|
530
|
+
# Thread Sanitizer
|
531
|
+
# https://clang.llvm.org/docs/ThreadSanitizer.html
|
532
|
+
# @return self
|
533
|
+
def tsan!
|
534
|
+
add_pass('tsan')
|
535
|
+
end
|
536
|
+
|
537
|
+
# Thread Sanitiver - Module
|
538
|
+
# https://clang.llvm.org/docs/ThreadSanitizer.html
|
539
|
+
# @return self
|
540
|
+
def tsan_module!
|
541
|
+
add_pass('tsan-module')
|
542
|
+
end
|
543
|
+
|
544
|
+
# Hardware Assisted Address Sanitiver
|
545
|
+
# TODO: takes params
|
546
|
+
# https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html
|
547
|
+
# https://llvm.org/doxygen/HWAddressSanitizer_8cpp_source.html
|
548
|
+
# @return self
|
549
|
+
def hwasan!(_options = {})
|
550
|
+
add_pass('hwasan')
|
551
|
+
end
|
552
|
+
|
553
|
+
# Address Sanitizer
|
554
|
+
# TODO: takes params
|
555
|
+
# https://clang.llvm.org/docs/AddressSanitizer.html
|
556
|
+
# https://llvm.org/doxygen/AddressSanitizer_8h_source.html
|
557
|
+
# https://llvm.org/doxygen/AddressSanitizer_8cpp_source.html
|
558
|
+
# @return self
|
559
|
+
def asan!(options = {})
|
560
|
+
opt_str = options[:kernel] ? '<kernel>' : ''
|
561
|
+
add_pass("asan#{opt_str}")
|
562
|
+
end
|
563
|
+
|
564
|
+
# Memory Sanitizer
|
565
|
+
# TODO: takes params
|
566
|
+
# https://llvm.org/doxygen/MemorySanitizer_8cpp.html
|
567
|
+
# https://llvm.org/doxygen/MemorySanitizer_8h_source.html
|
568
|
+
# https://clang.llvm.org/docs/MemorySanitizer.html
|
569
|
+
# KernelMemorySanitizer only supports X86_64 and SystemZ at the moment.
|
570
|
+
# @return self
|
571
|
+
def msan!(options = {})
|
572
|
+
opt_str = options[:kernel] ? '<kernel>' : ''
|
573
|
+
add_pass("msan#{opt_str}")
|
574
|
+
end
|
575
|
+
|
576
|
+
# DataFlow Sanitizer
|
577
|
+
# https://clang.llvm.org/docs/DataFlowSanitizer.html
|
578
|
+
# @return self
|
579
|
+
def dfsan!
|
580
|
+
add_pass('dfsan')
|
581
|
+
end
|
582
|
+
|
583
|
+
# https://clang.llvm.org/docs/SanitizerCoverage.html
|
584
|
+
# @return self
|
585
|
+
def sancov_module!
|
586
|
+
add_pass('sancov-module')
|
587
|
+
end
|
588
|
+
|
589
|
+
# https://llvm.org/docs/doxygen/SanitizerBinaryMetadata_8h_source.html
|
590
|
+
# @return self
|
591
|
+
def sanmd_module!
|
592
|
+
add_pass('sanmd-module')
|
593
|
+
end
|
594
|
+
|
595
|
+
def run(mod, target)
|
596
|
+
return self if passes.empty?
|
597
|
+
|
598
|
+
error = with_options { |options| C.run_passes(mod, pass_string, target, options) }
|
599
|
+
if !error.null?
|
600
|
+
error_msg = C.get_error_message(error)
|
601
|
+
# TODO: clone then dispose of error_msg, currently produces "munmap_chunk(): invalid pointer"
|
602
|
+
# save_message = error_msg.clone
|
603
|
+
# C.dispose_error_message(error_msg)
|
604
|
+
raise ArgumentError, error_msg
|
605
|
+
end
|
606
|
+
self
|
607
|
+
end
|
608
|
+
|
609
|
+
def pass_string
|
610
|
+
passes.join(',')
|
611
|
+
end
|
612
|
+
|
613
|
+
def ipcp!
|
614
|
+
deprecated('ipcp! / LLVMAddIPConstantPropagationPass was removed from LLVM')
|
615
|
+
end
|
616
|
+
|
617
|
+
def prune_eh!
|
618
|
+
deprecated('prune_eh! / LLVMAddPruneEHPass was removed in LLVM 16')
|
619
|
+
end
|
620
|
+
|
621
|
+
def simplify_libcalls!
|
622
|
+
deprecated('simplify_libcalls! / LLVMAddSimplifyLibCallsPass was removed from LLVM')
|
623
|
+
end
|
624
|
+
|
625
|
+
def scalarrepl!
|
626
|
+
deprecated('TODO: scalarrepl')
|
627
|
+
end
|
628
|
+
|
629
|
+
def scalarrepl_ssa!
|
630
|
+
deprecated('TODO: scalarrepl_ssa')
|
631
|
+
end
|
632
|
+
|
633
|
+
def scalarrepl_threshold!(_threshold = 0)
|
634
|
+
deprecated('TODO: scalarrepl_threshold')
|
635
|
+
end
|
636
|
+
|
637
|
+
def bb_vectorize!
|
638
|
+
warn('bb_vectorize! / LLVMAddBBVectorizePass was removed from LLVM - replace with slp_vectorize!')
|
639
|
+
slp_vectorize!
|
640
|
+
end
|
641
|
+
|
642
|
+
def constprop!
|
643
|
+
warn('constprop! / LLVMAddConstantPropagationPass was removed from LLVM')
|
644
|
+
end
|
645
|
+
|
646
|
+
private
|
647
|
+
|
648
|
+
attr_writer :passes
|
649
|
+
|
650
|
+
def deprecated(message)
|
651
|
+
warn message
|
652
|
+
self
|
653
|
+
end
|
654
|
+
|
655
|
+
# updates options parameter and returns it
|
656
|
+
def build_options!(options)
|
657
|
+
if inliner_threshold
|
658
|
+
C.set_inliner_threshold(options, inliner_threshold)
|
659
|
+
end
|
660
|
+
|
661
|
+
if merge_functions
|
662
|
+
C.set_merge_functions(options, !!merge_functions)
|
663
|
+
end
|
664
|
+
|
665
|
+
options
|
666
|
+
end
|
667
|
+
|
668
|
+
# wraps creation and disposal of options in block
|
669
|
+
def with_options
|
670
|
+
options = C.create_pass_builder_options
|
671
|
+
build_options!(options)
|
672
|
+
yield options
|
673
|
+
ensure
|
674
|
+
C.dispose_pass_builder_options(options)
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
module C
|
679
|
+
#
|
680
|
+
# @method run_passes(pmb, opt_level)
|
681
|
+
# @param [OpaquePassManagerBuilder] pmb
|
682
|
+
# @param [Integer] opt_level
|
683
|
+
# @return [nil]
|
684
|
+
# @scope class
|
685
|
+
# /**
|
686
|
+
# * Construct and run a set of passes over a module
|
687
|
+
# *
|
688
|
+
# * This function takes a string with the passes that should be used. The format
|
689
|
+
# * of this string is the same as opt's -passes argument for the new pass
|
690
|
+
# * manager. Individual passes may be specified, separated by commas. Full
|
691
|
+
# * pipelines may also be invoked using `default<O3>` and friends. See opt for
|
692
|
+
# * full reference of the Passes format.
|
693
|
+
# */
|
694
|
+
# LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes,
|
695
|
+
# LLVMTargetMachineRef TM,
|
696
|
+
# LLVMPassBuilderOptionsRef Options);
|
697
|
+
|
698
|
+
attach_function :run_passes, :LLVMRunPasses, [:pointer, :string, :pointer, :pointer], :pointer
|
699
|
+
|
700
|
+
attach_function :create_pass_builder_options, :LLVMCreatePassBuilderOptions, [], :pointer
|
701
|
+
|
702
|
+
attach_function :dispose_pass_builder_options, :LLVMDisposePassBuilderOptions, [:pointer], :void
|
703
|
+
|
704
|
+
attach_function(:get_error_message, :LLVMGetErrorMessage, [:pointer], :string)
|
705
|
+
|
706
|
+
attach_function(:dispose_error_message, :LLVMDisposeErrorMessage, [:string], :void)
|
707
|
+
|
708
|
+
attach_function(:set_inliner_threshold, :LLVMPassBuilderOptionsSetInlinerThreshold, [:pointer, :int], :void)
|
709
|
+
|
710
|
+
attach_function(:set_merge_functions, :LLVMPassBuilderOptionsSetMergeFunctions, [:pointer, :bool], :void)
|
711
|
+
end
|
712
|
+
end
|