|
20 | 20 | #include "llvm/Analysis/ValueLatticeUtils.h" |
21 | 21 | #include "llvm/Analysis/ValueTracking.h" |
22 | 22 | #include "llvm/IR/ConstantRange.h" |
| 23 | +#include "llvm/IR/DerivedTypes.h" |
23 | 24 | #include "llvm/IR/IRBuilder.h" |
24 | 25 | #include "llvm/IR/InstVisitor.h" |
25 | 26 | #include "llvm/IR/Instructions.h" |
@@ -768,6 +769,7 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> { |
768 | 769 | void handleCallArguments(CallBase &CB); |
769 | 770 | void handleExtractOfWithOverflow(ExtractValueInst &EVI, |
770 | 771 | const WithOverflowInst *WO, unsigned Idx); |
| 772 | + bool isInstUnderDefined(Instruction &Inst); |
771 | 773 |
|
772 | 774 | private: |
773 | 775 | friend class InstVisitor<SCCPInstVisitor>; |
@@ -1383,49 +1385,65 @@ bool SCCPInstVisitor::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const { |
1383 | 1385 | // 7. If a conditional branch has a value that is overdefined, make all |
1384 | 1386 | // successors executable. |
1385 | 1387 | void SCCPInstVisitor::visitPHINode(PHINode &PN) { |
1386 | | - // If this PN returns a struct, just mark the result overdefined. |
1387 | | - // TODO: We could do a lot better than this if code actually uses this. |
1388 | | - if (PN.getType()->isStructTy()) |
1389 | | - return (void)markOverdefined(&PN); |
1390 | | - |
1391 | | - if (getValueState(&PN).isOverdefined()) |
1392 | | - return; // Quick exit |
1393 | | - |
1394 | 1388 | // Super-extra-high-degree PHI nodes are unlikely to ever be marked constant, |
1395 | 1389 | // and slow us down a lot. Just mark them overdefined. |
1396 | 1390 | if (PN.getNumIncomingValues() > 64) |
1397 | 1391 | return (void)markOverdefined(&PN); |
1398 | 1392 |
|
1399 | | - unsigned NumActiveIncoming = 0; |
| 1393 | + if (isInstUnderDefined(PN)) |
| 1394 | + return; |
| 1395 | + llvm::SmallVector<unsigned> FeasibleIncomingIndices; |
| 1396 | + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { |
| 1397 | + if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) |
| 1398 | + continue; |
| 1399 | + FeasibleIncomingIndices.push_back(i); |
| 1400 | + } |
1400 | 1401 |
|
1401 | 1402 | // Look at all of the executable operands of the PHI node. If any of them |
1402 | 1403 | // are overdefined, the PHI becomes overdefined as well. If they are all |
1403 | 1404 | // constant, and they agree with each other, the PHI becomes the identical |
1404 | 1405 | // constant. If they are constant and don't agree, the PHI is a constant |
1405 | 1406 | // range. If there are no executable operands, the PHI remains unknown. |
1406 | | - ValueLatticeElement PhiState = getValueState(&PN); |
1407 | | - for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { |
1408 | | - if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) |
1409 | | - continue; |
1410 | | - |
1411 | | - ValueLatticeElement IV = getValueState(PN.getIncomingValue(i)); |
1412 | | - PhiState.mergeIn(IV); |
1413 | | - NumActiveIncoming++; |
1414 | | - if (PhiState.isOverdefined()) |
1415 | | - break; |
| 1407 | + if (StructType *STy = dyn_cast<StructType>(PN.getType())) { |
| 1408 | + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { |
| 1409 | + ValueLatticeElement PhiState = getStructValueState(&PN, i); |
| 1410 | + if (PhiState.isOverdefined()) |
| 1411 | + continue; |
| 1412 | + for (unsigned j : FeasibleIncomingIndices) { |
| 1413 | + ValueLatticeElement IV = getStructValueState(PN.getIncomingValue(j), i); |
| 1414 | + PhiState.mergeIn(IV); |
| 1415 | + if (PhiState.isOverdefined()) |
| 1416 | + break; |
| 1417 | + } |
| 1418 | + mergeInValue(getStructValueState(&PN, i), &PN, PhiState, |
| 1419 | + ValueLatticeElement::MergeOptions().setMaxWidenSteps( |
| 1420 | + FeasibleIncomingIndices.size() + 1)); |
| 1421 | + ValueLatticeElement &PhiStateRef = getStructValueState(&PN, i); |
| 1422 | + PhiStateRef.setNumRangeExtensions( |
| 1423 | + std::max((unsigned)FeasibleIncomingIndices.size(), |
| 1424 | + PhiStateRef.getNumRangeExtensions())); |
| 1425 | + } |
| 1426 | + } else { |
| 1427 | + ValueLatticeElement PhiState = getValueState(&PN); |
| 1428 | + for (unsigned i : FeasibleIncomingIndices) { |
| 1429 | + ValueLatticeElement IV = getValueState(PN.getIncomingValue(i)); |
| 1430 | + PhiState.mergeIn(IV); |
| 1431 | + if (PhiState.isOverdefined()) |
| 1432 | + break; |
| 1433 | + } |
| 1434 | + // We allow up to 1 range extension per active incoming value and one |
| 1435 | + // additional extension. Note that we manually adjust the number of range |
| 1436 | + // extensions to match the number of active incoming values. This helps to |
| 1437 | + // limit multiple extensions caused by the same incoming value, if other |
| 1438 | + // incoming values are equal. |
| 1439 | + mergeInValue(&PN, PhiState, |
| 1440 | + ValueLatticeElement::MergeOptions().setMaxWidenSteps( |
| 1441 | + FeasibleIncomingIndices.size() + 1)); |
| 1442 | + ValueLatticeElement &PhiStateRef = getValueState(&PN); |
| 1443 | + PhiStateRef.setNumRangeExtensions( |
| 1444 | + std::max((unsigned)FeasibleIncomingIndices.size(), |
| 1445 | + PhiStateRef.getNumRangeExtensions())); |
1416 | 1446 | } |
1417 | | - |
1418 | | - // We allow up to 1 range extension per active incoming value and one |
1419 | | - // additional extension. Note that we manually adjust the number of range |
1420 | | - // extensions to match the number of active incoming values. This helps to |
1421 | | - // limit multiple extensions caused by the same incoming value, if other |
1422 | | - // incoming values are equal. |
1423 | | - mergeInValue(&PN, PhiState, |
1424 | | - ValueLatticeElement::MergeOptions().setMaxWidenSteps( |
1425 | | - NumActiveIncoming + 1)); |
1426 | | - ValueLatticeElement &PhiStateRef = getValueState(&PN); |
1427 | | - PhiStateRef.setNumRangeExtensions( |
1428 | | - std::max(NumActiveIncoming, PhiStateRef.getNumRangeExtensions())); |
1429 | 1447 | } |
1430 | 1448 |
|
1431 | 1449 | void SCCPInstVisitor::visitReturnInst(ReturnInst &I) { |
@@ -2125,6 +2143,21 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) { |
2125 | 2143 | } |
2126 | 2144 | } |
2127 | 2145 |
|
| 2146 | +bool SCCPInstVisitor::isInstUnderDefined(Instruction &Inst) { |
| 2147 | + // For structure Type, we handle each member seperately. |
| 2148 | + // A structure object won't be considered as overDefined when |
| 2149 | + // there is at least one member can become constant. |
| 2150 | + if (StructType *STy = dyn_cast<StructType>(Inst.getType())) { |
| 2151 | + for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i) { |
| 2152 | + if (!getStructValueState(&Inst, i).isOverdefined()) |
| 2153 | + return false; |
| 2154 | + } |
| 2155 | + return true; |
| 2156 | + } |
| 2157 | + |
| 2158 | + return getValueState(&Inst).isOverdefined(); |
| 2159 | +} |
| 2160 | + |
2128 | 2161 | void SCCPInstVisitor::solve() { |
2129 | 2162 | // Process the work lists until they are empty! |
2130 | 2163 | while (!BBWorkList.empty() || !InstWorkList.empty()) { |
|
0 commit comments