Пример #1
0
void fun_llvm_2_nts::process_instruction ( const llvm::Instruction & i, StateInfo & st )
{
	switch ( i.getOpcode() )
	{
		case Instruction::Alloca:
			return ctx.m_alloca.process ( bni, st, funmap, i );

		case Instruction::Call:
			return ctx.m_icall.process ( bni, st, funmap, i );

		case Instruction::Store:
		case Instruction::Load:
		case Instruction::Ret:
			return ctx.m_ils.process ( bni, st, funmap, i );

		case Instruction::Add:
			return ctx.m_ia.process ( bni, st, funmap, i );

		case Instruction::ICmp:
			return ctx.m_icmp.process ( bni, st, funmap, i );

		case Instruction::Br:
			return ctx.m_ibr.process ( bni, st, funmap, i );

		default:
		{
			string s ( "Instruction not implemented: " );
			throw std::domain_error ( ( s + i.getOpcodeName() ).c_str() );
		}

	}
}
Пример #2
0
  /// \brief Set the currently active llvm::Instruction.
  ///
  void
  setActiveInstruction(llvm::Instruction const * const NewActiveInstruction) {
    ActiveInstruction = NewActiveInstruction;

    auto const BB = ActiveInstruction->getParent();
    if (BB != ActiveBasicBlock) {
      PreviousBasicBlock = ActiveBasicBlock;
      ActiveBasicBlock   = BB;
    }
  }
