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) {
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
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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; assumes that the block is well-formed.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
ValueT & at(const_arg_type_t< KeyT > Val)
Return the entry for the specified key, or abort if no such entry exists.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
TMC & getTM() const
Get the right type of TargetMachine for this target.
const ParentTy * getParent() const
@ BasicBlock
Various leaf nodes.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.