diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Float2Int.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/Float2Int.cpp | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp index 6b04d2c..d781cc0 100644 --- a/llvm/lib/Transforms/Scalar/Float2Int.cpp +++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp @@ -235,14 +235,17 @@ void Float2IntPass::walkBackwards() { } } -// Calculate result range from operand ranges -ConstantRange Float2IntPass::calcRange(Instruction *I) { +// Calculate result range from operand ranges. +// Return None if the range cannot be calculated yet. +Optional<ConstantRange> Float2IntPass::calcRange(Instruction *I) { SmallVector<ConstantRange, 4> OpRanges; for (Value *O : I->operands()) { if (Instruction *OI = dyn_cast<Instruction>(O)) { - assert(SeenInsts.find(OI) != SeenInsts.end() && - "def not seen before use!"); - OpRanges.push_back(SeenInsts.find(OI)->second); + auto OpIt = SeenInsts.find(OI); + assert(OpIt != SeenInsts.end() && "def not seen before use!"); + if (OpIt->second == unknownRange()) + return None; // Wait until operand range has been calculated. + OpRanges.push_back(OpIt->second); } else if (ConstantFP *CF = dyn_cast<ConstantFP>(O)) { // Work out if the floating point number can be losslessly represented // as an integer. @@ -324,12 +327,19 @@ ConstantRange Float2IntPass::calcRange(Instruction *I) { // Walk forwards down the list of seen instructions, so we visit defs before // uses. void Float2IntPass::walkForwards() { - for (auto &It : reverse(SeenInsts)) { - if (It.second != unknownRange()) - continue; + std::deque<Instruction *> Worklist; + for (const auto &Pair : SeenInsts) + if (Pair.second == unknownRange()) + Worklist.push_back(Pair.first); + + while (!Worklist.empty()) { + Instruction *I = Worklist.back(); + Worklist.pop_back(); - Instruction *I = It.first; - seen(I, calcRange(I)); + if (Optional<ConstantRange> Range = calcRange(I)) + seen(I, *Range); + else + Worklist.push_front(I); // Reprocess later. } } |