Bug Summary

File:src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
Warning:line 35, column 40
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name Legalizer.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Analysis -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ASMParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/BinaryFormat -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitstream -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /include/llvm/CodeGen -I /include/llvm/CodeGen/PBQP -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Coroutines -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData/Coverage -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/CodeView -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/DWARF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/MSF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/PDB -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Demangle -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/JITLink -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/Orc -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenACC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenMP -I /include/llvm/CodeGen/GlobalISel -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IRReader -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/LTO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Linker -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC/MCParser -I /include/llvm/CodeGen/MIRParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Object -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Option -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Passes -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Scalar -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ADT -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Support -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/Symbolize -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Target -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Utils -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Vectorize -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/IPO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libLLVM/../include -I /usr/src/gnu/usr.bin/clang/libLLVM/obj -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -D PIC -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -D_RET_PROTECTOR -ret-protector -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp

/usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp

1//===-- llvm/CodeGen/GlobalISel/Legalizer.cpp -----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file This file implements the LegalizerHelper class to legalize individual
10/// instructions and the LegalizePass wrapper pass for the primary
11/// legalization.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/CodeGen/GlobalISel/Legalizer.h"
16#include "llvm/ADT/PostOrderIterator.h"
17#include "llvm/ADT/SetVector.h"
18#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
19#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
20#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
21#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
22#include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
23#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
24#include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
25#include "llvm/CodeGen/GlobalISel/Utils.h"
26#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
27#include "llvm/CodeGen/MachineRegisterInfo.h"
28#include "llvm/CodeGen/TargetPassConfig.h"
29#include "llvm/CodeGen/TargetSubtargetInfo.h"
30#include "llvm/InitializePasses.h"
31#include "llvm/Support/Debug.h"
32#include "llvm/Support/Error.h"
33#include "llvm/Target/TargetMachine.h"
34
35#include <iterator>
36
37#define DEBUG_TYPE"legalizer" "legalizer"
38
39using namespace llvm;
40
41static cl::opt<bool>
42 EnableCSEInLegalizer("enable-cse-in-legalizer",
43 cl::desc("Should enable CSE in Legalizer"),
44 cl::Optional, cl::init(false));
45
46// This is a temporary hack, should be removed soon.
47static cl::opt<bool> AllowGInsertAsArtifact(
48 "allow-ginsert-as-artifact",
49 cl::desc("Allow G_INSERT to be considered an artifact. Hack around AMDGPU "
50 "test infinite loops."),
51 cl::Optional, cl::init(true));
52
53enum class DebugLocVerifyLevel {
54 None,
55 Legalizations,
56 LegalizationsAndArtifactCombiners,
57};
58#ifndef NDEBUG1
59static cl::opt<DebugLocVerifyLevel> VerifyDebugLocs(
60 "verify-legalizer-debug-locs",
61 cl::desc("Verify that debug locations are handled"),
62 cl::values(
63 clEnumValN(DebugLocVerifyLevel::None, "none", "No verification")llvm::cl::OptionEnumValue { "none", int(DebugLocVerifyLevel::
None), "No verification" }
,
64 clEnumValN(DebugLocVerifyLevel::Legalizations, "legalizations",llvm::cl::OptionEnumValue { "legalizations", int(DebugLocVerifyLevel
::Legalizations), "Verify legalizations" }
65 "Verify legalizations")llvm::cl::OptionEnumValue { "legalizations", int(DebugLocVerifyLevel
::Legalizations), "Verify legalizations" }
,
66 clEnumValN(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners,llvm::cl::OptionEnumValue { "legalizations+artifactcombiners"
, int(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners)
, "Verify legalizations and artifact combines" }
67 "legalizations+artifactcombiners",llvm::cl::OptionEnumValue { "legalizations+artifactcombiners"
, int(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners)
, "Verify legalizations and artifact combines" }
68 "Verify legalizations and artifact combines")llvm::cl::OptionEnumValue { "legalizations+artifactcombiners"
, int(DebugLocVerifyLevel::LegalizationsAndArtifactCombiners)
, "Verify legalizations and artifact combines" }
),
69 cl::init(DebugLocVerifyLevel::Legalizations));
70#else
71// Always disable it for release builds by preventing the observer from being
72// installed.
73static const DebugLocVerifyLevel VerifyDebugLocs = DebugLocVerifyLevel::None;
74#endif
75
76char Legalizer::ID = 0;
77INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,static void *initializeLegalizerPassOnce(PassRegistry &Registry
) {
78 "Legalize the Machine IR a function's Machine IR", false,static void *initializeLegalizerPassOnce(PassRegistry &Registry
) {
79 false)static void *initializeLegalizerPassOnce(PassRegistry &Registry
) {
80INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)initializeTargetPassConfigPass(Registry);
81INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)initializeGISelCSEAnalysisWrapperPassPass(Registry);
82INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,PassInfo *PI = new PassInfo( "Legalize the Machine IR a function's Machine IR"
, "legalizer", &Legalizer::ID, PassInfo::NormalCtor_t(callDefaultCtor
<Legalizer>), false, false); Registry.registerPass(*PI,
true); return PI; } static llvm::once_flag InitializeLegalizerPassFlag
; void llvm::initializeLegalizerPass(PassRegistry &Registry
) { llvm::call_once(InitializeLegalizerPassFlag, initializeLegalizerPassOnce
, std::ref(Registry)); }
83 "Legalize the Machine IR a function's Machine IR", false,PassInfo *PI = new PassInfo( "Legalize the Machine IR a function's Machine IR"
, "legalizer", &Legalizer::ID, PassInfo::NormalCtor_t(callDefaultCtor
<Legalizer>), false, false); Registry.registerPass(*PI,
true); return PI; } static llvm::once_flag InitializeLegalizerPassFlag
; void llvm::initializeLegalizerPass(PassRegistry &Registry
) { llvm::call_once(InitializeLegalizerPassFlag, initializeLegalizerPassOnce
, std::ref(Registry)); }
84 false)PassInfo *PI = new PassInfo( "Legalize the Machine IR a function's Machine IR"
, "legalizer", &Legalizer::ID, PassInfo::NormalCtor_t(callDefaultCtor
<Legalizer>), false, false); Registry.registerPass(*PI,
true); return PI; } static llvm::once_flag InitializeLegalizerPassFlag
; void llvm::initializeLegalizerPass(PassRegistry &Registry
) { llvm::call_once(InitializeLegalizerPassFlag, initializeLegalizerPassOnce
, std::ref(Registry)); }
85
86Legalizer::Legalizer() : MachineFunctionPass(ID) { }
87
88void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
89 AU.addRequired<TargetPassConfig>();
90 AU.addRequired<GISelCSEAnalysisWrapperPass>();
91 AU.addPreserved<GISelCSEAnalysisWrapperPass>();
92 getSelectionDAGFallbackAnalysisUsage(AU);
93 MachineFunctionPass::getAnalysisUsage(AU);
94}
95
96void Legalizer::init(MachineFunction &MF) {
97}
98
99static bool isArtifact(const MachineInstr &MI) {
100 switch (MI.getOpcode()) {
101 default:
102 return false;
103 case TargetOpcode::G_TRUNC:
104 case TargetOpcode::G_ZEXT:
105 case TargetOpcode::G_ANYEXT:
106 case TargetOpcode::G_SEXT:
107 case TargetOpcode::G_MERGE_VALUES:
108 case TargetOpcode::G_UNMERGE_VALUES:
109 case TargetOpcode::G_CONCAT_VECTORS:
110 case TargetOpcode::G_BUILD_VECTOR:
111 case TargetOpcode::G_EXTRACT:
112 return true;
113 case TargetOpcode::G_INSERT:
114 return AllowGInsertAsArtifact;
115 }
116}
117using InstListTy = GISelWorkList<256>;
118using ArtifactListTy = GISelWorkList<128>;
119
120namespace {
121class LegalizerWorkListManager : public GISelChangeObserver {
122 InstListTy &InstList;
123 ArtifactListTy &ArtifactList;
124#ifndef NDEBUG1
125 SmallVector<MachineInstr *, 4> NewMIs;
126#endif
127
128public:
129 LegalizerWorkListManager(InstListTy &Insts, ArtifactListTy &Arts)
130 : InstList(Insts), ArtifactList(Arts) {}
131
132 void createdOrChangedInstr(MachineInstr &MI) {
133 // Only legalize pre-isel generic instructions.
134 // Legalization process could generate Target specific pseudo
135 // instructions with generic types. Don't record them
136 if (isPreISelGenericOpcode(MI.getOpcode())) {
137 if (isArtifact(MI))
138 ArtifactList.insert(&MI);
139 else
140 InstList.insert(&MI);
141 }
142 }
143
144 void createdInstr(MachineInstr &MI) override {
145 LLVM_DEBUG(NewMIs.push_back(&MI))do { } while (false);
146 createdOrChangedInstr(MI);
147 }
148
149 void printNewInstrs() {
150 LLVM_DEBUG({do { } while (false)
151 for (const auto *MI : NewMIs)do { } while (false)
152 dbgs() << ".. .. New MI: " << *MI;do { } while (false)
153 NewMIs.clear();do { } while (false)
154 })do { } while (false);
155 }
156
157 void erasingInstr(MachineInstr &MI) override {
158 LLVM_DEBUG(dbgs() << ".. .. Erasing: " << MI)do { } while (false);
159 InstList.remove(&MI);
160 ArtifactList.remove(&MI);
161 }
162
163 void changingInstr(MachineInstr &MI) override {
164 LLVM_DEBUG(dbgs() << ".. .. Changing MI: " << MI)do { } while (false);
165 }
166
167 void changedInstr(MachineInstr &MI) override {
168 // When insts change, we want to revisit them to legalize them again.
169 // We'll consider them the same as created.
170 LLVM_DEBUG(dbgs() << ".. .. Changed MI: " << MI)do { } while (false);
171 createdOrChangedInstr(MI);
172 }
173};
174} // namespace
175
176Legalizer::MFResult
177Legalizer::legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
178 ArrayRef<GISelChangeObserver *> AuxObservers,
179 LostDebugLocObserver &LocObserver,
180 MachineIRBuilder &MIRBuilder) {
181 MIRBuilder.setMF(MF);
182 MachineRegisterInfo &MRI = MF.getRegInfo();
183
184 // Populate worklists.
185 InstListTy InstList;
186 ArtifactListTy ArtifactList;
187 ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
188 // Perform legalization bottom up so we can DCE as we legalize.
189 // Traverse BB in RPOT and within each basic block, add insts top down,
190 // so when we pop_back_val in the legalization process, we traverse bottom-up.
191 for (auto *MBB : RPOT) {
192 if (MBB->empty())
193 continue;
194 for (MachineInstr &MI : *MBB) {
195 // Only legalize pre-isel generic instructions: others don't have types
196 // and are assumed to be legal.
197 if (!isPreISelGenericOpcode(MI.getOpcode()))
198 continue;
199 if (isArtifact(MI))
200 ArtifactList.deferred_insert(&MI);
201 else
202 InstList.deferred_insert(&MI);
203 }
204 }
205 ArtifactList.finalize();
206 InstList.finalize();
207
208 // This observer keeps the worklists updated.
209 LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);
210 // We want both WorkListObserver as well as all the auxiliary observers (e.g.
211 // CSEInfo) to observe all changes. Use the wrapper observer.
212 GISelObserverWrapper WrapperObserver(&WorkListObserver);
213 for (GISelChangeObserver *Observer : AuxObservers)
214 WrapperObserver.addObserver(Observer);
215
216 // Now install the observer as the delegate to MF.
217 // This will keep all the observers notified about new insertions/deletions.
218 RAIIMFObsDelInstaller Installer(MF, WrapperObserver);
219 LegalizerHelper Helper(MF, LI, WrapperObserver, MIRBuilder);
220 LegalizationArtifactCombiner ArtCombiner(MIRBuilder, MRI, LI);
221 auto RemoveDeadInstFromLists = [&WrapperObserver](MachineInstr *DeadMI) {
222 WrapperObserver.erasingInstr(*DeadMI);
223 };
224 bool Changed = false;
225 SmallVector<MachineInstr *, 128> RetryList;
226 do {
227 LLVM_DEBUG(dbgs() << "=== New Iteration ===\n")do { } while (false);
228 assert(RetryList.empty() && "Expected no instructions in RetryList")((void)0);
229 unsigned NumArtifacts = ArtifactList.size();
230 while (!InstList.empty()) {
231 MachineInstr &MI = *InstList.pop_back_val();
232 assert(isPreISelGenericOpcode(MI.getOpcode()) &&((void)0)
233 "Expecting generic opcode")((void)0);
234 if (isTriviallyDead(MI, MRI)) {
235 LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n")do { } while (false);
236 MI.eraseFromParentAndMarkDBGValuesForRemoval();
237 LocObserver.checkpoint(false);
238 continue;
239 }
240
241 // Do the legalization for this instruction.
242 auto Res = Helper.legalizeInstrStep(MI, LocObserver);
243 // Error out if we couldn't legalize this instruction. We may want to
244 // fall back to DAG ISel instead in the future.
245 if (Res == LegalizerHelper::UnableToLegalize) {
246 // Move illegal artifacts to RetryList instead of aborting because
247 // legalizing InstList may generate artifacts that allow
248 // ArtifactCombiner to combine away them.
249 if (isArtifact(MI)) {
250 LLVM_DEBUG(dbgs() << ".. Not legalized, moving to artifacts retry\n")do { } while (false);
251 assert(NumArtifacts == 0 &&((void)0)
252 "Artifacts are only expected in instruction list starting the "((void)0)
253 "second iteration, but each iteration starting second must "((void)0)
254 "start with an empty artifacts list")((void)0);
255 (void)NumArtifacts;
256 RetryList.push_back(&MI);
257 continue;
258 }
259 Helper.MIRBuilder.stopObservingChanges();
260 return {Changed, &MI};
261 }
262 WorkListObserver.printNewInstrs();
263 LocObserver.checkpoint();
264 Changed |= Res == LegalizerHelper::Legalized;
265 }
266 // Try to combine the instructions in RetryList again if there
267 // are new artifacts. If not, stop legalizing.
268 if (!RetryList.empty()) {
269 if (!ArtifactList.empty()) {
270 while (!RetryList.empty())
271 ArtifactList.insert(RetryList.pop_back_val());
272 } else {
273 LLVM_DEBUG(dbgs() << "No new artifacts created, not retrying!\n")do { } while (false);
274 Helper.MIRBuilder.stopObservingChanges();
275 return {Changed, RetryList.front()};
276 }
277 }
278 LocObserver.checkpoint();
279 while (!ArtifactList.empty()) {
280 MachineInstr &MI = *ArtifactList.pop_back_val();
281 assert(isPreISelGenericOpcode(MI.getOpcode()) &&((void)0)
282 "Expecting generic opcode")((void)0);
283 if (isTriviallyDead(MI, MRI)) {
284 LLVM_DEBUG(dbgs() << MI << "Is dead\n")do { } while (false);
285 RemoveDeadInstFromLists(&MI);
286 MI.eraseFromParentAndMarkDBGValuesForRemoval();
287 LocObserver.checkpoint(false);
288 continue;
289 }
290 SmallVector<MachineInstr *, 4> DeadInstructions;
291 LLVM_DEBUG(dbgs() << "Trying to combine: " << MI)do { } while (false);
292 if (ArtCombiner.tryCombineInstruction(MI, DeadInstructions,
293 WrapperObserver)) {
294 WorkListObserver.printNewInstrs();
295 for (auto *DeadMI : DeadInstructions) {
296 LLVM_DEBUG(dbgs() << "Is dead: " << *DeadMI)do { } while (false);
297 RemoveDeadInstFromLists(DeadMI);
298 DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
299 }
300 LocObserver.checkpoint(
301 VerifyDebugLocs ==
302 DebugLocVerifyLevel::LegalizationsAndArtifactCombiners);
303 Changed = true;
304 continue;
305 }
306 // If this was not an artifact (that could be combined away), this might
307 // need special handling. Add it to InstList, so when it's processed
308 // there, it has to be legal or specially handled.
309 else {
310 LLVM_DEBUG(dbgs() << ".. Not combined, moving to instructions list\n")do { } while (false);
311 InstList.insert(&MI);
312 }
313 }
314 } while (!InstList.empty());
315
316 return {Changed, /*FailedOn*/ nullptr};
317}
318
319bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
320 // If the ISel pipeline failed, do not bother running that pass.
321 if (MF.getProperties().hasProperty(
1
Taking false branch
322 MachineFunctionProperties::Property::FailedISel))
323 return false;
324 LLVM_DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n')do { } while (false);
2
Loop condition is false. Exiting loop
325 init(MF);
326 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
327 GISelCSEAnalysisWrapper &Wrapper =
328 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
329 MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
330
331 const size_t NumBlocks = MF.size();
332
333 std::unique_ptr<MachineIRBuilder> MIRBuilder;
334 GISelCSEInfo *CSEInfo = nullptr;
335 bool EnableCSE = EnableCSEInLegalizer.getNumOccurrences()
3
Assuming the condition is false
4
'?' condition is false
336 ? EnableCSEInLegalizer
337 : TPC.isGISelCSEEnabled();
338 if (EnableCSE) {
5
Assuming 'EnableCSE' is false
6
Taking false branch
339 MIRBuilder = std::make_unique<CSEMIRBuilder>();
340 CSEInfo = &Wrapper.get(TPC.getCSEConfig());
341 MIRBuilder->setCSEInfo(CSEInfo);
342 } else
343 MIRBuilder = std::make_unique<MachineIRBuilder>();
344
345 SmallVector<GISelChangeObserver *, 1> AuxObservers;
346 if (EnableCSE
6.1
'EnableCSE' is false
6.1
'EnableCSE' is false
&& CSEInfo) {
347 // We want CSEInfo in addition to WorkListObserver to observe all changes.
348 AuxObservers.push_back(CSEInfo);
349 }
350 assert(!CSEInfo || !errorToBool(CSEInfo->verify()))((void)0);
351 LostDebugLocObserver LocObserver(DEBUG_TYPE"legalizer");
352 if (VerifyDebugLocs
6.2
'VerifyDebugLocs' is <= None
6.2
'VerifyDebugLocs' is <= None
> DebugLocVerifyLevel::None)
7
Taking false branch
353 AuxObservers.push_back(&LocObserver);
354
355 const LegalizerInfo &LI = *MF.getSubtarget().getLegalizerInfo();
356 MFResult Result =
357 legalizeMachineFunction(MF, LI, AuxObservers, LocObserver, *MIRBuilder);
358
359 if (Result.FailedOn) {
8
Assuming field 'FailedOn' is null
9
Taking false branch
360 reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
361 "unable to legalize instruction", *Result.FailedOn);
362 return false;
363 }
364 // For now don't support if new blocks are inserted - we would need to fix the
365 // outer loop for that.
366 if (MF.size() != NumBlocks) {
10
Assuming the condition is true
11
Taking true branch
367 MachineOptimizationRemarkMissed R("gisel-legalize", "GISelFailure",
13
Calling constructor for 'MachineOptimizationRemarkMissed'
368 MF.getFunction().getSubprogram(),
369 /*MBB=*/nullptr);
12
Passing null pointer value via 4th parameter 'MBB'
370 R << "inserting blocks is not supported yet";
371 reportGISelFailure(MF, TPC, MORE, R);
372 return false;
373 }
374
375 if (LocObserver.getNumLostDebugLocs()) {
376 MachineOptimizationRemarkMissed R("gisel-legalize", "LostDebugLoc",
377 MF.getFunction().getSubprogram(),
378 /*MBB=*/&*MF.begin());
379 R << "lost "
380 << ore::NV("NumLostDebugLocs", LocObserver.getNumLostDebugLocs())
381 << " debug locations during pass";
382 reportGISelWarning(MF, TPC, MORE, R);
383 // Example remark:
384 // --- !Missed
385 // Pass: gisel-legalize
386 // Name: GISelFailure
387 // DebugLoc: { File: '.../legalize-urem.mir', Line: 1, Column: 0 }
388 // Function: test_urem_s32
389 // Args:
390 // - String: 'lost '
391 // - NumLostDebugLocs: '1'
392 // - String: ' debug locations during pass'
393 // ...
394 }
395
396 // If for some reason CSE was not enabled, make sure that we invalidate the
397 // CSEInfo object (as we currently declare that the analysis is preserved).
398 // The next time get on the wrapper is called, it will force it to recompute
399 // the analysis.
400 if (!EnableCSE)
401 Wrapper.setComputed(false);
402 return Result.Changed;
403}

/usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h

1///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===//
2///
3/// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4/// See https://llvm.org/LICENSE.txt for license information.
5/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6///
7///===---------------------------------------------------------------------===//
8/// \file
9/// Optimization diagnostic interfaces for machine passes. It's packaged as an
10/// analysis pass so that by using this service passes become dependent on MBFI
11/// as well. MBFI is used to compute the "hotness" of the diagnostic message.
12///
13///===---------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
16#define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
17
18#include "llvm/Analysis/OptimizationRemarkEmitter.h"
19#include "llvm/CodeGen/MachineFunctionPass.h"
20
21namespace llvm {
22class MachineBasicBlock;
23class MachineBlockFrequencyInfo;
24class MachineInstr;
25
26/// Common features for diagnostics dealing with optimization remarks
27/// that are used by machine passes.
28class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
29public:
30 DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
31 StringRef RemarkName,
32 const DiagnosticLocation &Loc,
33 const MachineBasicBlock *MBB)
34 : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
35 MBB->getParent()->getFunction(), Loc),
16
Called C++ object pointer is null
36 MBB(MBB) {}
37
38 /// MI-specific kinds of diagnostic Arguments.
39 struct MachineArgument : public DiagnosticInfoOptimizationBase::Argument {
40 /// Print an entire MachineInstr.
41 MachineArgument(StringRef Key, const MachineInstr &MI);
42 };
43
44 static bool classof(const DiagnosticInfo *DI) {
45 return DI->getKind() >= DK_FirstMachineRemark &&
46 DI->getKind() <= DK_LastMachineRemark;
47 }
48
49 const MachineBasicBlock *getBlock() const { return MBB; }
50
51private:
52 const MachineBasicBlock *MBB;
53};
54
55/// Diagnostic information for applied optimization remarks.
56class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
57public:
58 /// \p PassName is the name of the pass emitting this diagnostic. If this name
59 /// matches the regular expression given in -Rpass=, then the diagnostic will
60 /// be emitted. \p RemarkName is a textual identifier for the remark. \p
61 /// Loc is the debug location and \p MBB is the block that the optimization
62 /// operates in.
63 MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
64 const DiagnosticLocation &Loc,
65 const MachineBasicBlock *MBB)
66 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
67 RemarkName, Loc, MBB) {}
68
69 static bool classof(const DiagnosticInfo *DI) {
70 return DI->getKind() == DK_MachineOptimizationRemark;
71 }
72
73 /// \see DiagnosticInfoOptimizationBase::isEnabled.
74 bool isEnabled() const override {
75 const Function &Fn = getFunction();
76 LLVMContext &Ctx = Fn.getContext();
77 return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
78 }
79};
80
81/// Diagnostic information for missed-optimization remarks.
82class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
83public:
84 /// \p PassName is the name of the pass emitting this diagnostic. If this name
85 /// matches the regular expression given in -Rpass-missed=, then the
86 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
87 /// remark. \p Loc is the debug location and \p MBB is the block that the
88 /// optimization operates in.
89 MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
90 const DiagnosticLocation &Loc,
91 const MachineBasicBlock *MBB)
92 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
15
Calling constructor for 'DiagnosticInfoMIROptimization'
93 PassName, RemarkName, Loc, MBB) {}
14
Passing null pointer value via 5th parameter 'MBB'
94
95 static bool classof(const DiagnosticInfo *DI) {
96 return DI->getKind() == DK_MachineOptimizationRemarkMissed;
97 }
98
99 /// \see DiagnosticInfoOptimizationBase::isEnabled.
100 bool isEnabled() const override {
101 const Function &Fn = getFunction();
102 LLVMContext &Ctx = Fn.getContext();
103 return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
104 }
105};
106
107/// Diagnostic information for optimization analysis remarks.
108class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
109public:
110 /// \p PassName is the name of the pass emitting this diagnostic. If this name
111 /// matches the regular expression given in -Rpass-analysis=, then the
112 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
113 /// remark. \p Loc is the debug location and \p MBB is the block that the
114 /// optimization operates in.
115 MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
116 const DiagnosticLocation &Loc,
117 const MachineBasicBlock *MBB)
118 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
119 PassName, RemarkName, Loc, MBB) {}
120
121 static bool classof(const DiagnosticInfo *DI) {
122 return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
123 }
124
125 /// \see DiagnosticInfoOptimizationBase::isEnabled.
126 bool isEnabled() const override {
127 const Function &Fn = getFunction();
128 LLVMContext &Ctx = Fn.getContext();
129 return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
130 }
131};
132
133/// Extend llvm::ore:: with MI-specific helper names.
134namespace ore {
135using MNV = DiagnosticInfoMIROptimization::MachineArgument;
136}
137
138/// The optimization diagnostic interface.
139///
140/// It allows reporting when optimizations are performed and when they are not
141/// along with the reasons for it. Hotness information of the corresponding
142/// code region can be included in the remark if DiagnosticsHotnessRequested is
143/// enabled in the LLVM context.
144class MachineOptimizationRemarkEmitter {
145public:
146 MachineOptimizationRemarkEmitter(MachineFunction &MF,
147 MachineBlockFrequencyInfo *MBFI)
148 : MF(MF), MBFI(MBFI) {}
149
150 /// Emit an optimization remark.
151 void emit(DiagnosticInfoOptimizationBase &OptDiag);
152
153 /// Whether we allow for extra compile-time budget to perform more
154 /// analysis to be more informative.
155 ///
156 /// This is useful to enable additional missed optimizations to be reported
157 /// that are normally too noisy. In this mode, we can use the extra analysis
158 /// (1) to filter trivial false positives or (2) to provide more context so
159 /// that non-trivial false positives can be quickly detected by the user.
160 bool allowExtraAnalysis(StringRef PassName) const {
161 return (
162 MF.getFunction().getContext().getLLVMRemarkStreamer() ||
163 MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
164 PassName));
165 }
166
167 /// Take a lambda that returns a remark which will be emitted. Second
168 /// argument is only used to restrict this to functions.
169 template <typename T>
170 void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171 // Avoid building the remark unless we know there are at least *some*
172 // remarks enabled. We can't currently check whether remarks are requested
173 // for the calling pass since that requires actually building the remark.
174
175 if (MF.getFunction().getContext().getLLVMRemarkStreamer() ||
176 MF.getFunction()
177 .getContext()
178 .getDiagHandlerPtr()
179 ->isAnyRemarkEnabled()) {
180 auto R = RemarkBuilder();
181 emit((DiagnosticInfoOptimizationBase &)R);
182 }
183 }
184
185 MachineBlockFrequencyInfo *getBFI() {
186 return MBFI;
187 }
188
189private:
190 MachineFunction &MF;
191
192 /// MBFI is only set if hotness is requested.
193 MachineBlockFrequencyInfo *MBFI;
194
195 /// Compute hotness from IR value (currently assumed to be a block) if PGO is
196 /// available.
197 Optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
198
199 /// Similar but use value from \p OptDiag and update hotness there.
200 void computeHotness(DiagnosticInfoMIROptimization &Remark);
201
202 /// Only allow verbose messages if we know we're filtering by hotness
203 /// (BFI is only set in this case).
204 bool shouldEmitVerbose() { return MBFI != nullptr; }
205};
206
207/// The analysis pass
208///
209/// Note that this pass shouldn't generally be marked as preserved by other
210/// passes. It's holding onto BFI, so if the pass does not preserve BFI, BFI
211/// could be freed.
212class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
213 std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
214
215public:
216 MachineOptimizationRemarkEmitterPass();
217
218 bool runOnMachineFunction(MachineFunction &MF) override;
219
220 void getAnalysisUsage(AnalysisUsage &AU) const override;
221
222 MachineOptimizationRemarkEmitter &getORE() {
223 assert(ORE && "pass not run yet")((void)0);
224 return *ORE;
225 }
226
227 static char ID;
228};
229}
230
231#endif