@@ -82,6 +82,11 @@ static cl::opt<unsigned> FrequentBranchThreshold(
82
82
" it is considered frequently taken" ),
83
83
cl::init(1000 ));
84
84
85
+ static cl::opt<bool >
86
+ WidenBranchGuards (" guard-widening-widen-branch-guards" , cl::Hidden,
87
+ cl::desc (" Whether or not we should widen guards "
88
+ " expressed as branches by widenable conditions" ),
89
+ cl::init(true ));
85
90
86
91
namespace {
87
92
@@ -92,6 +97,10 @@ static Value *getCondition(Instruction *I) {
92
97
" Bad guard intrinsic?" );
93
98
return GI->getArgOperand (0 );
94
99
}
100
+ if (isGuardAsWidenableBranch (I)) {
101
+ auto *Cond = cast<BranchInst>(I)->getCondition ();
102
+ return cast<BinaryOperator>(Cond)->getOperand (0 );
103
+ }
95
104
return cast<BranchInst>(I)->getCondition ();
96
105
}
97
106
@@ -262,8 +271,16 @@ class GuardWideningImpl {
262
271
void widenGuard (Instruction *ToWiden, Value *NewCondition,
263
272
bool InvertCondition) {
264
273
Value *Result;
265
- widenCondCommon (ToWiden-> getOperand ( 0 ), NewCondition, ToWiden, Result,
274
+ widenCondCommon (getCondition (ToWiden ), NewCondition, ToWiden, Result,
266
275
InvertCondition);
276
+ Value *WidenableCondition = nullptr ;
277
+ if (isGuardAsWidenableBranch (ToWiden)) {
278
+ auto *Cond = cast<BranchInst>(ToWiden)->getCondition ();
279
+ WidenableCondition = cast<BinaryOperator>(Cond)->getOperand (1 );
280
+ }
281
+ if (WidenableCondition)
282
+ Result = BinaryOperator::CreateAnd (Result, WidenableCondition,
283
+ " guard.chk" , ToWiden);
267
284
setCondition (ToWiden, Result);
268
285
}
269
286
@@ -281,6 +298,14 @@ class GuardWideningImpl {
281
298
};
282
299
}
283
300
301
+ static bool isSupportedGuardInstruction (const Instruction *Insn) {
302
+ if (isGuard (Insn))
303
+ return true ;
304
+ if (WidenBranchGuards && isGuardAsWidenableBranch (Insn))
305
+ return true ;
306
+ return false ;
307
+ }
308
+
284
309
bool GuardWideningImpl::run () {
285
310
DenseMap<BasicBlock *, SmallVector<Instruction *, 8 >> GuardsInBlock;
286
311
bool Changed = false ;
@@ -300,7 +325,7 @@ bool GuardWideningImpl::run() {
300
325
auto &CurrentList = GuardsInBlock[BB];
301
326
302
327
for (auto &I : *BB)
303
- if (isGuard (&I))
328
+ if (isSupportedGuardInstruction (&I))
304
329
CurrentList.push_back (cast<Instruction>(&I));
305
330
306
331
for (auto *II : CurrentList)
@@ -322,7 +347,7 @@ bool GuardWideningImpl::run() {
322
347
for (auto *I : EliminatedGuardsAndBranches)
323
348
if (!WidenedGuards.count (I)) {
324
349
assert (isa<ConstantInt>(getCondition (I)) && " Should be!" );
325
- if (isGuard (I))
350
+ if (isSupportedGuardInstruction (I))
326
351
eliminateGuard (I);
327
352
else {
328
353
assert (isa<BranchInst>(I) &&
@@ -452,6 +477,8 @@ GuardWideningImpl::computeWideningScore(Instruction *DominatedInstr,
452
477
auto MaybeHoistingOutOfIf = [&]() {
453
478
auto *DominatingBlock = DominatingGuard->getParent ();
454
479
auto *DominatedBlock = DominatedInstr->getParent ();
480
+ if (isGuardAsWidenableBranch (DominatingGuard))
481
+ DominatingBlock = cast<BranchInst>(DominatingGuard)->getSuccessor (0 );
455
482
456
483
// Same Block?
457
484
if (DominatedBlock == DominatingBlock)
0 commit comments