36#define DEBUG_TYPE "riscv-promote-const"
37#define RISCV_PROMOTE_CONSTANT_NAME "RISC-V Promote Constants"
39STATISTIC(NumPromoted,
"Number of constant literals promoted to globals");
40STATISTIC(NumPromotedUses,
"Number of uses of promoted literal constants");
44class RISCVPromoteConstant :
public ModulePass {
51 void getAnalysisUsage(AnalysisUsage &AU)
const override {
58 bool runOnModule(
Module &M)
override {
62 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
63 const TargetMachine &
TM = TPC.
getTM<TargetMachine>();
65 for (Function &
F : M) {
66 const RISCVSubtarget &
ST =
TM.getSubtarget<RISCVSubtarget>(
F);
67 const RISCVTargetLowering *TLI =
ST.getTargetLowering();
78char RISCVPromoteConstant::ID = 0;
84 return new RISCVPromoteConstant();
87bool RISCVPromoteConstant::runOnFunction(
Function &
F,
89 if (
F.hasOptNone() ||
F.hasOptSize())
100 MapVector<ConstantFP *, SmallVector<Use *, 8>> ConstUsesMap;
103 for (Use &U :
I.operands()) {
105 if (!
C || !
C->getType()->isDoubleTy())
115 unsigned OperandIdx =
U.getOperandNo();
116 if (IntrinsicFunc && IntrinsicFunc->
getAttributes().hasParamAttr(
117 OperandIdx, Attribute::ImmArg)) {
119 <<
" because operand " << OperandIdx
120 <<
" must be an immediate.\n");
127 ConstUsesMap[
C].push_back(&U);
131 int PromotableConstants = ConstUsesMap.
size();
133 <<
" promotable constants in " <<
F.getName() <<
"\n");
135 if (PromotableConstants < 2) {
136 LLVM_DEBUG(
dbgs() <<
"Performing no promotions as insufficient promotable "
137 "constants found\n");
141 NumPromoted += PromotableConstants;
145 Type *DoubleTy = Type::getDoubleTy(
M->getContext());
148 for (
auto const &Pair : ConstUsesMap)
151 ArrayType *ArrayTy = ArrayType::get(DoubleTy, ConstantVector.
size());
155 auto *GlobalArray =
new GlobalVariable(
158 ".promoted_doubles." +
F.getName());
161 DenseMap<std::pair<ConstantFP *, BasicBlock *>,
Value *> LocalLoads;
165 for (
auto const &Pair : ConstUsesMap) {
169 for (Use *U :
Uses) {
177 InsertionBB = PN->getIncomingBlock(*U);
182 LLVM_DEBUG(
dbgs() <<
"Bailing out: catchswitch means thre is no valid "
183 "insertion point.\n");
187 auto CacheKey = std::make_pair(Const, InsertionBB);
188 Value *LoadedVal =
nullptr;
191 if (LocalLoads.
count(CacheKey)) {
192 LoadedVal = LocalLoads.
at(CacheKey);
198 Value *ElementPtr = Builder.CreateConstInBoundsGEP2_64(
199 GlobalArray->getValueType(), GlobalArray, 0, Idx,
"double.addr");
200 LoadedVal = Builder.CreateLoad(DoubleTy, ElementPtr,
"double.val");
203 LocalLoads[CacheKey] = LoadedVal;
Expand Atomic instructions
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
Machine Check Debug Module
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Remove Loads Into Fake Uses
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
const ValueT & at(const_arg_type_t< KeyT > Val) const
at - Return the entry for the specified key, or abort if no such entry exists.
AttributeList getAttributes() const
Return the attribute list for this Function.
@ InternalLinkage
Rename collisions when linking (static functions).
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
void push_back(const T &Elt)
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
TMC & getTM() const
Get the right type of TargetMachine for this target.
const ParentTy * getParent() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
ModulePass * createRISCVPromoteConstantPass()
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.