예제 #1
0
/*
	the instruction's result is considered an output if it's
		- a memory write
		- used outside its basic block
		- used in the block's terminator instruction (e.g. a return statement)
*/
bool Primitives::isOutputForBasicBlock(const Instruction *inst)
{
	// memory write?
	if (isa<StoreInst>(inst))
		return true;
	// used outside of its basic block?
	const BasicBlock *bb = inst->getParent();
	if (isUsedOutsideOfBlock(inst, bb))
		return true;
	// check terminator instruction
	const TerminatorInst *ti = bb->getTerminator();
	if (ti != NULL)
	{
		if (isa<InvokeInst>(ti) || isa<ReturnInst>(ti) || isa<SwitchInst>(ti) ||
			isa<BranchInst>(ti))
		{
			for (User::const_op_iterator oi = ti->op_begin(), oe = ti->op_end(); oi != oe; ++oi)
			{
				const Value* v = oi->get();
				if (isa<Instruction>(v) && v == inst)
					return true;
			}
		}
	}
	return false;
}
예제 #2
0
파일: MemModel.cpp 프로젝트: melbcat/SVF
/*!
 * Find the max possible offset for an object pointed to by (V).
 */
std::vector<LocationSet> SymbolTableInfo::getFlattenedFields(const Value *V) {
    assert(V);
    std::vector<LocationSet> fields;
    fields.push_back(LocationSet(0));

    const Type *T = V->getType();
    // Use the biggest struct type out of all operands.
    if (const User *U = dyn_cast<User>(V)) {
        Size_t msz = 1;		//the max size seen so far
        for (User::const_op_iterator it = U->op_begin(), ie = U->op_end();
                it != ie; ++it) {
            T = it->get()->getType();

            Size_t sz = getFields(fields, T, msz);
            if (msz < sz)
                msz = sz;
        }
    }
    //If V is a CE or bitcast, the actual pointer type is its operand.
    else if (isa<ConstantExpr>(V) || isa<BitCastInst>(V)) {

        if (const ConstantExpr *E = dyn_cast<ConstantExpr>(V))
            T = E->getOperand(0)->getType();
        else if (const BitCastInst *BI = dyn_cast<BitCastInst>(V))
            T = BI->getOperand(0)->getType();

        getFields(fields, T, 0);
    }

    return fields;
}
예제 #3
0
unsigned int ArchitectureVirtual::getSwInstructionTiming(const llvm::Instruction* inst) const
{
	if (isa<BinaryOperator>(inst))
	{
		const BinaryOperator *binop = cast<BinaryOperator>(inst);
		bool floatingPoint = false;
		for (User::const_op_iterator oi = inst->op_begin(), oe = inst->op_end();
			oi != oe; ++oi)
		{
			if (oi->get()->getType()->isFloatingPoint())
			{
				floatingPoint = true;
				break;
			}
		}
		int opcode = binop->getOpcode();
		if (!floatingPoint)
		{
			if (opcode == Instruction::UDiv || opcode == Instruction::URem ||
				opcode == Instruction::SDiv || opcode == Instruction::SRem)
				return 15;
			else if (opcode == Instruction::Mul)
				return 5;
			else
				return 1;
		}
		else
		{
			switch (opcode)
			{
			case Instruction::Add:
			case Instruction::Sub:
			case Instruction::FCmp:
				return 50;
			case Instruction::Mul:
				return 100;
			case Instruction::FPToUI:
			case Instruction::FPToSI:
			case Instruction::SIToFP:
			case Instruction::UIToFP:
			case Instruction::FPExt:
			case Instruction::FPTrunc:
				return 40;
			case Instruction::FDiv:
			case Instruction::FRem:
				return 1500;
			}
		}
	}
	else if (isa<StoreInst>(inst) || isa<LoadInst>(inst))
		return 2;
	else if (isa<TerminatorInst>(inst))
		return 3;
	else if (isa<BitCastInst>(inst) || isa<PtrToIntInst>(inst) || 
		isa<IntToPtrInst>(inst))
		return 0;
	return 1;
}
bool
SomeOperandIsSPPointer(std::set<const Value*> &SpPointers, const Instruction *I) {
  for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end(); OI != OE; ++OI) {
    if (SpPointers.find(OI->get()) != SpPointers.end()) {
      return true;
    }
  }
  return false;
}
예제 #5
0
bool TempScopInfo::isReduction(BasicBlock &BB) {
  int loadAccess = 0, storeAccess = 0;
  const StoreInst *storeInst;
  const Value *storePointer;
  const LoadInst *loadInst[2];
  const Value *loadPointer[2];

  for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) {
    Instruction &Inst = *I;
    if (isa<LoadInst>(&Inst)) {
      if (loadAccess >= 2)
        return false;
      loadInst[loadAccess] = dyn_cast<LoadInst>(&Inst);
      loadPointer[loadAccess] = loadInst[loadAccess]->getPointerOperand();
      loadAccess++;
    } else if (isa<StoreInst>(&Inst)) {
      if (storeAccess >= 1)
        return false;
      storeInst = dyn_cast<StoreInst>(&Inst);
      storePointer = storeInst->getPointerOperand();
      storeAccess++;
    }
  }

  if (loadAccess < 2)
    return false;

  if (loadPointer[0] == loadPointer[1])
   return false;

  const Value *reductionLoadInst;
  if (storePointer == loadPointer[0])
    reductionLoadInst = loadInst[0];
  else if (storePointer == loadPointer[1])
    reductionLoadInst = loadInst[1];
  else
    return false;

  const Instruction *reductionInst =
    dyn_cast<Instruction>(storeInst->getValueOperand());

  // Check if the value stored is an instruction
  if (!reductionInst)
    return false;

  // Reduction operations must be associative and commutative
  if (!reductionInst->isAssociative() || !reductionInst->isCommutative())
    return false;

  // Check if this instruction is using the loaded value
  for (User::const_op_iterator I = reductionInst->op_begin(),
       E = reductionInst->op_end(); I != E; I++) {
    const Value *operand = I->get();
    if (operand == reductionLoadInst) {
      // The loaded value's one and only use must be this one.
      return operand->hasOneUse();
    }
  }

  return false;
}
예제 #6
0
/*
	1 HW unit = 0.1 SW units
*/
unsigned int ArchitectureVirtual::getHwInstructionTiming(const llvm::Instruction* inst) const
{
	// casts are 'free'
	if (isa<BitCastInst>(inst) || isa<TruncInst>(inst) ||
		isa<ZExtInst>(inst) || isa<SExtInst>(inst) ||
		isa<PtrToIntInst>(inst) || isa<IntToPtrInst>(inst))
		return 0;
	if (isa<BinaryOperator>(inst))
	{
		const BinaryOperator *binop = cast<BinaryOperator>(inst);
		int opcode = binop->getOpcode();
		bool constantOperand = false, floatingPoint = false;
		for (User::const_op_iterator oi = inst->op_begin(), oe = inst->op_end();
			oi != oe; ++oi)
		{
			if (isa<Constant>(oi->get()))
				constantOperand = true;
			if (oi->get()->getType()->isFloatingPoint())
				floatingPoint = true;
		}
		switch (opcode)
		{
		// arithmetic operations
		case Instruction::Add:
		case Instruction::Sub:
			return floatingPoint ? 100 : (constantOperand ?  6 : 8);
		case Instruction::UDiv:
		case Instruction::SDiv:
			return constantOperand ? 45 : 75;
		case Instruction::URem:
		case Instruction::SRem:
			return constantOperand ? 100: 125;
		case Instruction::Mul:
			return floatingPoint ? 175 : (constantOperand  ? 35 : 45);
		// logical operations
		case Instruction::Xor:
		case Instruction::And:
		case Instruction::Or:
			return constantOperand ? 6 : 8;
		// shift instructions
		case Instruction::Shl:
		case Instruction::LShr:
		case Instruction::AShr:
			return constantOperand ? 7 : 9;
		// floating point operations
		case Instruction::FPToUI:
		case Instruction::FPToSI:
		case Instruction::SIToFP:
		case Instruction::UIToFP:
		case Instruction::FPExt:
		case Instruction::FPTrunc:
			return 75;
		case Instruction::FCmp:
			return 100;
		case Instruction::FDiv:
		case Instruction::FRem:
			return 400;
		}
	}
	else if (isa<CmpInst>(inst))
	{
		bool constantOperand = false;
		for (User::const_op_iterator oi = inst->op_begin(), oe = inst->op_end();
			oi != oe; ++oi)
		{
			if (isa<Constant>(oi->get()))
			{
				constantOperand = true;
				break;
			}
		}
		if (cast<CmpInst>(inst)->getPredicate() > 31)
			return (constantOperand ? 6 : 8);	// integer comparison
		else
			return 100;
	}
	return 10;
}