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>();
65 if (
F.isDeclaration())
68 const RISCVTargetLowering *TLI =
ST.getTargetLowering();
79char RISCVPromoteConstant::ID = 0;
85 return new RISCVPromoteConstant();
88bool RISCVPromoteConstant::runOnFunction(
Function &
F,
90 if (
F.hasOptNone() ||
F.hasOptSize())
101 MapVector<ConstantFP *, SmallVector<Use *, 8>> ConstUsesMap;
104 for (Use &U :
I.operands()) {
106 if (!
C || !
C->getType()->isDoubleTy())
116 unsigned OperandIdx =
U.getOperandNo();
117 if (IntrinsicFunc && IntrinsicFunc->
getAttributes().hasParamAttr(
118 OperandIdx, Attribute::ImmArg)) {
120 <<
" because operand " << OperandIdx
121 <<
" must be an immediate.\n");
128 ConstUsesMap[
C].push_back(&U);
132 int PromotableConstants = ConstUsesMap.
size();
134 <<
" promotable constants in " <<
F.getName() <<
"\n");
136 if (PromotableConstants < 2) {
137 LLVM_DEBUG(
dbgs() <<
"Performing no promotions as insufficient promotable "
138 "constants found\n");
142 NumPromoted += PromotableConstants;
146 Type *DoubleTy = Type::getDoubleTy(
M->getContext());
149 for (
auto const &Pair : ConstUsesMap)
152 ArrayType *ArrayTy = ArrayType::get(DoubleTy, ConstantVector.
size());
156 auto *GlobalArray =
new GlobalVariable(
159 ".promoted_doubles." +
F.getName());
162 DenseMap<std::pair<ConstantFP *, BasicBlock *>,
Value *> LocalLoads;
166 for (
auto const &Pair : ConstUsesMap) {
170 for (Use *U :
Uses) {
178 InsertionBB = PN->getIncomingBlock(*U);
183 LLVM_DEBUG(
dbgs() <<
"Bailing out: catchswitch means thre is no valid "
184 "insertion point.\n");
188 auto CacheKey = std::make_pair(Const, InsertionBB);
189 Value *LoadedVal =
nullptr;
192 if (LocalLoads.
count(CacheKey)) {
193 LoadedVal = LocalLoads.
at(CacheKey);
199 Value *ElementPtr = Builder.CreateConstInBoundsGEP2_64(
200 GlobalArray->getValueType(), GlobalArray, 0, Idx,
"double.addr");
201 LoadedVal = Builder.CreateLoad(DoubleTy, ElementPtr,
"double.val");
204 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.