35#define DEBUG_TYPE "riscv-promote-const"
36#define RISCV_PROMOTE_CONSTANT_NAME "RISC-V Promote Constants"
38STATISTIC(NumPromoted,
"Number of constant literals promoted to globals");
39STATISTIC(NumPromotedUses,
"Number of uses of promoted literal constants");
43class RISCVPromoteConstant :
public ModulePass {
50 void getAnalysisUsage(AnalysisUsage &AU)
const override {
57 bool runOnModule(
Module &M)
override {
61 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
62 const TargetMachine &TM = TPC.
getTM<TargetMachine>();
66 const RISCVTargetLowering *TLI =
ST.getTargetLowering();
77char RISCVPromoteConstant::ID = 0;
83 return new RISCVPromoteConstant();
86bool RISCVPromoteConstant::runOnFunction(
Function &
F,
88 if (
F.hasOptNone() ||
F.hasOptSize())
99 MapVector<ConstantFP *, SmallVector<Use *, 8>> ConstUsesMap;
102 for (Use &U :
I.operands()) {
104 if (!
C || !
C->getType()->isDoubleTy())
114 unsigned OperandIdx =
U.getOperandNo();
115 if (IntrinsicFunc && IntrinsicFunc->
getAttributes().hasParamAttr(
116 OperandIdx, Attribute::ImmArg)) {
118 <<
" because operand " << OperandIdx
119 <<
" must be an immediate.\n");
126 ConstUsesMap[
C].push_back(&U);
130 int PromotableConstants = ConstUsesMap.
size();
132 <<
" promotable constants in " <<
F.getName() <<
"\n");
134 if (PromotableConstants < 2) {
135 LLVM_DEBUG(
dbgs() <<
"Performing no promotions as insufficient promotable "
136 "constants found\n");
140 NumPromoted += PromotableConstants;
144 Type *DoubleTy = Type::getDoubleTy(
M->getContext());
147 for (
auto const &Pair : ConstUsesMap)
150 ArrayType *ArrayTy = ArrayType::get(DoubleTy, ConstantVector.
size());
154 auto *GlobalArray =
new GlobalVariable(
157 ".promoted_doubles." +
F.getName());
160 DenseMap<std::pair<ConstantFP *, BasicBlock *>,
Value *> LocalLoads;
164 for (
auto const &Pair : ConstUsesMap) {
168 for (Use *U :
Uses) {
176 InsertionBB = PN->getIncomingBlock(*U);
181 LLVM_DEBUG(
dbgs() <<
"Bailing out: catchswitch means thre is no valid "
182 "insertion point.\n");
186 auto CacheKey = std::make_pair(Const, InsertionBB);
187 Value *LoadedVal =
nullptr;
190 if (LocalLoads.
count(CacheKey)) {
191 LoadedVal = LocalLoads.
at(CacheKey);
197 Value *ElementPtr = Builder.CreateConstInBoundsGEP2_64(
198 GlobalArray->getValueType(), GlobalArray, 0, Idx,
"double.addr");
199 LoadedVal = Builder.CreateLoad(DoubleTy, ElementPtr,
"double.val");
202 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.