mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-30 21:29:28 +00:00
Adds a function to target transform info to query for the cost of address computation. The cost model analysis pass now also queries this interface. The code in LoopVectorize adds the cost of address computation as part of the memory instruction cost calculation. Only there, we know whether the instruction will be scalarized or not. Increase the penality for inserting in to D registers on swift. This becomes necessary because we now always assume that address computation has a cost and three is a closer value to the architecture. radar://13097204 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174713 91177308-0d34-0410-b5e6-96231b3b80d8
197 lines
6.3 KiB
C++
197 lines
6.3 KiB
C++
//===- CostModel.cpp ------ Cost Model Analysis ---------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the cost model analysis. It provides a very basic cost
|
|
// estimation for LLVM-IR. This analysis uses the services of the codegen
|
|
// to approximate the cost of any IR instruction when lowered to machine
|
|
// instructions. The cost results are unit-less and the cost number represents
|
|
// the throughput of the machine assuming that all loads hit the cache, all
|
|
// branches are predicted, etc. The cost numbers can be added in order to
|
|
// compare two or more transformation alternatives.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define CM_NAME "cost-model"
|
|
#define DEBUG_TYPE CM_NAME
|
|
#include "llvm/Analysis/Passes.h"
|
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/IR/Value.h"
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
class CostModelAnalysis : public FunctionPass {
|
|
|
|
public:
|
|
static char ID; // Class identification, replacement for typeinfo
|
|
CostModelAnalysis() : FunctionPass(ID), F(0), TTI(0) {
|
|
initializeCostModelAnalysisPass(
|
|
*PassRegistry::getPassRegistry());
|
|
}
|
|
|
|
/// Returns the expected cost of the instruction.
|
|
/// Returns -1 if the cost is unknown.
|
|
/// Note, this method does not cache the cost calculation and it
|
|
/// can be expensive in some cases.
|
|
unsigned getInstructionCost(const Instruction *I) const;
|
|
|
|
private:
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
|
virtual bool runOnFunction(Function &F);
|
|
virtual void print(raw_ostream &OS, const Module*) const;
|
|
|
|
/// The function that we analyze.
|
|
Function *F;
|
|
/// Target information.
|
|
const TargetTransformInfo *TTI;
|
|
};
|
|
} // End of anonymous namespace
|
|
|
|
// Register this pass.
|
|
char CostModelAnalysis::ID = 0;
|
|
static const char cm_name[] = "Cost Model Analysis";
|
|
INITIALIZE_PASS_BEGIN(CostModelAnalysis, CM_NAME, cm_name, false, true)
|
|
INITIALIZE_PASS_END (CostModelAnalysis, CM_NAME, cm_name, false, true)
|
|
|
|
FunctionPass *llvm::createCostModelAnalysisPass() {
|
|
return new CostModelAnalysis();
|
|
}
|
|
|
|
void
|
|
CostModelAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
|
|
AU.setPreservesAll();
|
|
}
|
|
|
|
bool
|
|
CostModelAnalysis::runOnFunction(Function &F) {
|
|
this->F = &F;
|
|
TTI = getAnalysisIfAvailable<TargetTransformInfo>();
|
|
|
|
return false;
|
|
}
|
|
|
|
unsigned CostModelAnalysis::getInstructionCost(const Instruction *I) const {
|
|
if (!TTI)
|
|
return -1;
|
|
|
|
switch (I->getOpcode()) {
|
|
case Instruction::GetElementPtr:{
|
|
Type *ValTy = I->getOperand(0)->getType()->getPointerElementType();
|
|
return TTI->getAddressComputationCost(ValTy);
|
|
}
|
|
|
|
case Instruction::Ret:
|
|
case Instruction::PHI:
|
|
case Instruction::Br: {
|
|
return TTI->getCFInstrCost(I->getOpcode());
|
|
}
|
|
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::Shl:
|
|
case Instruction::LShr:
|
|
case Instruction::AShr:
|
|
case Instruction::And:
|
|
case Instruction::Or:
|
|
case Instruction::Xor: {
|
|
return TTI->getArithmeticInstrCost(I->getOpcode(), I->getType());
|
|
}
|
|
case Instruction::Select: {
|
|
const SelectInst *SI = cast<SelectInst>(I);
|
|
Type *CondTy = SI->getCondition()->getType();
|
|
return TTI->getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy);
|
|
}
|
|
case Instruction::ICmp:
|
|
case Instruction::FCmp: {
|
|
Type *ValTy = I->getOperand(0)->getType();
|
|
return TTI->getCmpSelInstrCost(I->getOpcode(), ValTy);
|
|
}
|
|
case Instruction::Store: {
|
|
const StoreInst *SI = cast<StoreInst>(I);
|
|
Type *ValTy = SI->getValueOperand()->getType();
|
|
return TTI->getMemoryOpCost(I->getOpcode(), ValTy,
|
|
SI->getAlignment(),
|
|
SI->getPointerAddressSpace());
|
|
}
|
|
case Instruction::Load: {
|
|
const LoadInst *LI = cast<LoadInst>(I);
|
|
return TTI->getMemoryOpCost(I->getOpcode(), I->getType(),
|
|
LI->getAlignment(),
|
|
LI->getPointerAddressSpace());
|
|
}
|
|
case Instruction::ZExt:
|
|
case Instruction::SExt:
|
|
case Instruction::FPToUI:
|
|
case Instruction::FPToSI:
|
|
case Instruction::FPExt:
|
|
case Instruction::PtrToInt:
|
|
case Instruction::IntToPtr:
|
|
case Instruction::SIToFP:
|
|
case Instruction::UIToFP:
|
|
case Instruction::Trunc:
|
|
case Instruction::FPTrunc:
|
|
case Instruction::BitCast: {
|
|
Type *SrcTy = I->getOperand(0)->getType();
|
|
return TTI->getCastInstrCost(I->getOpcode(), I->getType(), SrcTy);
|
|
}
|
|
case Instruction::ExtractElement: {
|
|
const ExtractElementInst * EEI = cast<ExtractElementInst>(I);
|
|
ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1));
|
|
unsigned Idx = -1;
|
|
if (CI)
|
|
Idx = CI->getZExtValue();
|
|
return TTI->getVectorInstrCost(I->getOpcode(),
|
|
EEI->getOperand(0)->getType(), Idx);
|
|
}
|
|
case Instruction::InsertElement: {
|
|
const InsertElementInst * IE = cast<InsertElementInst>(I);
|
|
ConstantInt *CI = dyn_cast<ConstantInt>(IE->getOperand(2));
|
|
unsigned Idx = -1;
|
|
if (CI)
|
|
Idx = CI->getZExtValue();
|
|
return TTI->getVectorInstrCost(I->getOpcode(),
|
|
IE->getType(), Idx);
|
|
}
|
|
default:
|
|
// We don't have any information on this instruction.
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
void CostModelAnalysis::print(raw_ostream &OS, const Module*) const {
|
|
if (!F)
|
|
return;
|
|
|
|
for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
|
|
for (BasicBlock::iterator it = B->begin(), e = B->end(); it != e; ++it) {
|
|
Instruction *Inst = it;
|
|
unsigned Cost = getInstructionCost(Inst);
|
|
if (Cost != (unsigned)-1)
|
|
OS << "Cost Model: Found an estimated cost of " << Cost;
|
|
else
|
|
OS << "Cost Model: Unknown cost";
|
|
|
|
OS << " for instruction: "<< *Inst << "\n";
|
|
}
|
|
}
|
|
}
|