Пример #3
0
bool DINOGlobal::isFuncEntryInstruction(llvm::Instruction &I){

  llvm::BasicBlock *B = I.getParent();
  llvm::Function *F = B->getParent();
  llvm::BasicBlock &FuncEntryBlock = F->front();
  llvm::Instruction &FuncEntryInst = FuncEntryBlock.front();
  
  if( &I == &FuncEntryInst ){
    return true;
  }
  return false;

}
Пример #4
0
static bool instMatchesCrit(LLVMDependenceGraph& dg,
                            const llvm::Instruction& I,
                            const std::vector<std::pair<int, std::string>>& parsedCrit)
{
    for (const auto& c : parsedCrit) {
        auto& Loc = I.getDebugLoc();
        if (!Loc)
            continue;
        if (static_cast<int>(Loc.getLine()) != c.first)
            continue;

        if (isStoreToTheVar(dg, I, c.second) ||
            isLoadOfTheVar(dg, I, c.second)) {
            llvm::errs() << "Matched line " << c.first << " with variable "
                         << c.second << " to:\n" << I << "\n";
            return true;
        }
    }

    return false;
}
Пример #5
0
/// canHoistInst - Return true if the hoister can handle this instruction.
bool Hoister::canHoistInst(llvm::Instruction &I, llvm::AliasAnalysis *AA)
{
    // Loads have extra constraints we have to verify before we can hoist them.
    if (llvm::LoadInst *LI = llvm::dyn_cast<llvm::LoadInst>(&I)) {
        if (LI->isVolatile()) {
            return false;        // Don't hoist volatile loads!
        }

        // Loads from constant memory are always safe to move, even if they end up
        // in the same alias set as something that ends up being modified.
        if (AA->pointsToConstantMemory(LI->getOperand(0))) {
            return true;
        }

        // Don't hoist loads which have may-aliased stores in loop.
        uint64_t Size = 0;
        if (LI->getType()->isSized()) {
#if LLVM_VERSION <= VERSION(3, 7)
            Size = AA->getTypeStoreSize(LI->getType());
#else
            Size = I.getModule()->getDataLayout().getTypeStoreSize(LI->getType());
#endif
        }
#if LLVM_VERSION <= VERSION(3, 5)
        return !CurAST->getAliasSetForPointer(LI->getOperand(0), Size, LI->getMetadata(llvm::LLVMContext::MD_tbaa)).isMod();
#else
        llvm::AAMDNodes AAInfo;
        LI->getAAMetadata(AAInfo);
        return !CurAST->getAliasSetForPointer(LI->getOperand(0), Size, AAInfo).isMod();
#endif
    } else if (llvm::CallInst *CI = llvm::dyn_cast<llvm::CallInst>(&I)) {
        // Handle obvious cases efficiently.
#if LLVM_VERSION <= VERSION(3, 7)
        llvm::AliasAnalysis::ModRefBehavior Behavior = AA->getModRefBehavior(CI);
#else
        llvm::FunctionModRefBehavior Behavior = AA->getModRefBehavior(CI);
#endif
#if LLVM_VERSION <= VERSION(3, 7)
        if (Behavior == llvm::AliasAnalysis::DoesNotAccessMemory || doesNotAccessMemory(CI->getCalledFunction())) {
#else
        if (Behavior == llvm::FMRB_DoesNotAccessMemory || doesNotAccessMemory(CI->getCalledFunction())) {
#endif
            return true;
#if LLVM_VERSION <= VERSION(3, 7)
        } else if (Behavior == llvm::AliasAnalysis::OnlyReadsMemory) {
#else
        } else if (Behavior == llvm::FMRB_OnlyReadsMemory) {
#endif
            // If this call only reads from memory and there are no writes to memory
            // in the loop, we can hoist or sink the call as appropriate.
            bool FoundMod = false;
            for (llvm::AliasSetTracker::iterator IT = CurAST->begin(), ET = CurAST->end(); IT != ET; ++IT) {
                llvm::AliasSet &AS = *IT;
                if (!AS.isForwardingAliasSet() && AS.isMod()) {
                    FoundMod = true;
                    break;
                }
            }
            if (!FoundMod) {
                return true;
            }
        }

        // FIXME: This should use mod/ref information to see if we can hoist the call.
        return false;
    }

    // Otherwise these instructions are hoistable.
    if (llvm::isa<llvm::BinaryOperator>(I)) {
        llvm::BinaryOperator *binop = llvm::cast<llvm::BinaryOperator>(&I);
        llvm::BinaryOperator::BinaryOps opcode = binop->getOpcode();
        if (opcode == llvm::BinaryOperator::Xor) {
            if (llvm::isa<llvm::ConstantInt>(I.getOperand(1)) && llvm::cast<llvm::ConstantInt>(I.getOperand(1))->isAllOnesValue()) {
                // it is xor %i, -1 --> actually, it is -%i - 1
                return false;
            } else {
                return true;
            }
        } else if (I.getType()->isFloatingPointTy()) {
            return true;
        } else {
            bool res = (opcode == llvm::BinaryOperator::SDiv);
            res |= (opcode == llvm::BinaryOperator::UDiv);
            res |= (opcode == llvm::BinaryOperator::SRem);
            res |= (opcode == llvm::BinaryOperator::URem);
            res |= (opcode == llvm::BinaryOperator::AShr);
            res |= (opcode == llvm::BinaryOperator::LShr);
            res |= (opcode == llvm::BinaryOperator::Shl);
            res |= (opcode == llvm::BinaryOperator::And);
            res |= (opcode == llvm::BinaryOperator::Or);
            res |= (opcode == llvm::BinaryOperator::Xor);
            return res;
        }
    } else if (llvm::isa<llvm::ZExtInst>(I) || llvm::isa<llvm::SExtInst>(I) || llvm::isa<llvm::TruncInst>(I)) {
        return true;
    } else if (llvm::isa<llvm::PHINode>(I)) {
        return false;
    } else if (llvm::isa<llvm::PtrToIntInst>(I)) {
        return true;
    } else if (llvm::isa<llvm::FPToSIInst>(I) || llvm::isa<llvm::FPToUIInst>(I)) {
        return true;
    } else if (llvm::isa<llvm::PointerType>(I.getType())) {
        return true;
    } else {
        return false;
    }
}

/// isLoopInvariantInst - Return true if all operands of this instruction are loop invariant.
bool Hoister::isLoopInvariantInst(llvm::Loop *L, llvm::Instruction &I)
{
    // The instruction is loop invariant if all of its operands are loop-invariant
    for (unsigned int i = 0, e = I.getNumOperands(); i != e; ++i) {
        if (!L->isLoopInvariant(I.getOperand(i))) {
            return false;
        }
    }

    // If we got this far, the instruction is loop invariant!
    return true;
}

/// hoist - When an instruction is found to only use loop invariant operands
/// that is safe to hoist, this instruction is called to do the dirty work.
void Hoister::hoist(llvm::BasicBlock *preheader, llvm::Instruction &I)
{
    // Remove the instruction from its current basic block... but don't delete the
    // instruction.
    I.removeFromParent();

    // Insert the new node in Preheader, before the terminator.
    I.insertBefore(preheader->getTerminator());

    changed = true;
}
Пример #6
0
unsigned 
InstructionCostEstimator::getInstructionCost(const llvm::Instruction &I) {
  switch (I.getOpcode()) {
    case llvm::Instruction::GetElementPtr:
      return Cost::Low;
    case llvm::Instruction::Ret:
    case llvm::Instruction::PHI:
    case llvm::Instruction::Br:
      return Cost::No;
    case llvm::Instruction::FRem:
    case llvm::Instruction::FAdd:
    case llvm::Instruction::FSub:
    case llvm::Instruction::FMul:
    case llvm::Instruction::FDiv:
      return Cost::Medium;
    case llvm::Instruction::Add:
    case llvm::Instruction::Sub:
    case llvm::Instruction::Mul:
    case llvm::Instruction::UDiv:
    case llvm::Instruction::SDiv:
    case llvm::Instruction::URem:
    case llvm::Instruction::SRem:
    case llvm::Instruction::Shl:
    case llvm::Instruction::LShr:
    case llvm::Instruction::AShr:
    case llvm::Instruction::And:
    case llvm::Instruction::Or:
    case llvm::Instruction::Xor:
      return Cost::Low;
    case llvm::Instruction::Select:
      return Cost::Low;
    case llvm::Instruction::ICmp:
    case llvm::Instruction::FCmp:
      return Cost::Low;
    case llvm::Instruction::Store:
      return Cost::Low;
    case llvm::Instruction::Load:
      return Cost::Low;
    case llvm::Instruction::ZExt:
    case llvm::Instruction::SExt:
    case llvm::Instruction::FPToUI:
    case llvm::Instruction::FPToSI:
    case llvm::Instruction::FPExt:
    case llvm::Instruction::PtrToInt:
    case llvm::Instruction::IntToPtr:
    case llvm::Instruction::SIToFP:
    case llvm::Instruction::UIToFP:
    case llvm::Instruction::Trunc:
    case llvm::Instruction::FPTrunc:
    case llvm::Instruction::BitCast:
    case llvm::Instruction::AddrSpaceCast:
      return Cost::No;
    case llvm::Instruction::ExtractElement:
      return Cost::Low;
    case llvm::Instruction::InsertElement:
      return Cost::Low;
    case llvm::Instruction::ShuffleVector:
      return Cost::Low;
    case llvm::Instruction::Call:
      return Cost::Low;
    default:
      return Cost::Low;
  }
}