LLVM: lib/Analysis/PHITransAddr.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

16#include "llvm/Config/llvm-config.h"

23using namespace llvm;

24

27 cl::desc("Enable phi-translation of add instructions"));

28

31 return true;

32

33 if (Inst->getOpcode() == Instruction::Add &&

35 return true;

36

37 return false;

38}

39

40#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

42 if (!Addr) {

43 dbgs() << "PHITransAddr: null\n";

44 return;

45 }

46 dbgs() << "PHITransAddr: " << *Addr << "\n";

47 for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)

48 dbgs() << " Input #" << i << " is " << *InstInputs[i] << "\n";

49}

50#endif

51

54

56 if (I) return true;

57

58

59

60 if (auto Entry = find(InstInputs, I); Entry != InstInputs.end()) {

61 InstInputs.erase(Entry);

62 return true;

63 }

64

65

66

68 errs() << "Instruction in PHITransAddr is not phi-translatable:\n";

69 errs() << *I << '\n';

70 llvm_unreachable("Either something is missing from InstInputs or "

71 "canPHITrans is wrong.");

72 }

73

74

75 return all_of(I->operands(),

76 [&](Value *Op) { return verifySubExpr(Op, InstInputs); });

77}

78

79

80

81

83 if (!Addr) return true;

84

86

88 return false;

89

90 if (!Tmp.empty()) {

91 errs() << "PHITransAddr contains extra instructions:\n";

92 for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)

93 errs() << " InstInput #" << i << " is " << *InstInputs[i] << "\n";

95 }

96

97

98 return true;

99}

100

101

102

103

110

114 if (I) return;

115

116

117 if (auto Entry = find(InstInputs, I); Entry != InstInputs.end()) {

118 InstInputs.erase(Entry);

119 return;

120 }

121

122 assert(isa<PHINode>(I) && "Error, removing something that isn't an input");

123

124

125 for (Value *Op : I->operands())

128}

129

133

135 if (!Inst) return V;

136

137

139

140

142 if (Inst->getParent() != CurBB) {

143

144

145 return Inst;

146 }

147

148

149

150

151

152 InstInputs.erase(find(InstInputs, Inst));

153

154

156 return addAsInput(PN->getIncomingValueForBlock(PredBB));

157

158

159

161 return nullptr;

162

163

164

166 addAsInput(Op);

167 }

168

169

170

171

172

174 Value *PHIIn = translateSubExpr(Cast->getOperand(0), CurBB, PredBB, DT);

175 if (!PHIIn) return nullptr;

176 if (PHIIn == Cast->getOperand(0))

177 return Cast;

178

179

180

181

183 {DL, TLI, DT, AC})) {

185 return addAsInput(V);

186 }

187

188

189

190 for (User *U : PHIIn->users()) {

192 if (CastI->getOpcode() == Cast->getOpcode() &&

193 CastI->getType() == Cast->getType() &&

194 (!DT || DT->dominates(CastI->getParent(), PredBB)))

195 return CastI;

196 }

197 return nullptr;

198 }

199

200

202 SmallVector<Value*, 8> GEPOps;

203 bool AnyChanged = false;

205 Value *GEPOp = translateSubExpr(Op, CurBB, PredBB, DT);

206 if (!GEPOp) return nullptr;

207

208 AnyChanged |= GEPOp != Op;

210 }

211

212 if (!AnyChanged)

213 return GEP;

214

215

218 GEP->getNoWrapFlags(), {DL, TLI, DT, AC})) {

221

222 return addAsInput(V);

223 }

224

225

226 Value *APHIOp = GEPOps[0];

228 return nullptr;

229

230 for (User *U : APHIOp->users()) {

232 if (GEPI->getType() == GEP->getType() &&

233 GEPI->getSourceElementType() == GEP->getSourceElementType() &&

234 GEPI->getNumOperands() == GEPOps.size() &&

235 GEPI->getParent()->getParent() == CurBB->getParent() &&

236 (!DT || DT->dominates(GEPI->getParent(), PredBB))) {

237 if (std::equal(GEPOps.begin(), GEPOps.end(), GEPI->op_begin()))

238 return GEPI;

239 }

240 }

241 return nullptr;

242 }

243

244

245 if (Inst->getOpcode() == Instruction::Add &&

247

251

252 Value *LHS = translateSubExpr(Inst->getOperand(0), CurBB, PredBB, DT);

253 if (LHS) return nullptr;

254

255

257 if (BOp->getOpcode() == Instruction::Add)

259 LHS = BOp->getOperand(0);

261 isNSW = isNUW = false;

262

263

266 addAsInput(LHS);

267 }

268 }

269

270

272

273

275 return addAsInput(Res);

276 }

277

278

280 return Inst;

281

282

283 for (User *U : LHS->users()) {

285 if (BO->getOpcode() == Instruction::Add &&

286 BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&

287 BO->getParent()->getParent() == CurBB->getParent() &&

288 (!DT || DT->dominates(BO->getParent(), PredBB)))

289 return BO;

290 }

291

292 return nullptr;

293 }

294

295

