mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-13 22:00:42 +02:00
It is not an external component, and it makes paths needlessly long. Ryan seemed amenable to this when we discussed on IRC earlier. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
78 lines
1.9 KiB
C++
78 lines
1.9 KiB
C++
/*
|
|
$info$
|
|
tags: ir|opts
|
|
desc: Sanity checking pass
|
|
$end_info$
|
|
*/
|
|
|
|
#include <FEXCore/IR/IR.h>
|
|
#include <FEXCore/IR/IREmitter.h>
|
|
#include <FEXCore/IR/IntrusiveIRList.h>
|
|
#include <FEXCore/Utils/LogManager.h>
|
|
#include <FEXCore/Utils/Profiler.h>
|
|
#include <FEXCore/fextl/sstream.h>
|
|
|
|
#include "Interface/IR/PassManager.h"
|
|
|
|
#include <memory>
|
|
|
|
namespace FEXCore::IR::Validation {
|
|
|
|
class PhiValidation final : public FEXCore::IR::Pass {
|
|
public:
|
|
bool Run(IREmitter *IREmit) override;
|
|
};
|
|
|
|
bool PhiValidation::Run(IREmitter *IREmit) {
|
|
FEXCORE_PROFILE_SCOPED("PassManager::PHIValidation");
|
|
|
|
bool HadError = false;
|
|
auto CurrentIR = IREmit->ViewIR();
|
|
|
|
fextl::ostringstream Errors;
|
|
|
|
// Walk the list and calculate the control flow
|
|
for (auto [BlockNode, BlockHeader] : CurrentIR.GetBlocks()) {
|
|
|
|
bool FoundNonPhi{};
|
|
|
|
for (auto [CodeNode, IROp] : CurrentIR.GetCode(BlockNode)) {
|
|
|
|
switch (IROp->Op) {
|
|
// BEGINBLOCK doesn't matter for us
|
|
case IR::OP_BEGINBLOCK: break;
|
|
case IR::OP_PHIVALUE:
|
|
case IR::OP_PHI: {
|
|
if (FoundNonPhi) {
|
|
// If we have found a non-phi IR op and then had a Phi or PhiValue value then this is a programming mistake
|
|
// PHI values MUST be defined at the top of the block only
|
|
HadError |= true;
|
|
Errors << "Phi %" << CurrentIR.GetID(CodeNode) << ": Was defined after non-phi operations. Which is invalid!" << std::endl;
|
|
}
|
|
|
|
// Check all the phi values to ensure they have the same type
|
|
break;
|
|
}
|
|
default:
|
|
FoundNonPhi = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (HadError) {
|
|
fextl::stringstream Out;
|
|
FEXCore::IR::Dump(&Out, &CurrentIR, nullptr);
|
|
Out << "Errors:" << std::endl << Errors.str() << std::endl;
|
|
LogMan::Msg::EFmt("{}", Out.str());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
fextl::unique_ptr<FEXCore::IR::Pass> CreatePhiValidation() {
|
|
return fextl::make_unique<PhiValidation>();
|
|
}
|
|
|
|
}
|