llvm-project/llvm/lib/IR/CFG.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

57 lines
1.7 KiB
C++
Raw Normal View History

Introduce CfgTraits abstraction The CfgTraits abstraction simplfies writing algorithms that are generic over the type of CFG, and enables writing such algorithms as regular non-template code that operates on opaque references to CFG blocks and values. Implementations of CfgTraits provide operations on the concrete CFG types, e.g. `IrCfgTraits::BlockRef` is `BasicBlock *`. CfgInterface is an abstract base class which provides operations on opaque types CfgBlockRef and CfgValueRef. Those opaque types encapsulate a `void *`, but the meaning depends on the concrete CFG type. For example, MachineCfgTraits -- for use with MachineIR in SSA form -- encodes a Register inside CfgValueRef. Converting between concrete references and opaque/generic ones is done by CfgTraits::{fromGeneric,toGeneric}. Convenience methods CfgTraits::{un}wrap{Iterator,Range} are available as well. Writing algorithms in terms of CfgInterface adds some overhead (virtual method calls, plus in same cases it removes the opportunity to inline iterators), but can be much more convenient since generic algorithms can be written as non-templates. This patch adds implementations of CfgTraits for all CFGs on which dominator trees are calculated, so that the dominator tree can be ported to this machinery. Only IrCfgTraits (LLVM IR) and MachineCfgTraits (Machine IR in SSA form) are complete, the other implementations are limited to the absolute minimum required to make the upcoming dominator tree changes work. v5: - fix MachineCfgTraits::blockdef_iterator and allow it to iterate over the instructions in a bundle - use MachineBasicBlock::printName v6: - implement predecessors/successors for all CfgTraits implementations - fix error in unwrapRange - rename toGeneric/fromGeneric into wrapRef/unwrapRef to have naming that is consistent with {wrap,unwrap}{Iterator,Range} - use getVRegDef instead of getUniqueVRegDef v7: - std::forward fix in wrapping_iterator - fix typos v8: - cleanup operators on CfgOpaqueType - address other review comments Change-Id: Ia75f4f268fded33fca11218a7d578c9aec1f3f4d Differential Revision: https://reviews.llvm.org/D83088
2020-10-20 19:50:52 +08:00
//===- CFG.cpp --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/CFG.h"
#include "llvm/IR/ModuleSlotTracker.h"
using namespace llvm;
IrCfgTraits::Printer::Printer(const IrCfgTraits &) {}
IrCfgTraits::Printer::~Printer() {}
void IrCfgTraits::Printer::printValue(raw_ostream &out, ValueRef value) const {
if (!m_moduleSlotTracker) {
const Function *function = nullptr;
if (auto *instruction = dyn_cast<Instruction>(value)) {
function = instruction->getParent()->getParent();
} else if (auto *argument = dyn_cast<Argument>(value)) {
function = argument->getParent();
}
if (function)
ensureModuleSlotTracker(*function);
}
if (m_moduleSlotTracker) {
value->print(out, *m_moduleSlotTracker, true);
} else {
value->print(out, true);
}
}
void IrCfgTraits::Printer::printBlockName(raw_ostream &out,
BlockRef block) const {
if (block->hasName()) {
out << block->getName();
} else {
ensureModuleSlotTracker(*block->getParent());
out << m_moduleSlotTracker->getLocalSlot(block);
}
}
void IrCfgTraits::Printer::ensureModuleSlotTracker(
const Function &function) const {
if (!m_moduleSlotTracker) {
m_moduleSlotTracker =
std::make_unique<ModuleSlotTracker>(function.getParent(), false);
m_moduleSlotTracker->incorporateFunction(function);
}
}