Ejemplo n.º 1
0
/// \brief Find the operand of the GEP that should be checked for consecutive
/// stores. This ignores trailing indices that have no effect on the final
/// pointer.
unsigned llvm::getGEPInductionOperand(const GetElementPtrInst *Gep) {
  const DataLayout &DL = Gep->getModule()->getDataLayout();
  unsigned LastOperand = Gep->getNumOperands() - 1;
  unsigned GEPAllocSize = DL.getTypeAllocSize(
      cast<PointerType>(Gep->getType()->getScalarType())->getElementType());

  // Walk backwards and try to peel off zeros.
  while (LastOperand > 1 &&
         match(Gep->getOperand(LastOperand), llvm::PatternMatch::m_Zero())) {
    // Find the type we're currently indexing into.
    gep_type_iterator GEPTI = gep_type_begin(Gep);
    std::advance(GEPTI, LastOperand - 1);

    // If it's a type with the same allocation size as the result of the GEP we
    // can peel off the zero index.
    if (DL.getTypeAllocSize(*GEPTI) != GEPAllocSize)
      break;
    --LastOperand;
  }

  return LastOperand;
}
Ejemplo n.º 2
0
  ref<ConstantExpr> Executor::evalConstantExpr(const llvm::ConstantExpr *ce) {
    LLVM_TYPE_Q llvm::Type *type = ce->getType();

    ref<ConstantExpr> op1(0), op2(0), op3(0);
    int numOperands = ce->getNumOperands();

    if (numOperands > 0) op1 = evalConstant(ce->getOperand(0));
    if (numOperands > 1) op2 = evalConstant(ce->getOperand(1));
    if (numOperands > 2) op3 = evalConstant(ce->getOperand(2));

    switch (ce->getOpcode()) {
    default :
      ce->dump();
      std::cerr << "error: unknown ConstantExpr type\n"
                << "opcode: " << ce->getOpcode() << "\n";
      abort();

    case Instruction::Trunc: 
      return op1->Extract(0, getWidthForLLVMType(type));
    case Instruction::ZExt:  return op1->ZExt(getWidthForLLVMType(type));
    case Instruction::SExt:  return op1->SExt(getWidthForLLVMType(type));
    case Instruction::Add:   return op1->Add(op2);
    case Instruction::Sub:   return op1->Sub(op2);
    case Instruction::Mul:   return op1->Mul(op2);
    case Instruction::SDiv:  return op1->SDiv(op2);
    case Instruction::UDiv:  return op1->UDiv(op2);
    case Instruction::SRem:  return op1->SRem(op2);
    case Instruction::URem:  return op1->URem(op2);
    case Instruction::And:   return op1->And(op2);
    case Instruction::Or:    return op1->Or(op2);
    case Instruction::Xor:   return op1->Xor(op2);
    case Instruction::Shl:   return op1->Shl(op2);
    case Instruction::LShr:  return op1->LShr(op2);
    case Instruction::AShr:  return op1->AShr(op2);
    case Instruction::BitCast:  return op1;

    case Instruction::IntToPtr:
      return op1->ZExt(getWidthForLLVMType(type));

    case Instruction::PtrToInt:
      return op1->ZExt(getWidthForLLVMType(type));

    case Instruction::GetElementPtr: {
      ref<ConstantExpr> base = op1->ZExt(Context::get().getPointerWidth());

      for (gep_type_iterator ii = gep_type_begin(ce), ie = gep_type_end(ce);
           ii != ie; ++ii) {
        ref<ConstantExpr> addend = 
          ConstantExpr::alloc(0, Context::get().getPointerWidth());

        if (LLVM_TYPE_Q StructType *st = dyn_cast<StructType>(*ii)) {
          const StructLayout *sl = kmodule->targetData->getStructLayout(st);
          const ConstantInt *ci = cast<ConstantInt>(ii.getOperand());

          addend = ConstantExpr::alloc(sl->getElementOffset((unsigned)
                                                            ci->getZExtValue()),
                                       Context::get().getPointerWidth());
        } else {
          const SequentialType *set = cast<SequentialType>(*ii);
          ref<ConstantExpr> index = 
            evalConstant(cast<Constant>(ii.getOperand()));
          unsigned elementSize = 
            kmodule->targetData->getTypeStoreSize(set->getElementType());

          index = index->ZExt(Context::get().getPointerWidth());
          addend = index->Mul(ConstantExpr::alloc(elementSize, 
                                                  Context::get().getPointerWidth()));
        }

        base = base->Add(addend);
      }

      return base;
    }
      
    case Instruction::ICmp: {
      switch(ce->getPredicate()) {
      default: assert(0 && "unhandled ICmp predicate");
      case ICmpInst::ICMP_EQ:  return op1->Eq(op2);
      case ICmpInst::ICMP_NE:  return op1->Ne(op2);
      case ICmpInst::ICMP_UGT: return op1->Ugt(op2);
      case ICmpInst::ICMP_UGE: return op1->Uge(op2);
      case ICmpInst::ICMP_ULT: return op1->Ult(op2);
      case ICmpInst::ICMP_ULE: return op1->Ule(op2);
      case ICmpInst::ICMP_SGT: return op1->Sgt(op2);
      case ICmpInst::ICMP_SGE: return op1->Sge(op2);
      case ICmpInst::ICMP_SLT: return op1->Slt(op2);
      case ICmpInst::ICMP_SLE: return op1->Sle(op2);
      }
    }

    case Instruction::Select:
      return op1->isTrue() ? op2 : op3;

    case Instruction::FAdd:
    case Instruction::FSub:
    case Instruction::FMul:
    case Instruction::FDiv:
    case Instruction::FRem:
    case Instruction::FPTrunc:
    case Instruction::FPExt:
    case Instruction::UIToFP:
    case Instruction::SIToFP:
    case Instruction::FPToUI:
    case Instruction::FPToSI:
    case Instruction::FCmp:
      assert(0 && "floating point ConstantExprs unsupported");
    }
  }
