mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-30 08:06:06 +00:00

Uniformity analysis is a generalization of divergence analysis to include irreducible control flow: 1. The proposed spec presents a notion of "maximal convergence" that captures the existing convention of converging threads at the headers of natual loops. 2. Maximal convergence is then extended to irreducible cycles. The identity of irreducible cycles is determined by the choices made in a depth-first traversal of the control flow graph. Uniformity analysis uses criteria that depend only on closed paths and not cycles, to determine maximal convergence. This makes it a conservative analysis that is independent of the effect of DFS on CycleInfo. 3. The analysis is implemented as a template that can be instantiated for both LLVM IR and Machine IR. Validation: - passes existing tests for divergence analysis - passes new tests with irreducible control flow - passes equivalent tests in MIR and GMIR Based on concepts originally outlined by Nicolai Haehnle <nicolai.haehnle@amd.com> With contributions from Ruiling Song <ruiling.song@amd.com> and Jay Foad <jay.foad@amd.com>. Support for GMIR and lit tests for GMIR/MIR added by Yashwant Singh <yashwant.singh@amd.com>. Differential Revision: https://reviews.llvm.org/D130746
87 lines
2.6 KiB
C++
87 lines
2.6 KiB
C++
//===- MachineSSAContext.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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
/// \file
|
|
///
|
|
/// This file defines a specialization of the GenericSSAContext<X>
|
|
/// template class for Machine IR.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/MachineSSAContext.h"
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace llvm;
|
|
|
|
const Register MachineSSAContext::ValueRefNull{};
|
|
|
|
void MachineSSAContext::setFunction(MachineFunction &Fn) {
|
|
MF = &Fn;
|
|
RegInfo = &MF->getRegInfo();
|
|
}
|
|
|
|
MachineBasicBlock *MachineSSAContext::getEntryBlock(MachineFunction &F) {
|
|
return &F.front();
|
|
}
|
|
|
|
void MachineSSAContext::appendBlockTerms(
|
|
SmallVectorImpl<const MachineInstr *> &terms,
|
|
const MachineBasicBlock &block) {
|
|
for (auto &T : block.terminators())
|
|
terms.push_back(&T);
|
|
}
|
|
|
|
void MachineSSAContext::appendBlockDefs(SmallVectorImpl<Register> &defs,
|
|
const MachineBasicBlock &block) {
|
|
for (const MachineInstr &instr : block.instrs()) {
|
|
for (const MachineOperand &op : instr.operands()) {
|
|
if (op.isReg() && op.isDef())
|
|
defs.push_back(op.getReg());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Get the defining block of a value.
|
|
MachineBasicBlock *MachineSSAContext::getDefBlock(Register value) const {
|
|
if (!value)
|
|
return nullptr;
|
|
return RegInfo->getVRegDef(value)->getParent();
|
|
}
|
|
|
|
bool MachineSSAContext::isConstantValuePhi(const MachineInstr &Phi) {
|
|
return Phi.isConstantValuePHI();
|
|
}
|
|
|
|
Printable MachineSSAContext::print(const MachineBasicBlock *Block) const {
|
|
if (!Block)
|
|
return Printable([](raw_ostream &Out) { Out << "<nullptr>"; });
|
|
return Printable([Block](raw_ostream &Out) { Block->printName(Out); });
|
|
}
|
|
|
|
Printable MachineSSAContext::print(const MachineInstr *I) const {
|
|
return Printable([I](raw_ostream &Out) { I->print(Out); });
|
|
}
|
|
|
|
Printable MachineSSAContext::print(Register Value) const {
|
|
auto *MRI = RegInfo;
|
|
return Printable([MRI, Value](raw_ostream &Out) {
|
|
Out << printReg(Value, MRI->getTargetRegisterInfo(), 0, MRI);
|
|
|
|
if (Value) {
|
|
// Try to print the definition.
|
|
if (auto *Instr = MRI->getUniqueVRegDef(Value)) {
|
|
Out << ": ";
|
|
Instr->print(Out);
|
|
}
|
|
}
|
|
});
|
|
}
|