296 return nullptr;

297}

298

299

300

301

304 bool MustDominate) {

305 assert(DT || !MustDominate);

308 Addr = translateSubExpr(Addr, CurBB, PredBB, DT);

309 else

310 Addr = nullptr;

312

313 if (MustDominate)

314

317 Addr = nullptr;

318

319 return Addr;

320}

321

322

323

324

325

326

327

328

333 unsigned NISize = NewInsts.size();

334

335

336 Addr = insertTranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts);

337

338

339 if (Addr) return Addr;

340

341

342 while (NewInsts.size() != NISize)

344 return nullptr;

345}

346

347

348

349

350

351

352Value *PHITransAddr::insertTranslatedSubExpr(

355

356

358 if (Value *Addr =

359 Tmp.translateValue(CurBB, PredBB, &DT, true))

360 return Addr;

361

362

364 if (!Inst)

365 return nullptr;

366

367

369 Value *OpVal = insertTranslatedSubExpr(Cast->getOperand(0), CurBB, PredBB,

370 DT, NewInsts);

371 if (!OpVal) return nullptr;

372

373

375 InVal->getName() + ".phi.trans.insert",

379 return New;

380 }

381

382

387 Value *OpVal = insertTranslatedSubExpr(Op, CurBB, PredBB, DT, NewInsts);

388 if (!OpVal) return nullptr;

390 }

391

393 GEP->getSourceElementType(), GEPOps[0], ArrayRef(GEPOps).slice(1),

394 InVal->getName() + ".phi.trans.insert",

397 Result->setNoWrapFlags(GEP->getNoWrapFlags());

400 }

401

402

405

406

407

408

409

410

411 Value *OpVal = insertTranslatedSubExpr(Inst->getOperand(0), CurBB, PredBB,

412 DT, NewInsts);

413 if (OpVal == nullptr)

414 return nullptr;

415

416 BinaryOperator *Res = BinaryOperator::CreateAdd(

417 OpVal, Inst->getOperand(1), InVal->getName() + ".phi.trans.insert",

422 return Res;

423 }

424

425 return nullptr;

426}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static bool hasNoSignedWrap(BinaryOperator &I)

static bool hasNoUnsignedWrap(BinaryOperator &I)

static bool isInput(const ArrayRef< StringRef > &Prefixes, StringRef Arg)

static void RemoveInstInputs(Value *V, SmallVectorImpl< Instruction * > &InstInputs)

Definition PHITransAddr.cpp:111

static bool canPHITrans(Instruction *Inst)

Definition PHITransAddr.cpp:29

static cl::opt< bool > EnableAddPhiTranslation("gvn-add-phi-translation", cl::init(false), cl::Hidden, cl::desc("Enable phi-translation of add instructions"))

static bool verifySubExpr(Value *Expr, SmallVectorImpl< Instruction * > &InstInputs)

Definition PHITransAddr.cpp:52

LLVM Basic Block Representation.

const Function * getParent() const

Return the enclosing method, or null if none.

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

This is the base class for all instructions that perform data casts.

static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)

Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...

static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

LLVM_ABI bool isReachableFromEntry(const Use &U) const

Provide an overload for a Use.

LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const

Return true if the (end of the) basic block BB dominates the use U.

an instruction for type-safe pointer arithmetic to access elements of arrays and structs

static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

LLVM_ABI void setHasNoUnsignedWrap(bool b=true)

Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.

LLVM_ABI void setHasNoSignedWrap(bool b=true)

Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.

const DebugLoc & getDebugLoc() const

Return the debug location for this node as a DebugLoc.

unsigned getOpcode() const

Returns a member of one of the enums like Instruction::Add.

PHITransAddr - An address value which tracks and handles phi translation.

LLVM_ABI Value * translateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)

translateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state ...

Definition PHITransAddr.cpp:302

LLVM_ABI void dump() const

Definition PHITransAddr.cpp:41

LLVM_ABI bool isPotentiallyPHITranslatable() const

isPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...

Definition PHITransAddr.cpp:104

LLVM_ABI bool verify() const

verify - Check internal consistency of this data structure.

Definition PHITransAddr.cpp:82

LLVM_ABI Value * translateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl< Instruction * > &NewInsts)

translateWithInsertion - PHI translate this value into the specified predecessor block,...

Definition PHITransAddr.cpp:330

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

iterator erase(const_iterator CI)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

Value * getOperand(unsigned i) const

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

iterator_range< user_iterator > users()

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

const ParentTy * getParent() const

self_iterator getIterator()

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

initializer< Ty > init(const Ty &Val)

friend class Instruction

Iterator for Instructions in a `BasicBlock.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

auto find(R &&Range, const T &Val)

Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)

Given operands for a GetElementPtrInst, fold the result or return null.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)

Given operands for a CastInst, fold the result or return null.

LLVM_ABI Value * simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, const SimplifyQuery &Q)

Given operands for an Add, fold the result or return null.

auto dyn_cast_or_null(const Y &Val)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

DWARFExpression::Operation Op

ArrayRef(const T &OneElt) -> ArrayRef< T >

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.