SizeOffsetType ObjectSizeOffsetVisitor::visitGEPOperator(GEPOperator &GEP) {
  SizeOffsetType PtrData = compute(GEP.getPointerOperand());
  APInt Offset(IntTyBits, 0);
  if (!bothKnown(PtrData) || !GEP.accumulateConstantOffset(*TD, Offset))
    return unknown();

  return std::make_pair(PtrData.first, PtrData.second + Offset);
}
SizeOffsetType ObjectSizeOffsetVisitor::visitGEPOperator(GEPOperator &GEP) {
  SizeOffsetType PtrData = compute(GEP.getPointerOperand());
  if (!bothKnown(PtrData) || !GEP.hasAllConstantIndices())
    return unknown();

  SmallVector<Value*, 8> Ops(GEP.idx_begin(), GEP.idx_end());
  APInt Offset(IntTyBits,TD->getIndexedOffset(GEP.getPointerOperandType(),Ops));
  return std::make_pair(PtrData.first, PtrData.second + Offset);
}
Exemple #3
0
/// \brief Accumulate a constant GEP offset into an APInt if possible.
///
/// Returns false if unable to compute the offset for any reason. Respects any
/// simplified values known during the analysis of this callsite.
bool CallAnalyzer::accumulateGEPOffset(GEPOperator &GEP, APInt &Offset) {
  if (!TD)
    return false;

  unsigned AS = GEP.getPointerAddressSpace();
  unsigned IntPtrWidth = TD->getPointerSizeInBits(AS);
  assert(IntPtrWidth == Offset.getBitWidth());

  for (gep_type_iterator GTI = gep_type_begin(GEP), GTE = gep_type_end(GEP);
       GTI != GTE; ++GTI) {
    ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
    if (!OpC)
      if (Constant *SimpleOp = SimplifiedValues.lookup(GTI.getOperand()))
        OpC = dyn_cast<ConstantInt>(SimpleOp);
    if (!OpC)
      return false;
    if (OpC->isZero()) continue;

    // Handle a struct index, which adds its field offset to the pointer.
    if (StructType *STy = dyn_cast<StructType>(*GTI)) {
      unsigned ElementIdx = OpC->getZExtValue();
      const StructLayout *SL = TD->getStructLayout(STy);
      Offset += APInt(IntPtrWidth, SL->getElementOffset(ElementIdx));
      continue;
    }

    APInt TypeSize(IntPtrWidth, TD->getTypeAllocSize(GTI.getIndexedType()));
    Offset += OpC->getValue().sextOrTrunc(IntPtrWidth) * TypeSize;
  }
  return true;
}
SizeOffsetEvalType
ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
  SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand());
  if (!bothKnown(PtrData))
    return unknown();

  Value *Offset = EmitGEPOffset(&Builder, *TD, &GEP, /*NoAssumptions=*/true);
  Offset = Builder.CreateAdd(PtrData.second, Offset);
  return std::make_pair(PtrData.first, Offset);
}
Exemple #5
0
string esp::parseName(Value *value){
  // has existed
  if(names.find(value) != names.end())
    return names[value];

  string name = "";
  Value *current = value;

  /*
  bool continueFlag = true;
  do{
    if(isa<Instruction > (current)){
      Instruction* inst = dyn_cast<Instruction>(current);
      unsigned op = inst->getOpcode();
      switch(op){
      case Instruction::Ret :{
        break;
      }

      case Instruction::Br :{
        break;
      }

      case Instruction::Switch :{
        break;
      }

      case Instruction::Call :{
        CallInst *callinst = (CallInst*) current;

        if (((CallInst*) current)->getCalledFunction() != NULL) {
            name += string("@")+((CallInst*) current)->getCalledFunction()->getNameStr() + "(";
        } else {
            name += string("@[funcPTR](");
            name += ((CallInst*) current)->getCalledValue()->getNameStr();
        }

        for (unsigned i = 1; i < callinst->getNumOperands(); i++) {
            name += esp::parseName(callinst->getOperand(i));
        }

        name += string(")");
        continueFlag = false;
        break;
      }

      case Instruction::PHI :{
        name += string("PHI[");
        name += current->getNameStr();
        PHINode *phi = (PHINode*) current;
        for (unsigned i = 0; i < phi->getNumIncomingValues(); i++) {
            Value *incoming = phi->getIncomingValue(i);
            if (i != 0) name += ",";
            if (!hasLoop(incoming)) {
                if (!incoming->hasName()) {
                    name += esp::parseName(incoming);
                } else {
                    name += incoming->getNameStr();
                }

            }
        }

        name += std::string("]");
        continueFlag = false;
        break;
      }

      case Instruction::Select :{
        break;
      }

      case Instruction::Add :{
        name += "+";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::Sub :{
        name += "-";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::Mul :{
        name += "*";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::UDiv :{
        name += "/";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::SDiv :{
        name += "//";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::And :{
        name += "&";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::Or :{
        name += "|";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::Xor :{
        name += "^";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::Shl :{
        name += "<<";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::LShr :{
        name += ">>";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::AShr :{
        name += ">>>";
        name += parseBinaryOpName(inst);
        break;
      }

      case Instruction::ICmp :{
        ICmpInst * icmp = dyn_cast<ICmpInst>(current);
        if (isa<Constant>(icmp->getOperand(0))) {
          name += esp::parseName(icmp->getOperand(1));
          continueFlag = false;
        } else {
          name += esp::parseName(icmp->getOperand(0));
          continueFlag = false;
        }
        break;
      }

      case Instruction::Alloca :{
        name += current->getNameStr();
        break;
      }

      case Instruction::Load :{
        if (((LoadInst*) inst)->isVolatile())
          name += std::string("@VolatileLoad");
        name += "*";
        name += esp::parseName(inst->getOperand(0));
        continueFlag = false;
        break;
      }

      case Instruction::Store :{
        // need to handle
        continueFlag = false;
        break;
      }

      case Instruction::GetElementPtr :{
        GetElementPtrInst * gep = dyn_cast<GetElementPtrInst>(current);
        unsigned ops = gep->getNumOperands();
        name += "[";
        for (unsigned i = 1; i < ops; i++) {
          Value *v = gep->getOperand(i);
          if (ConstantInt * ci = dyn_cast<ConstantInt>(v)) {
            if (i == 1 && ci->equalsInt(0))
              continue;
            name += ".";
            name += ci->getValue().toString(10, false);
          } else {
            name += ".";
            name += esp::parseName(v);
          }
        }
        name += "]";
        name += esp::parseName(gep->getOperand(0));
        continueFlag = false;
        break;
      }

      case Instruction::BitCast:{
        name += esp::parseName(inst->getOperand(0));
        continueFlag = false;
        break;
      }

      default :{
        // Illegal or unsupported instruction
        name += current->getNameStr();
        break;
      }
      }

    }else if(isa<Argument>(current)){
      if (arguments.find(current) != arguments.end())
        name += std::string("$") + current->getNameStr();

    }else if(isa<GlobalValue>(current)){
      name += std::string("@") + current->getNameStr();

    }else if(isa<ConstantInt>(current)){
      ConstantInt * cint = dyn_cast<ConstantInt > (current);
      name += cint->getValue().toString(10, true);

    }else if (isa<Constant > (current)) {
      Constant *c = dyn_cast<Constant > (current);
      if (c->isNullValue()) {
          name += "null";
      }
  }else{
      // Illegal format
  }
  if(!continueFlag)
    break;
  current = parents[current];
  }while(current);
  */

  //Refactor

   do {
     if (isa<LoadInst > (current)) {
       name += "*";
       if (parents[current] == NULL)
         name += (((LoadInst*) current)->getOperand(0))->getNameStr();
       if (((LoadInst*) current)->isVolatile())
         name += std::string("@VolatileLoad");

     } else if (dyn_cast<GetElementPtrInst > (current)) {
       GetElementPtrInst * gep = dyn_cast<GetElementPtrInst > (current);
       unsigned ops = gep->getNumOperands();
       name += "[";
       for (unsigned i = 1; i < ops; i++) {
         Value *v = gep->getOperand(i);
         if (dyn_cast<ConstantInt > (current)) {
           ConstantInt * ci = dyn_cast<ConstantInt > (current);
           if (i == 1 && ci->equalsInt(0)) continue;
           name += ".";
           name += ci->getValue().toString(10, false);
         } else {
           name += ".";
           name += parseName(v);
         }

       }
       name += "]";
       name += parseName(gep->getOperand(0));
       break;

     } else if (isa<AllocaInst > (current)) {
       name += current->getNameStr();
     } else if (isa<Argument > (current)) {
       if (arguments.find(current) != arguments.end())
         name += std::string("$") + current->getNameStr();
     } else if (isa<GlobalValue > (current)) {
       name += std::string("@") + current->getNameStr();
     } else if (isa<CallInst > (current)) {
       CallInst *callinst = (CallInst*) current;

       if (((CallInst*) current)->getCalledFunction() != NULL) {
         name += std::string("@")+((CallInst*) current)->getCalledFunction()->getNameStr() + "(";
       } else {
         name += std::string("@[funcPTR](");
         name += ((CallInst*) current)->getCalledValue()->getNameStr();
       }

       for (unsigned i = 1; i < callinst->getNumOperands(); i++) {
         name += parseName(callinst->getOperand(i));
       }

       name += std::string(")");
       break;
     } else if (isa<CastInst > (current)) {
     } else if (isa<PHINode > (current)) {
       /*
       name += std::string("PHI[");
       s += parent->getNameStr();
       PHINode *phi = (PHINode*) parent;
       for (unsigned i = 0; i < phi->getNumIncomingValues(); i++) {
         //s+=phi->getIncomingBlock(i)->getNameStr();
         Value *incoming = phi->getIncomingValue(i);
         if (i != 0) s += ",";
         if (!hasLoop(incoming)) {
           DEBUG(errs() << "incoming#" << i << " no loop(i rather doubt it)\n");
           if (!incoming->hasName()) {
             s += parseName(incoming);
           } else {
             s += incoming->getNameStr();
           }

         }
       }

       // PHI nodes...ugh
       s += std::string("]");
       break;
       */

     } else if (isa<BinaryOperator > (current)) {
       BinaryOperator *bo = dyn_cast<BinaryOperator > (current);
       Instruction::BinaryOps opcode = bo->getOpcode();
       if (opcode == Instruction::Add) {
         name.append("+");
       } else if (opcode == Instruction::Sub) {
         name.append("-");
       } else if (opcode == Instruction::Or) {
         name.append("||");
       } else if (opcode == Instruction::Mul) {
         name.append("*");
       } else if (opcode == Instruction::Xor) {
         name.append("^");
       } else if (opcode == Instruction::And) {
         name.append("&&");
       } else if (opcode == Instruction::Shl) {
         name.append("<<");
       } else if (opcode == Instruction::AShr) {
         name.append(">>");
       } else if (opcode == Instruction::LShr) {
         name.append(">>>");
       }
       Value *v0 = bo->getOperand(0);
       Value *v1 = bo->getOperand(1);
       if (isa<ConstantInt > (v0)) {
         name += ((ConstantInt*) v0)->getValue().toString(10, false);
       } else if (isa<ConstantInt > (v1)) {
         name += ((ConstantInt*) v1)->getValue().toString(10, false);
       } else {
         printDebugMsg("Binary Operation between non-constants\n");
       }
     } else if (dyn_cast<GEPOperator > (current)) {
       GEPOperator * gep = dyn_cast<GEPOperator > (current);
       unsigned ops = gep->getNumOperands();
       name += "[";
       for (unsigned i = 1; i < ops; i++) {
         Value *v = gep->getOperand(i);
         if (dyn_cast<ConstantInt > (v)) {
           ConstantInt * ci = dyn_cast<ConstantInt > (v);
           if (i == 1 && ci->equalsInt(0)) continue;
           name += ".";
           name += ci->getValue().toString(10, false);
         }

       }
       name += "]";

       name += parseName(gep->getOperand(0));
       break;

     } else if (dyn_cast<ICmpInst > (current)) {
       ICmpInst * icmp = dyn_cast<ICmpInst > (current);
       if (isa<Constant > (icmp->getOperand(0))) {
         name += parseName(icmp->getOperand(1));
         break;
       } else {
         name += parseName(icmp->getOperand(0));
         break;
       }
     } else if (dyn_cast<ConstantInt > (current)) {
       ConstantInt * cint = dyn_cast<ConstantInt > (current);
       name += cint->getValue().toString(10, true);
     } else {
       name += current->getNameStr(); // might not work
     }

   } while ((current = parents[current]));

  names[value] = name;

  return name;
}
Exemple #6
0
//
// Method: runOnModule()
//
// Description:
//  Entry point for this LLVM pass.
//  Clone functions that take GEPs as arguments
//
// Inputs:
//  M - A reference to the LLVM module to transform
//
// Outputs:
//  M - The transformed LLVM module.
//
// Return value:
//  true  - The module was modified.
//  false - The module was not modified.
//
bool GEPExprArgs::runOnModule(Module& M) {
  bool changed;
  do {
    changed = false;
    for (Module::iterator F = M.begin(); F != M.end(); ++F){
      for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
        for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
          CallInst *CI = dyn_cast<CallInst>(I++);
          if(!CI)
            continue;

          if(CI->hasByValArgument())
            continue;
          // if the GEP calls a function, that is externally defined,
          // or might be changed, ignore this call site.
          Function *F = CI->getCalledFunction();

          if (!F || (F->isDeclaration() || F->mayBeOverridden())) 
            continue;
          if(F->hasStructRetAttr())
            continue;
          if(F->isVarArg())
            continue;

          // find the argument we must replace
          Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
          unsigned argNum = 1;
          for(; argNum < CI->getNumOperands();argNum++, ++ai) {
            if(ai->use_empty())
              continue;
            if (isa<GEPOperator>(CI->getOperand(argNum)))
              break;
          }

          // if no argument was a GEP operator to be changed 
          if(ai == ae)
            continue;

          GEPOperator *GEP = dyn_cast<GEPOperator>(CI->getOperand(argNum));
          if(!GEP->hasAllConstantIndices())
            continue;

          // Construct the new Type
          // Appends the struct Type at the beginning
          std::vector<Type*>TP;
          TP.push_back(GEP->getPointerOperand()->getType());
          for(unsigned c = 1; c < CI->getNumOperands();c++) {
            TP.push_back(CI->getOperand(c)->getType());
          }

          //return type is same as that of original instruction
          FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
          Function *NewF;
          numSimplified++;
          if(numSimplified > 800) 
            return true;

          NewF = Function::Create(NewFTy,
                                  GlobalValue::InternalLinkage,
                                  F->getName().str() + ".TEST",
                                  &M);

          Function::arg_iterator NI = NewF->arg_begin();
          NI->setName("GEParg");
          ++NI;

          ValueToValueMapTy ValueMap;

          for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
            ValueMap[II] = NI;
            NI->setName(II->getName());
            NI->addAttr(F->getAttributes().getParamAttributes(II->getArgNo() + 1));
          }
          NewF->setAttributes(NewF->getAttributes().addAttr(
              0, F->getAttributes().getRetAttributes()));
          // Perform the cloning.
          SmallVector<ReturnInst*,100> Returns;
          CloneFunctionInto(NewF, F, ValueMap, false, Returns);
          std::vector<Value*> fargs;
          for(Function::arg_iterator ai = NewF->arg_begin(), 
              ae= NewF->arg_end(); ai != ae; ++ai) {
            fargs.push_back(ai);
          }

          NewF->setAttributes(NewF->getAttributes().addAttr(
              ~0, F->getAttributes().getFnAttributes()));
          //Get the point to insert the GEP instr.
          SmallVector<Value*, 8> Ops(CI->op_begin()+1, CI->op_end());
          Instruction *InsertPoint;
          for (BasicBlock::iterator insrt = NewF->front().begin(); 
               isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}

          NI = NewF->arg_begin();
          SmallVector<Value*, 8> Indices;
          Indices.append(GEP->op_begin()+1, GEP->op_end());
          GetElementPtrInst *GEP_new = GetElementPtrInst::Create(cast<Value>(NI),
                                                                 Indices, 
                                                                 "", InsertPoint);
          fargs.at(argNum)->replaceAllUsesWith(GEP_new);
          unsigned j = argNum + 1;
          for(; j < CI->getNumOperands();j++) {
            if(CI->getOperand(j) == GEP)
              fargs.at(j)->replaceAllUsesWith(GEP_new);
          }

          SmallVector<AttributeWithIndex, 8> AttributesVec;

          // Get the initial attributes of the call
          AttrListPtr CallPAL = CI->getAttributes();
          Attributes RAttrs = CallPAL.getRetAttributes();
          Attributes FnAttrs = CallPAL.getFnAttributes();
          if (RAttrs)
            AttributesVec.push_back(AttributeWithIndex::get(0, RAttrs));

          SmallVector<Value*, 8> Args;
          Args.push_back(GEP->getPointerOperand());
          for(unsigned j =1;j<CI->getNumOperands();j++) {
            Args.push_back(CI->getOperand(j));
            // position in the AttributesVec
            if (Attributes Attrs = CallPAL.getParamAttributes(j))
              AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
          }
          // Create the new attributes vec.
          if (FnAttrs != Attribute::None)
            AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));

          AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec.begin(),
                                                    AttributesVec.end());

          CallInst *CallI = CallInst::Create(NewF,Args,"", CI);
          CallI->setCallingConv(CI->getCallingConv());
          CallI->setAttributes(NewCallPAL);
          CI->replaceAllUsesWith(CallI);
          CI->eraseFromParent();
          changed = true;
        }
      }
    }
  } while(changed);
  return true;
}