Ejemplo n.º 3
0
/**
 * Print the given instruction.
 * 
 * @param inst  the instruction
 */
void JVMWriter::printInstruction(const Instruction *inst) {
    const Value *left, *right;
    if(inst->getNumOperands() >= 1) left  = inst->getOperand(0);
    if(inst->getNumOperands() >= 2) right = inst->getOperand(1);
    switch(inst->getOpcode()) {
    case Instruction::Ret:
        printStartInvocationTag();
        printEndInvocationTag("lljvm/runtime/Memory/destroyStackFrame()V");
        if(inst->getNumOperands() >= 1) {
            printValueLoad(left);
            printSimpleInstruction(
                getTypePrefix(left->getType(), true) + "return");
        } else {
            printSimpleInstruction("return");
        }
        break;
    case Instruction::Unwind:
        printSimpleInstruction("getstatic",
            "lljvm/runtime/Instruction$Unwind/instance "
            "Llljvm/runtime/Instruction$Unwind;");
        printSimpleInstruction("athrow");
        // TODO: need to destroy stack frames
        break;
    case Instruction::Unreachable:
        printSimpleInstruction("getstatic",
            "lljvm/runtime/Instruction$Unreachable/instance "
            "Llljvm/runtime/Instruction$Unreachable;");
        printSimpleInstruction("athrow");
        break;
    case Instruction::Add:
    case Instruction::FAdd:
    case Instruction::Sub:
    case Instruction::FSub:
    case Instruction::Mul:
    case Instruction::FMul:
    case Instruction::UDiv:
    case Instruction::SDiv:
    case Instruction::FDiv:
    case Instruction::URem:
    case Instruction::SRem:
    case Instruction::FRem:
    case Instruction::And:
    case Instruction::Or:
    case Instruction::Xor:
    case Instruction::Shl:
    case Instruction::LShr:
    case Instruction::AShr:
        printArithmeticInstruction(inst->getOpcode(), left, right);
        break;
    case Instruction::SExt:
    case Instruction::Trunc:
    case Instruction::ZExt:
    case Instruction::FPTrunc:
    case Instruction::FPExt:
    case Instruction::UIToFP:
    case Instruction::SIToFP:
    case Instruction::FPToUI:
    case Instruction::FPToSI:
    case Instruction::PtrToInt:
    case Instruction::IntToPtr:
    case Instruction::BitCast:
        printCastInstruction(inst->getOpcode(), left,
                             cast<CastInst>(inst)->getDestTy(),
                             cast<CastInst>(inst)->getSrcTy()); break;
    case Instruction::ICmp:
    case Instruction::FCmp:
        printCmpInstruction(cast<CmpInst>(inst)->getPredicate(),
                            left, right); break;
    case Instruction::Br:
        printBranchInstruction(cast<BranchInst>(inst)); break;
    case Instruction::Select:
        printSelectInstruction(inst->getOperand(0),
                               inst->getOperand(1),
                               inst->getOperand(2)); break;
    case Instruction::Load:
        printIndirectLoad(inst->getOperand(0)); break;
    case Instruction::Store:
        printIndirectStore(inst->getOperand(1), inst->getOperand(0)); break;
    case Instruction::GetElementPtr:
        printGepInstruction(inst->getOperand(0),
                            gep_type_begin(inst),
                            gep_type_end(inst)); break;
    case Instruction::Call:
        printCallInstruction(cast<CallInst>(inst)); break;
    case Instruction::Invoke:
        printInvokeInstruction(cast<InvokeInst>(inst)); break;
    case Instruction::Switch:
        printSwitchInstruction(cast<SwitchInst>(inst)); break;
    case Instruction::Alloca:
        printAllocaInstruction(cast<AllocaInst>(inst)); break;
    case Instruction::VAArg:
        printVAArgInstruction(cast<VAArgInst>(inst)); break;
    default:
        errs() << "Instruction = " << *inst << '\n';
        llvm_unreachable("Unsupported instruction");
    }
}
Ejemplo n.º 4
0
DyckVertex* AAAnalyzer::handle_gep(GEPOperator* gep) {
    Value * ptr = gep->getPointerOperand();
    DyckVertex* current = wrapValue(ptr);

    gep_type_iterator preGTI = gep_type_begin(gep); // preGTI is the PointerTy of ptr
    gep_type_iterator GTI = gep_type_begin(gep); // GTI is the PointerTy of ptr
    if (GTI != gep_type_end(gep))
        GTI++; // ptr's element type, e.g. struct

    int num_indices = gep->getNumIndices();
    int idxidx = 0;
    while (idxidx < num_indices) {
        Value * idx = gep->getOperand(++idxidx);
        if (/*!isa<ConstantInt>(idx) ||*/ !GTI->isSized()) {
            // current->addProperty("unknown-offset", (void*) 1);
            break;
        }

        if ((*preGTI)->isStructTy()) {
            // example: gep y 0 constIdx
            // s1: y--deref-->?1--(-2-constIdx)-->?2
            DyckVertex* theStruct = this->addPtrTo(current, NULL);

            ConstantInt * ci = cast<ConstantInt>(idx);
            if (ci == NULL) {
                errs() << ("ERROR: when dealing with gep: \n");
                errs() << *gep << "\n";
                exit(1);
            }
            // field index need not be the same as original value
            // make it be a negative integer
            long fieldIdx = (long) (*(ci->getValue().getRawData()));
            DyckVertex* field = this->addField(theStruct, -2 - fieldIdx, NULL);

            // s2: ?3--deref-->?2
            DyckVertex* fieldPtr = this->addPtrTo(NULL, field);

            /// the label representation and feature impl is temporal. @FIXME
            // s3: y--2-->?3
            current->getRepresentative()->addTarget(fieldPtr->getRepresentative(), (void*) (fieldIdx));

            // update current
            current = fieldPtr;
        } else if ((*preGTI)->isPointerTy() || (*preGTI)->isArrayTy()) {
#ifndef ARRAY_SIMPLIFIED
            current = addPtrOffset(current, getConstantIntRawData(cast<ConstantInt>(idx)) * dl.getTypeAllocSize(*GTI), dgraph);
#endif
        } else {
            errs() << "ERROR in handle_gep: unknown type:\n";
            errs() << "Type Id: " << (*preGTI)->getTypeID() << "\n";
            exit(1);
        }

        if (GTI != gep_type_end(gep))
            GTI++;
        if (preGTI != gep_type_end(gep))
            preGTI++;
    }

    return current;
}