|
| 1 | + |
| 2 | +#include "llvm/Analysis/CFG.h" |
| 3 | +#include "llvm/Analysis/DomTreeUpdater.h" |
| 4 | +#include "llvm/Analysis/PostDominators.h" |
| 5 | +#include "llvm/IR/IRBuilder.h" |
| 6 | +#include "llvm/IR/InstIterator.h" |
| 7 | +#include "llvm/IR/Instructions.h" |
| 8 | +#include "llvm/IR/Module.h" |
| 9 | +#include "llvm/IR/PassManager.h" |
| 10 | +#include "llvm/Passes/PassBuilder.h" |
| 11 | +#include "llvm/Passes/PassPlugin.h" |
| 12 | +#include "llvm/Support/raw_ostream.h" |
| 13 | +#include "llvm/Transforms/Utils/BasicBlockUtils.h" |
| 14 | + |
| 15 | +// only needed for printing |
| 16 | +#include <assert.h> |
| 17 | +#include <iostream> |
| 18 | +using namespace llvm; |
| 19 | + |
| 20 | +namespace { |
| 21 | + |
| 22 | +struct ModifyBuildCFG : public PassInfoMixin<ModifyBuildCFG> { |
| 23 | + |
| 24 | + PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) { |
| 25 | + |
| 26 | + if (F.getName() != "main") |
| 27 | + return PreservedAnalyses::all(); |
| 28 | + |
| 29 | + // What we intend do do in the pass starts here. |
| 30 | + LoopInfo &getLI = FAM.getResult<llvm::LoopAnalysis>(F); |
| 31 | + DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F); |
| 32 | + PostDominatorTree &PDT = FAM.getResult<PostDominatorTreeAnalysis>(F); |
| 33 | + |
| 34 | + /** |
| 35 | + * @brief Loop Info Analysis |
| 36 | + */ |
| 37 | + if (getLI.empty()) |
| 38 | + std::cout << "\nNo Loops !\n"; |
| 39 | + else |
| 40 | + getLI.print(errs()); |
| 41 | + |
| 42 | + /** |
| 43 | + * @brief Print Dominator Tree to llvm::errs() |
| 44 | + */ |
| 45 | + DT.print(errs()); |
| 46 | + |
| 47 | + auto DTU = DomTreeUpdater(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy); |
| 48 | + int found = 0; |
| 49 | + |
| 50 | + Instruction *binop = nullptr; |
| 51 | + for (auto &BB : F) { |
| 52 | + errs() << "\t\tBasic Block : " << BB.getName().str() << "\n"; |
| 53 | + for (auto &I : BB) { |
| 54 | + errs() << "\tOperation : " << I.getOpcodeName() << "\n"; |
| 55 | + binop = dyn_cast<BinaryOperator>(&I); |
| 56 | + if (binop != NULL) { |
| 57 | + errs() << "\t\t Binary Operation : " << binop->getOpcodeName() |
| 58 | + << "\n"; |
| 59 | + found = 1; |
| 60 | + break; |
| 61 | + assert(0); |
| 62 | + } |
| 63 | + } |
| 64 | + if (found == 1) |
| 65 | + break; |
| 66 | + } |
| 67 | + |
| 68 | + // Use the operands of a binary operator to |
| 69 | + // get the operands of Compare Not Equal Instruction. |
| 70 | + if (binop != NULL) { |
| 71 | + IRBuilder<> IRModIfElse(binop); |
| 72 | + Value *v1 = binop->getOperand(0); |
| 73 | + Value *v2 = binop->getOperand(1); |
| 74 | + Value *Cmp = IRModIfElse.CreateICmpNE(v1, v2, "dummy_compare_op"); |
| 75 | + Instruction *ThenTerm, *ElseTerm; |
| 76 | + errs() << Cmp->getValueID() << "\n"; |
| 77 | + SplitBlockAndInsertIfThenElse(Cmp, binop, &ThenTerm, &ElseTerm); |
| 78 | + errs() << ThenTerm->getOpcodeName() << "\n"; |
| 79 | + errs() << ElseTerm->getOpcodeName() << "\n"; |
| 80 | + } |
| 81 | + |
| 82 | + for (auto &BB : F) { |
| 83 | + errs() << "\t\tBasic Block : " << BB.getName().str() << "\n"; |
| 84 | + } |
| 85 | + |
| 86 | + // Preserve previous analysis in the pass. Like Dominator information. |
| 87 | + // THe pass we made does not modify that. |
| 88 | + return PreservedAnalyses::none(); |
| 89 | + } |
| 90 | +}; |
| 91 | +} // namespace |
| 92 | + |
| 93 | +// Registering the pass. |
| 94 | +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK |
| 95 | +llvmGetPassPluginInfo() { |
| 96 | + return {LLVM_PLUGIN_API_VERSION, "ModifyBuildCFG", "v0.1", |
| 97 | + [](PassBuilder &PB) { |
| 98 | + PB.registerPipelineParsingCallback( |
| 99 | + [](StringRef Name, FunctionPassManager &FPM, |
| 100 | + ArrayRef<PassBuilder::PipelineElement>) { |
| 101 | + if (Name == "modifyncfg") { |
| 102 | + FPM.addPass(ModifyBuildCFG()); |
| 103 | + return true; |
| 104 | + } |
| 105 | + return false; |
| 106 | + }); |
| 107 | + }}; |
| 108 | +} |
0 commit comments