1111
1212#include " bolt/Core/BinaryFunction.h"
1313#include " bolt/Passes/BinaryPasses.h"
14+ #include " llvm/ADT/SparseBitVector.h"
1415
1516namespace llvm {
1617namespace bolt {
@@ -20,22 +21,72 @@ namespace bolt {
2021// /
2122class IdenticalCodeFolding : public BinaryFunctionPass {
2223protected:
23- bool shouldOptimize (const BinaryFunction &BF) const override {
24- if (BF.hasUnknownControlFlow ())
25- return false ;
26- if (BF.isFolded ())
27- return false ;
28- if (BF.hasSDTMarker ())
29- return false ;
30- return BinaryFunctionPass::shouldOptimize (BF);
31- }
24+ // / Return true if the function is safe to fold.
25+ bool shouldOptimize (const BinaryFunction &BF) const override ;
3226
3327public:
28+ enum class ICFLevel {
29+ None, // / No ICF. (Default)
30+ Safe, // / Safe ICF.
31+ All, // / Aggressive ICF.
32+ };
3433 explicit IdenticalCodeFolding (const cl::opt<bool > &PrintPass)
3534 : BinaryFunctionPass(PrintPass) {}
3635
3736 const char *getName () const override { return " identical-code-folding" ; }
3837 Error runOnFunctions (BinaryContext &BC) override ;
38+
39+ private:
40+ // / Bit vector of memory addresses of vtables.
41+ llvm::SparseBitVector<> VTableBitVector;
42+
43+ // / Return true if the memory address is in a vtable.
44+ bool isAddressInVTable (uint64_t Address) const {
45+ return VTableBitVector.test (Address / 8 );
46+ }
47+
48+ // / Mark memory address of a vtable as used.
49+ void setAddressUsedInVTable (uint64_t Address) {
50+ VTableBitVector.set (Address / 8 );
51+ }
52+
53+ // / Scan symbol table and mark memory addresses of
54+ // / vtables.
55+ void initVTableReferences (const BinaryContext &BC);
56+
57+ // / Analyze code section and relocations and mark functions that are not
58+ // / safe to fold.
59+ void markFunctionsUnsafeToFold (BinaryContext &BC);
60+
61+ // / Process static and dynamic relocations in the data sections to identify
62+ // / function references, and mark them as unsafe to fold. It filters out
63+ // / symbol references that are in vtables.
64+ void analyzeDataRelocations (BinaryContext &BC);
65+
66+ // / Process functions that have been disassembled and mark functions that are
67+ // / used in non-control flow instructions as unsafe to fold.
68+ void analyzeFunctions (BinaryContext &BC);
69+ };
70+
71+ class DeprecatedICFNumericOptionParser
72+ : public cl::parser<IdenticalCodeFolding::ICFLevel> {
73+ public:
74+ explicit DeprecatedICFNumericOptionParser (cl::Option &O)
75+ : cl::parser<IdenticalCodeFolding::ICFLevel>(O) {}
76+
77+ bool parse (cl::Option &O, StringRef ArgName, StringRef Arg,
78+ IdenticalCodeFolding::ICFLevel &Value) {
79+ if (Arg == " 0" || Arg == " 1" ) {
80+ Value = (Arg == " 0" ) ? IdenticalCodeFolding::ICFLevel::None
81+ : IdenticalCodeFolding::ICFLevel::All;
82+ errs () << formatv (" BOLT-WARNING: specifying numeric value \" {0}\" "
83+ " for option -{1} is deprecated\n " ,
84+ Arg, ArgName);
85+ return false ;
86+ }
87+ return cl::parser<IdenticalCodeFolding::ICFLevel>::parse (O, ArgName, Arg,
88+ Value);
89+ }
3990};
4091
4192} // namespace bolt
0 commit comments