aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/MIR/ReachingDefPrinter.cpp
blob: 5687590d20bfab0c2f6da96c746d5f7af4b53966 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// SPDX-License-Identifier: GPL-3.0-or-later

#include "rcc/MIR/ReachingDefPrinter.h"

#include "rcc/CodeGen/MIRPrinter.h"
#include "rcc/CodeGen/MachineBasicBlock.h"
#include "rcc/CodeGen/MachineFunction.h"
#include "rcc/CodeGen/MachineInstr.h"
#include "rcc/CodeGen/MachineOperand.h"
#include "rcc/CodeGen/ReachingDefAnalysis.h"

#include <iostream>
#include <optional>

namespace rcc::mir {

const MachinePassContract &ReachingDefPrinterPass::contract() const noexcept {
  static const MachinePassContract Contract = [] {
    MachinePassContract Value{
        .Name = std::string(name()),
        .Requires = {MachineFunctionProperty::NoVRegs},
        .Sets = {},
        .Clears = {},
        .RequiredAnalyses = {MachineFunctionAnalysisManager::id<ReachingDefAnalysis>()},
        .VerificationStage = std::nullopt,
    };
    Value.DeclaredChanges = {};
    return Value;
  }();
  return Contract;
}

Expected<MachinePassResult> ReachingDefPrinterPass::run(MachineFunction &Function,
                                                        const TargetDescription &Target,
                                                        MachineFunctionAnalysisManager &Analyses) {
  auto ReachingDefinitions = Analyses.getResult<ReachingDefAnalysis>(Function, Target);
  if (!ReachingDefinitions)
    return std::unexpected(ReachingDefinitions.error());
  auto Context = createMachineFunctionPrintContext(Function);
  if (!Context)
    return std::unexpected(Context.error());

  std::cerr << "Reaching definitions for for machine function: " << Function.name() << '\n';
  for (MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr; Block = Block->next()) {
    std::cerr << "%bb." << Block->denseNumber().value_or(0) << ":\n";
    for (MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;
         Instruction = Instruction->next()) {
      for (const MachineOperand &Operand : Instruction->operands()) {
        if (Operand.isRegister()) {
          const std::optional<Register> Reg = Operand.registerValue();
          if (Operand.isDef() || !Reg || Reg->isNoRegister())
            continue;
        } else if (Operand.kind() != MachineOperand::Kind::FrameIndex) {
          continue;
        }

        auto PrintedOperand = printMachineOperand(Operand, Target, *Context);
        if (!PrintedOperand)
          return std::unexpected(PrintedOperand.error());
        std::cerr << *PrintedOperand << ":{ ";
        for (const MachineInstr *Definition :
             (*ReachingDefinitions)->reachingDefinitions(Operand)) {
          std::cerr << (*ReachingDefinitions)->instructionNumber(*Definition) << ' ';
        }
        std::cerr << "}\n";
      }

      auto PrintedInstruction = printMachineInstruction(*Instruction, Target, *Context);
      if (!PrintedInstruction)
        return std::unexpected(PrintedInstruction.error());
      std::cerr << (*ReachingDefinitions)->instructionNumber(*Instruction) << ": "
                << *PrintedInstruction << "\n\n";
    }
  }

  MachinePassResult Result;
  Result.Preserved = PreservedAnalyses::all();
  return Result;
}

} // namespace rcc::mir