LLVM: lib/Target/RISCV/RISCVPromoteConstant.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

33

34using namespace llvm;

35

36#define DEBUG_TYPE "riscv-promote-const"

37#define RISCV_PROMOTE_CONSTANT_NAME "RISC-V Promote Constants"

38

39STATISTIC(NumPromoted, "Number of constant literals promoted to globals");

40STATISTIC(NumPromotedUses, "Number of uses of promoted literal constants");

41

42namespace {

43

44class RISCVPromoteConstant : public ModulePass {

45public:

46 static char ID;

48

50

51 void getAnalysisUsage(AnalysisUsage &AU) const override {

54 }

55

56

57

58 bool runOnModule(Module &M) override {

59 if (skipModule(M))

60 return false;

61

62 const TargetPassConfig &TPC = getAnalysis();

63 const TargetMachine &TM = TPC.getTM();

65 for (Function &F : M) {

66 const RISCVSubtarget &ST = TM.getSubtarget(F);

67 const RISCVTargetLowering *TLI = ST.getTargetLowering();

69 }

71 }

72

73private:

74 bool runOnFunction(Function &F, const RISCVTargetLowering *TLI);

75};

76}

77

78char RISCVPromoteConstant::ID = 0;

79

81 false, false)

82

84 return new RISCVPromoteConstant();

85}

86

87bool RISCVPromoteConstant::runOnFunction(Function &F,

89 if (F.hasOptNone() || F.hasOptSize())

90 return false;

91

92

93

94

96 return false;

97

98

99

100 MapVector<ConstantFP *, SmallVector<Use *, 8>> ConstUsesMap;

101

103 for (Use &U : I.operands()) {

105 if (C || C->getType()->isDoubleTy())

106 continue;

107

108 if (TLI->isFPImmLegal(C->getValueAPF(), MVT::f64,

109 false))

110 continue;

111

112

114 Function *IntrinsicFunc = II->getFunction();

115 unsigned OperandIdx = U.getOperandNo();

116 if (IntrinsicFunc && IntrinsicFunc->getAttributes().hasParamAttr(

117 OperandIdx, Attribute::ImmArg)) {

118 LLVM_DEBUG(dbgs() << "Skipping promotion of constant in: " << *II

119 << " because operand " << OperandIdx

120 << " must be an immediate.\n");

121 continue;

122 }

123 }

124

125

126

127 ConstUsesMap[C].push_back(&U);

128 }

129 }

130

131 int PromotableConstants = ConstUsesMap.size();

133 << " promotable constants in " << F.getName() << "\n");

134

135 if (PromotableConstants < 2) {

136 LLVM_DEBUG(dbgs() << "Performing no promotions as insufficient promotable "

137 "constants found\n");

138 return false;

139 }

140

141 NumPromoted += PromotableConstants;

142

143

145 Type *DoubleTy = Type::getDoubleTy(M->getContext());

146

148 for (auto const &Pair : ConstUsesMap)

149 ConstantVector.push_back(Pair.first);

150

151 ArrayType *ArrayTy = ArrayType::get(DoubleTy, ConstantVector.size());

152 Constant *GlobalArrayInitializer =

154

155 auto *GlobalArray = new GlobalVariable(

156 *M, ArrayTy,

158 ".promoted_doubles." + F.getName());

159

160

161 DenseMap<std::pair<ConstantFP *, BasicBlock *>, Value *> LocalLoads;

162

163

164 unsigned Idx = 0;

165 for (auto const &Pair : ConstUsesMap) {

168

169 for (Use *U : Uses) {

172

173

174

175

177 InsertionBB = PN->getIncomingBlock(*U);

178 else

179 InsertionBB = UserInst->getParent();

180

182 LLVM_DEBUG(dbgs() << "Bailing out: catchswitch means thre is no valid "

183 "insertion point.\n");

184 return false;

185 }

186

187 auto CacheKey = std::make_pair(Const, InsertionBB);

188 Value *LoadedVal = nullptr;

189

190

191 if (LocalLoads.count(CacheKey)) {

192 LoadedVal = LocalLoads.at(CacheKey);

193 } else {

194

195

196

198 Value *ElementPtr = Builder.CreateConstInBoundsGEP2_64(

199 GlobalArray->getValueType(), GlobalArray, 0, Idx, "double.addr");

200 LoadedVal = Builder.CreateLoad(DoubleTy, ElementPtr, "double.val");

201

202

203 LocalLoads[CacheKey] = LoadedVal;

204 }

205

206 U->set(LoadedVal);

207 ++NumPromotedUses;

208 }

209 ++Idx;

210 }

211

212 return true;

213}

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)

ValueT & at(const_arg_type_t< KeyT > Val)

at - 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

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 - 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 - 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 - Return the argument parameter cast to the specified type.