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"
@@ -1174,6 +1175,15 @@ scanPHIsAndUpdateValueMap(Instruction *Prev, BasicBlock *NewBlock,
1174
1175
static bool simplifyTerminatorLeadingToRet (Instruction *InitialInst) {
1175
1176
DenseMap<Value *, Value *> ResolvedValues;
1176
1177
BasicBlock *UnconditionalSucc = nullptr ;
1178
+ assert (InitialInst->getModule ());
1179
+ const DataLayout &DL = InitialInst->getModule ()->getDataLayout ();
1180
+
1181
+ auto TryResolveConstant = [&ResolvedValues](Value *V) {
1182
+ auto It = ResolvedValues.find (V);
1183
+ if (It != ResolvedValues.end ())
1184
+ V = It->second ;
1185
+ return dyn_cast<ConstantInt>(V);
1186
+ };
1177
1187
1178
1188
Instruction *I = InitialInst;
1179
1189
while (I->isTerminator () ||
@@ -1190,47 +1200,65 @@ static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) {
1190
1200
}
1191
1201
if (auto *BR = dyn_cast<BranchInst>(I)) {
1192
1202
if (BR->isUnconditional ()) {
1193
- BasicBlock *BB = BR->getSuccessor (0 );
1203
+ BasicBlock *Succ = BR->getSuccessor (0 );
1194
1204
if (I == InitialInst)
1195
- UnconditionalSucc = BB;
1196
- scanPHIsAndUpdateValueMap (I, BB, ResolvedValues);
1197
- I = BB->getFirstNonPHIOrDbgOrLifetime ();
1205
+ UnconditionalSucc = Succ;
1206
+ scanPHIsAndUpdateValueMap (I, Succ, ResolvedValues);
1207
+ I = Succ->getFirstNonPHIOrDbgOrLifetime ();
1208
+ continue ;
1209
+ }
1210
+
1211
+ BasicBlock *BB = BR->getParent ();
1212
+ // Handle the case the condition of the conditional branch is constant.
1213
+ // e.g.,
1214
+ //
1215
+ // br i1 false, label %cleanup, label %CoroEnd
1216
+ //
1217
+ // It is possible during the transformation. We could continue the
1218
+ // simplifying in this case.
1219
+ if (ConstantFoldTerminator (BB, /* DeleteDeadConditions=*/ true )) {
1220
+ // Handle this branch in next iteration.
1221
+ I = BB->getTerminator ();
1198
1222
continue ;
1199
1223
}
1200
1224
} else if (auto *CondCmp = dyn_cast<CmpInst>(I)) {
1225
+ // If the case number of suspended switch instruction is reduced to
1226
+ // 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator.
1201
1227
auto *BR = dyn_cast<BranchInst>(I->getNextNode ());
1202
- if (BR && BR->isConditional () && CondCmp == BR->getCondition ()) {
1203
- // If the case number of suspended switch instruction is reduced to
1204
- // 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator.
1205
- // And the comparsion looks like : %cond = icmp eq i8 %V, constant.
1206
- ConstantInt *CondConst = dyn_cast<ConstantInt>(CondCmp->getOperand (1 ));
1207
- if (CondConst && CondCmp->getPredicate () == CmpInst::ICMP_EQ) {
1208
- Value *V = CondCmp->getOperand (0 );
1209
- auto it = ResolvedValues.find (V);
1210
- if (it != ResolvedValues.end ())
1211
- V = it->second ;
1212
-
1213
- if (ConstantInt *Cond0 = dyn_cast<ConstantInt>(V)) {
1214
- BasicBlock *BB = Cond0->equalsInt (CondConst->getZExtValue ())
1215
- ? BR->getSuccessor (0 )
1216
- : BR->getSuccessor (1 );
1217
- scanPHIsAndUpdateValueMap (I, BB, ResolvedValues);
1218
- I = BB->getFirstNonPHIOrDbgOrLifetime ();
1219
- continue ;
1220
- }
1221
- }
1222
- }
1228
+ if (!BR || !BR->isConditional () || CondCmp != BR->getCondition ())
1229
+ return false ;
1230
+
1231
+ // And the comparsion looks like : %cond = icmp eq i8 %V, constant.
1232
+ // So we try to resolve constant for the first operand only since the
1233
+ // second operand should be literal constant by design.
1234
+ ConstantInt *Cond0 = TryResolveConstant (CondCmp->getOperand (0 ));
1235
+ auto *Cond1 = dyn_cast<ConstantInt>(CondCmp->getOperand (1 ));
1236
+ if (!Cond0 || !Cond1)
1237
+ return false ;
1238
+
1239
+ // Both operands of the CmpInst are Constant. So that we could evaluate
1240
+ // it immediately to get the destination.
1241
+ auto *ConstResult =
1242
+ dyn_cast_or_null<ConstantInt>(ConstantFoldCompareInstOperands (
1243
+ CondCmp->getPredicate (), Cond0, Cond1, DL));
1244
+ if (!ConstResult)
1245
+ return false ;
1246
+
1247
+ CondCmp->replaceAllUsesWith (ConstResult);
1248
+ CondCmp->eraseFromParent ();
1249
+
1250
+ // Handle this branch in next iteration.
1251
+ I = BR;
1252
+ continue ;
1223
1253
} else if (auto *SI = dyn_cast<SwitchInst>(I)) {
1224
- Value *V = SI->getCondition ();
1225
- auto it = ResolvedValues.find (V);
1226
- if (it != ResolvedValues.end ())
1227
- V = it->second ;
1228
- if (ConstantInt *Cond = dyn_cast<ConstantInt>(V)) {
1229
- BasicBlock *BB = SI->findCaseValue (Cond)->getCaseSuccessor ();
1230
- scanPHIsAndUpdateValueMap (I, BB, ResolvedValues);
1231
- I = BB->getFirstNonPHIOrDbgOrLifetime ();
1232
- continue ;
1233
- }
1254
+ ConstantInt *Cond = TryResolveConstant (SI->getCondition ());
1255
+ if (!Cond)
1256
+ return false ;
1257
+
1258
+ BasicBlock *BB = SI->findCaseValue (Cond)->getCaseSuccessor ();
1259
+ scanPHIsAndUpdateValueMap (I, BB, ResolvedValues);
1260
+ I = BB->getFirstNonPHIOrDbgOrLifetime ();
1261
+ continue ;
1234
1262
}
1235
1263
return false ;
1236
1264
}
0 commit comments