29
29
#include " llvm/Analysis/CFG.h"
30
30
#include " llvm/Analysis/CallGraph.h"
31
31
#include " llvm/Analysis/CallGraphSCCPass.h"
32
+ #include " llvm/Analysis/ConstantFolding.h"
32
33
#include " llvm/Analysis/LazyCallGraph.h"
33
34
#include " llvm/IR/Argument.h"
34
35
#include " llvm/IR/Attributes.h"
@@ -1197,6 +1198,15 @@ scanPHIsAndUpdateValueMap(Instruction *Prev, BasicBlock *NewBlock,
1197
1198
static bool simplifyTerminatorLeadingToRet (Instruction *InitialInst) {
1198
1199
DenseMap<Value *, Value *> ResolvedValues;
1199
1200
BasicBlock *UnconditionalSucc = nullptr ;
1201
+ assert (InitialInst->getModule ());
1202
+ const DataLayout &DL = InitialInst->getModule ()->getDataLayout ();
1203
+
1204
+ auto TryResolveConstant = [&ResolvedValues](Value *V) {
1205
+ auto It = ResolvedValues.find (V);
1206
+ if (It != ResolvedValues.end ())
1207
+ V = It->second ;
1208
+ return dyn_cast<ConstantInt>(V);
1209
+ };
1200
1210
1201
1211
Instruction *I = InitialInst;
1202
1212
while (I->isTerminator () ||
@@ -1213,47 +1223,65 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) {
1213
1223
}
1214
1224
if (auto *BR = dyn_cast<BranchInst>(I)) {
1215
1225
if (BR->isUnconditional ()) {
1216
- BasicBlock *BB = BR->getSuccessor (0 );
1226
+ BasicBlock *Succ = BR->getSuccessor (0 );
1217
1227
if (I == InitialInst)
1218
- UnconditionalSucc = BB;
1219
- scanPHIsAndUpdateValueMap (I, BB, ResolvedValues);
1220
- I = BB->getFirstNonPHIOrDbgOrLifetime ();
1228
+ UnconditionalSucc = Succ;
1229
+ scanPHIsAndUpdateValueMap (I, Succ, ResolvedValues);
1230
+ I = Succ->getFirstNonPHIOrDbgOrLifetime ();
1231
+ continue ;
1232
+ }
1233
+
1234
+ BasicBlock *BB = BR->getParent ();
1235
+ // Handle the case the condition of the conditional branch is constant.
1236
+ // e.g.,
1237
+ //
1238
+ // br i1 false, label %cleanup, label %CoroEnd
1239
+ //
1240
+ // It is possible during the transformation. We could continue the
1241
+ // simplifying in this case.
1242
+ if (ConstantFoldTerminator (BB, /* DeleteDeadConditions=*/ true )) {
1243
+ // Handle this branch in next iteration.
1244
+ I = BB->getTerminator ();
1221
1245
continue ;
1222
1246
}
1223
1247
} else if (auto *CondCmp = dyn_cast<CmpInst>(I)) {
1248
+ // If the case number of suspended switch instruction is reduced to
1249
+ // 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator.
1224
1250
auto *BR = dyn_cast<BranchInst>(I->getNextNode ());
1225
- if (BR && BR->isConditional () && CondCmp == BR->getCondition ()) {
1226
- // If the case number of suspended switch instruction is reduced to
1227
- // 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator.
1228
- // And the comparsion looks like : %cond = icmp eq i8 %V, constant.
1229
- ConstantInt *CondConst = dyn_cast<ConstantInt>(CondCmp->getOperand (1 ));
1230
- if (CondConst && CondCmp->getPredicate () == CmpInst::ICMP_EQ) {
1231
- Value *V = CondCmp->getOperand (0 );
1232
- auto it = ResolvedValues.find (V);
1233
- if (it != ResolvedValues.end ())
1234
- V = it->second ;
1235
-
1236
- if (ConstantInt *Cond0 = dyn_cast<ConstantInt>(V)) {
1237
- BasicBlock *BB = Cond0->equalsInt (CondConst->getZExtValue ())
1238
- ? BR->getSuccessor (0 )
1239
- : BR->getSuccessor (1 );
1240
- scanPHIsAndUpdateValueMap (I, BB, ResolvedValues);
1241
- I = BB->getFirstNonPHIOrDbgOrLifetime ();
1242
- continue ;
1243
- }
1244
- }
1245
- }
1251
+ if (!BR || !BR->isConditional () || CondCmp != BR->getCondition ())
1252
+ return false ;
1253
+
1254
+ // And the comparsion looks like : %cond = icmp eq i8 %V, constant.
1255
+ // So we try to resolve constant for the first operand only since the
1256
+ // second operand should be literal constant by design.
1257
+ ConstantInt *Cond0 = TryResolveConstant (CondCmp->getOperand (0 ));
1258
+ auto *Cond1 = dyn_cast<ConstantInt>(CondCmp->getOperand (1 ));
1259
+ if (!Cond0 || !Cond1)
1260
+ return false ;
1261
+
1262
+ // Both operands of the CmpInst are Constant. So that we could evaluate
1263
+ // it immediately to get the destination.
1264
+ auto *ConstResult =
1265
+ dyn_cast_or_null<ConstantInt>(ConstantFoldCompareInstOperands (
1266
+ CondCmp->getPredicate (), Cond0, Cond1, DL));
1267
+ if (!ConstResult)
1268
+ return false ;
1269
+
1270
+ CondCmp->replaceAllUsesWith (ConstResult);
1271
+ CondCmp->eraseFromParent ();
1272
+
1273
+ // Handle this branch in next iteration.
1274
+ I = BR;
1275
+ continue ;
1246
1276
} else if (auto *SI = dyn_cast<SwitchInst>(I)) {
1247
- Value *V = SI->getCondition ();
1248
- auto it = ResolvedValues.find (V);
1249
- if (it != ResolvedValues.end ())
1250
- V = it->second ;
1251
- if (ConstantInt *Cond = dyn_cast<ConstantInt>(V)) {
1252
- BasicBlock *BB = SI->findCaseValue (Cond)->getCaseSuccessor ();
1253
- scanPHIsAndUpdateValueMap (I, BB, ResolvedValues);
1254
- I = BB->getFirstNonPHIOrDbgOrLifetime ();
1255
- continue ;
1256
- }
1277
+ ConstantInt *Cond = TryResolveConstant (SI->getCondition ());
1278
+ if (!Cond)
1279
+ return false ;
1280
+
1281
+ BasicBlock *BB = SI->findCaseValue (Cond)->getCaseSuccessor ();
1282
+ scanPHIsAndUpdateValueMap (I, BB, ResolvedValues);
1283
+ I = BB->getFirstNonPHIOrDbgOrLifetime ();
1284
+ continue ;
1257
1285
}
1258
1286
return false ;
1259
1287
}
0 commit comments