Guest User

DummyPass

a guest
Jun 19th, 2020
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.53 KB | None | 0 0
  1. // TODO: move this as a proper LLVM pass into the optimization pipeline
  2. // so we'll be able to re-use the precomputed bits analysis results
  3. // and get the optimizations for free
  4. llvm::legacy::PassManager PassRunner;
  5. llvm::legacy::FunctionPassManager FunctionPassRunner(finalFn->getParent());
  6. FunctionPassRunner.add(llvm::createDemandedBitsWrapperPass());
  7. FunctionPassRunner.run(*finalFn);
  8. const llvm::DataLayout &DL = finalFn->getParent()->getDataLayout();
  9. for (auto &BB : *finalFn) {
  10.   for (auto &I : BB) {
  11.     // Check if we found a 'load' instruction
  12.     if (auto *Load = llvm::dyn_cast<llvm::LoadInst>(&I)) {
  13.       if (auto *BitCast = llvm::dyn_cast<llvm::BitCastInst>(Load->getPointerOperand())) {
  14.         if (auto *GEP = llvm::dyn_cast<llvm::GetElementPtrInst>(BitCast->getOperand(0))) {
  15.           // Check if it has a single index
  16.           if (GEP->getNumIndices() == 1) {
  17.             // Determine if the index is an 'add' instruction
  18.             if (auto *BO = llvm::dyn_cast<llvm::BinaryOperator>(GEP->getOperand(1))) {
  19.               if (BO->getOpcode() == llvm::Instruction::BinaryOps::Add) {
  20.                 // Check if one of the operands may be folded to 2 known values
  21.                 auto *Op1 = BO->getOperand(0);
  22.                 auto *Op2 = BO->getOperand(1);
  23.                 auto *Op1Ty = Op1->getType();
  24.                 auto *Op2Ty = Op2->getType();
  25.                 // Compute the known bits (zeros and ones)
  26.                 llvm::KnownBits Op1KnownBits(Op1Ty->getIntegerBitWidth());
  27.                 llvm::KnownBits Op2KnownBits(Op2Ty->getIntegerBitWidth());
  28.                 llvm::computeKnownBits(Op1, Op1KnownBits, DL);
  29.                 llvm::computeKnownBits(Op2, Op2KnownBits, DL);
  30.                 // Determine the unknown bits mask
  31.                 auto Op1UnknownBits = ~(Op1KnownBits.Zero | Op1KnownBits.One);
  32.                 auto Op2UnknownBits = ~(Op2KnownBits.Zero | Op2KnownBits.One);
  33.                 // Determine if we have a value with 1 unknown bit
  34.                 if (Op1UnknownBits.isPowerOf2() && !Op2UnknownBits.isPowerOf2()) {
  35.                   // Fine, we'll handle the case
  36.                 } else if (Op1UnknownBits.isPowerOf2() && !Op2UnknownBits.isPowerOf2()) {
  37.                   // Switch the values
  38.                   auto *Tmp = Op1;
  39.                   Op1 = Op2;
  40.                   Op2 = Tmp;
  41.                 } else {
  42.                   // Stop the optimization
  43.                   continue;
  44.                 }
  45.                 // Get the 2 possible constant values
  46.                 auto *Const1 = llvm::ConstantInt::get(Op1Ty, Op1KnownBits.getMinValue());
  47.                 auto *Const2 = llvm::ConstantInt::get(Op1Ty, Op1KnownBits.getMaxValue());
  48.                 // Generate the 2 possible indexes
  49.                 auto *Index1 = llvm::BinaryOperator::Create(
  50.                     llvm::Instruction::BinaryOps::Add, Op2, Const1, "", Load);
  51.                 auto *Index2 = llvm::BinaryOperator::Create(
  52.                     llvm::Instruction::BinaryOps::Add, Op2, Const2, "", Load);
  53.                 // Generate the 2 possible 'getelementptr' instructions
  54.                 llvm::ArrayRef<llvm::Value *> Indexes1{Index1};
  55.                 auto *GEP1 = llvm::GetElementPtrInst::CreateInBounds(
  56.                     GEP->getPointerOperand(), Indexes1, "", Load);
  57.                 llvm::ArrayRef<llvm::Value *> Indexes2{Index2};
  58.                 auto *GEP2 = llvm::GetElementPtrInst::CreateInBounds(
  59.                     GEP->getPointerOperand(), Indexes2, "", Load);
  60.                 // Generate the 2 possible 'bitcast' instructions
  61.                 auto *BC1 = new llvm::BitCastInst(GEP1, BitCast->getType(), "", Load);
  62.                 auto *BC2 = new llvm::BitCastInst(GEP2, BitCast->getType(), "", Load);
  63.                 // Generate the 2 possible 'load' instructions
  64.                 auto *L1 = new llvm::LoadInst(BC1, "", Load);
  65.                 auto *L2 = new llvm::LoadInst(BC2, "", Load);
  66.                 // Generate a new 'icmp' instruction
  67.                 auto *ICmp =
  68.                     llvm::CmpInst::Create(llvm::Instruction::ICmp, llvm::ICmpInst::ICMP_EQ,
  69.                                           Op1, Const1, "", Load);
  70.                 // Generate a new 'select' instruction
  71.                 auto *Select = llvm::SelectInst::Create(ICmp, L1, L2, "", Load);
  72.                 // Replace the original 'getelementptr'
  73.                 Load->replaceAllUsesWith(Select);
  74.               }
  75.             }
  76.           }
  77.         }
  78.       }
  79.     }
  80.   }
  81. }
  82.  
  83. // Optimize again to guarantee the propagation
  84. lifter.OptimizeFunction(finalFn, g);
Add Comment
Please, Sign In to add comment