2018-09-21 14:40:36 -07:00
|
|
|
//===- Dominance.cpp - Dominator analysis for CFG Functions ---------------===//
|
|
|
|
//
|
|
|
|
// Copyright 2019 The MLIR Authors.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
// =============================================================================
|
|
|
|
//
|
|
|
|
// Implementation of dominance related classes and instantiations of extern
|
|
|
|
// templates.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "mlir/Analysis/Dominance.h"
|
2018-12-27 11:07:34 -08:00
|
|
|
#include "mlir/IR/Statements.h"
|
2018-09-21 14:40:36 -07:00
|
|
|
#include "llvm/Support/GenericDomTreeConstruction.h"
|
|
|
|
using namespace mlir;
|
|
|
|
|
|
|
|
template class llvm::DominatorTreeBase<BasicBlock, false>;
|
|
|
|
template class llvm::DominatorTreeBase<BasicBlock, true>;
|
|
|
|
template class llvm::DomTreeNodeBase<BasicBlock>;
|
|
|
|
|
|
|
|
/// Compute the immediate-dominators map.
|
2018-12-28 08:48:09 -08:00
|
|
|
DominanceInfo::DominanceInfo(Function *function) : DominatorTreeBase() {
|
2018-09-21 14:40:36 -07:00
|
|
|
// Build the dominator tree for the function.
|
2018-12-27 11:07:34 -08:00
|
|
|
recalculate(function->getBlockList());
|
2018-09-21 14:40:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return true if instruction A properly dominates instruction B.
|
|
|
|
bool DominanceInfo::properlyDominates(const Instruction *a,
|
|
|
|
const Instruction *b) {
|
|
|
|
auto *aBlock = a->getBlock(), *bBlock = b->getBlock();
|
|
|
|
|
|
|
|
// If the blocks are different, it's as easy as whether A's block
|
|
|
|
// dominates B's block.
|
|
|
|
if (aBlock != bBlock)
|
|
|
|
return properlyDominates(a->getBlock(), b->getBlock());
|
|
|
|
|
|
|
|
// If a/b are the same, then they don't properly dominate each other.
|
|
|
|
if (a == b)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// If one is a terminator, then the other dominates it.
|
2018-11-15 18:31:15 -08:00
|
|
|
if (a->isTerminator())
|
2018-09-21 14:40:36 -07:00
|
|
|
return false;
|
|
|
|
|
2018-11-15 18:31:15 -08:00
|
|
|
if (b->isTerminator())
|
2018-09-21 14:40:36 -07:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// Otherwise, do a linear scan to determine whether B comes after A.
|
2018-11-15 18:31:15 -08:00
|
|
|
auto aIter = BasicBlock::const_iterator(a);
|
|
|
|
auto bIter = BasicBlock::const_iterator(b);
|
2018-09-21 14:40:36 -07:00
|
|
|
auto fIter = aBlock->begin();
|
|
|
|
while (bIter != fIter) {
|
|
|
|
--bIter;
|
|
|
|
if (aIter == bIter)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return true if value A properly dominates instruction B.
|
2018-12-27 14:35:10 -08:00
|
|
|
bool DominanceInfo::properlyDominates(const Value *a, const Instruction *b) {
|
2018-09-21 14:40:36 -07:00
|
|
|
if (auto *aInst = a->getDefiningInst())
|
|
|
|
return properlyDominates(aInst, b);
|
|
|
|
|
|
|
|
// bbarguments properly dominate all instructions in their own block, so we
|
|
|
|
// use a dominates check here, not a properlyDominates check.
|
2018-12-28 04:14:52 -08:00
|
|
|
return dominates(cast<BlockArgument>(a)->getOwner(), b->getBlock());
|
2018-09-21 14:40:36 -07:00
|
|
|
}
|