Skip to content

Commit d826b0c

Browse files
authored
[LLVM] Add HasFakeUses to MachineFunction (#110097)
Following the addition of the llvm.fake.use intrinsic and corresponding MIR instruction, two further changes are planned: to add an -fextend-lifetimes flag to Clang that emits these intrinsics, and to have -Og enable this flag by default. Currently, some logic for handling fake uses is gated by the optdebug attribute, which is intended to be switched on by -fextend-lifetimes (and by extension -Og later on). However, the decision was made that a general optdebug attribute should be incompatible with other opt_ attributes (e.g. optsize, optnone), since they all express different intents for how to optimize the program. We would still like to allow -fextend-lifetimes with optsize however (i.e. -Os -fextend-lifetimes should be legal), since it may be a useful configuration and there is no technical reason to not allow it. This patch resolves this by tracking MachineFunctions that have fake uses, allowing us to run passes that interact with them and skip passes that clash with them.
1 parent 6294679 commit d826b0c

File tree

11 files changed

+76
-8
lines changed

11 files changed

+76
-8
lines changed

llvm/include/llvm/CodeGen/MIRYamlMapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ struct MachineFunction {
734734
std::optional<bool> NoPHIs;
735735
std::optional<bool> IsSSA;
736736
std::optional<bool> NoVRegs;
737+
std::optional<bool> HasFakeUses;
737738

738739
bool CallsEHReturn = false;
739740
bool CallsUnwindInit = false;
@@ -780,6 +781,7 @@ template <> struct MappingTraits<MachineFunction> {
780781
YamlIO.mapOptional("noPhis", MF.NoPHIs, std::optional<bool>());
781782
YamlIO.mapOptional("isSSA", MF.IsSSA, std::optional<bool>());
782783
YamlIO.mapOptional("noVRegs", MF.NoVRegs, std::optional<bool>());
784+
YamlIO.mapOptional("hasFakeUses", MF.HasFakeUses, std::optional<bool>());
783785

784786
YamlIO.mapOptional("callsEHReturn", MF.CallsEHReturn, false);
785787
YamlIO.mapOptional("callsUnwindInit", MF.CallsUnwindInit, false);

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ class MachineFunctionProperties {
187187
TiedOpsRewritten,
188188
FailsVerification,
189189
TracksDebugUserValues,
190+
HasFakeUses,
190191
LastProperty = TracksDebugUserValues,
191192
};
192193

@@ -376,6 +377,7 @@ class LLVM_ABI MachineFunction {
376377
bool HasEHCatchret = false;
377378
bool HasEHScopes = false;
378379
bool HasEHFunclets = false;
380+
bool HasFakeUses = false;
379381
bool IsOutlined = false;
380382

381383
/// BBID to assign to the next basic block of this function.
@@ -1195,6 +1197,9 @@ class LLVM_ABI MachineFunction {
11951197
bool hasEHFunclets() const { return HasEHFunclets; }
11961198
void setHasEHFunclets(bool V) { HasEHFunclets = V; }
11971199

1200+
bool hasFakeUses() const { return HasFakeUses; }
1201+
void setHasFakeUses(bool V) { HasFakeUses = V; }
1202+
11981203
bool isOutlined() const { return IsOutlined; }
11991204
void setIsOutlined(bool V) { IsOutlined = V; }
12001205

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,6 +2201,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
22012201
for (auto VReg : getOrCreateVRegs(*Arg))
22022202
VRegs.push_back(VReg);
22032203
MIRBuilder.buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
2204+
MF->setHasFakeUses(true);
22042205
return true;
22052206
}
22062207
case Intrinsic::dbg_declare: {

llvm/lib/CodeGen/MIRParser/MIRParser.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,16 @@ bool MIRParserImpl::computeFunctionProperties(
380380

381381
bool HasPHI = false;
382382
bool HasInlineAsm = false;
383+
bool HasFakeUses = false;
383384
bool AllTiedOpsRewritten = true, HasTiedOps = false;
384385
for (const MachineBasicBlock &MBB : MF) {
385386
for (const MachineInstr &MI : MBB) {
386387
if (MI.isPHI())
387388
HasPHI = true;
388389
if (MI.isInlineAsm())
389390
HasInlineAsm = true;
391+
if (MI.isFakeUse())
392+
HasFakeUses = true;
390393
for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
391394
const MachineOperand &MO = MI.getOperand(I);
392395
if (!MO.isReg() || !MO.getReg())
@@ -441,6 +444,16 @@ bool MIRParserImpl::computeFunctionProperties(
441444
" has explicit property NoVRegs, but contains virtual registers");
442445
}
443446

447+
// For hasFakeUses we follow similar logic to the ComputedPropertyHelper,
448+
// except for caring about the inverse case only, i.e. when the property is
449+
// explicitly set to false and Fake Uses are present; having HasFakeUses=true
450+
// on a function without fake uses is harmless.
451+
if (YamlMF.HasFakeUses && !*YamlMF.HasFakeUses && HasFakeUses)
452+
return error(
453+
MF.getName() +
454+
" has explicit property hasFakeUses=false, but contains fake uses");
455+
MF.setHasFakeUses(YamlMF.HasFakeUses.value_or(HasFakeUses));
456+
444457
return false;
445458
}
446459

llvm/lib/CodeGen/MIRPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ void MIRPrinter::print(const MachineFunction &MF) {
207207
YamlMF.HasEHCatchret = MF.hasEHCatchret();
208208
YamlMF.HasEHScopes = MF.hasEHScopes();
209209
YamlMF.HasEHFunclets = MF.hasEHFunclets();
210+
YamlMF.HasFakeUses = MF.hasFakeUses();
210211
YamlMF.IsOutlined = MF.isOutlined();
211212
YamlMF.UseDebugInstrRef = MF.useDebugInstrRef();
212213

llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,8 @@ INITIALIZE_PASS_END(RemoveLoadsIntoFakeUses, DEBUG_TYPE,
7474
"Remove Loads Into Fake Uses", false, false)
7575

7676
bool RemoveLoadsIntoFakeUses::runOnMachineFunction(MachineFunction &MF) {
77-
// Only `optdebug` functions should contain FAKE_USEs, so don't try to run
78-
// this for other functions.
79-
if (!MF.getFunction().hasFnAttribute(Attribute::OptimizeForDebugging) ||
80-
skipFunction(MF.getFunction()))
77+
// Only run this for functions that have fake uses.
78+
if (!MF.hasFakeUses() || skipFunction(MF.getFunction()))
8179
return false;
8280

8381
bool AnyChanges = false;

llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llvm/IR/Function.h"
3232
#include "llvm/IR/Instructions.h"
3333
#include "llvm/IR/IntrinsicInst.h"
34+
#include "llvm/IR/Intrinsics.h"
3435
#include "llvm/IR/Module.h"
3536
#include "llvm/Support/Debug.h"
3637
#include "llvm/Support/ErrorHandling.h"
@@ -200,12 +201,22 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
200201
}
201202
}
202203
}
203-
// Look for calls to the @llvm.va_start intrinsic. We can omit some
204-
// prologue boilerplate for variadic functions that don't examine their
205-
// arguments.
206204
if (const auto *II = dyn_cast<IntrinsicInst>(&I)) {
207-
if (II->getIntrinsicID() == Intrinsic::vastart)
205+
switch (II->getIntrinsicID()) {
206+
case Intrinsic::vastart:
207+
// Look for calls to the @llvm.va_start intrinsic. We can omit
208+
// some prologue boilerplate for variadic functions that don't
209+
// examine their arguments.
208210
MF->getFrameInfo().setHasVAStart(true);
211+
break;
212+
case Intrinsic::fake_use:
213+
// Look for llvm.fake.uses, so that we can remove loads into fake
214+
// uses later if necessary.
215+
MF->setHasFakeUses(true);
216+
break;
217+
default:
218+
break;
219+
}
209220
}
210221

211222
// If we have a musttail call in a variadic function, we need to ensure
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# RUN: not llc -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
2+
3+
# Test that computed properties are not conflicting with explicitly set
4+
# properties
5+
6+
---
7+
# CHECK: error: {{.*}}: TestHasFakeUsesOverrideConflict has explicit property hasFakeUses=false, but contains fake uses
8+
name: TestHasFakeUsesOverrideConflict
9+
hasFakeUses: false
10+
body: |
11+
bb.0:
12+
%0:_(s32) = G_IMPLICIT_DEF
13+
FAKE_USE %0
14+
...

llvm/test/CodeGen/MIR/Generic/machine-function-optionally-computed-properties.mir

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,23 @@ noVRegs: false
6262
name: TestNoVRegsOverrideTrue
6363
noVRegs: true
6464
...
65+
---
66+
# CHECK-LABEL: name: TestHasFakeUses
67+
# CHECK: hasFakeUses: false
68+
# CHECK: ...
69+
name: TestHasFakeUses
70+
...
71+
---
72+
# CHECK-LABEL: name: TestHasFakeUsesOverride
73+
# CHECK: hasFakeUses: false
74+
# CHECK: ...
75+
name: TestHasFakeUsesOverride
76+
hasFakeUses: false
77+
...
78+
---
79+
# CHECK-LABEL: name: TestHasFakeUsesOverrideTrue
80+
# CHECK: hasFakeUses: true
81+
# CHECK: ...
82+
name: TestHasFakeUsesOverrideTrue
83+
hasFakeUses: true
84+
...

llvm/test/tools/llvm-reduce/mir/preserve-func-info.mir

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# RESULT-NEXT: noPhis: false
1818
# RESULT-NEXT: isSSA: false
1919
# RESULT-NEXT: noVRegs: false
20+
# RESULT-NEXT: hasFakeUses: true
2021
# RESULT-NEXT: callsEHReturn: true
2122
# RESULT-NEXT: callsUnwindInit: true
2223
# RESULT-NEXT: hasEHCatchret: true
@@ -47,6 +48,7 @@ hasWinCFI: true
4748
noPhis: false
4849
isSSA: false
4950
noVRegs: false
51+
hasFakeUses: true
5052
failsVerification: true
5153
tracksDebugUserValues: true
5254
callsEHReturn: true

llvm/tools/llvm-reduce/ReducerWorkItem.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF,
403403
DstMF->setHasEHCatchret(SrcMF->hasEHCatchret());
404404
DstMF->setHasEHScopes(SrcMF->hasEHScopes());
405405
DstMF->setHasEHFunclets(SrcMF->hasEHFunclets());
406+
DstMF->setHasFakeUses(SrcMF->hasFakeUses());
406407
DstMF->setIsOutlined(SrcMF->isOutlined());
407408

408409
if (!SrcMF->getLandingPads().empty() ||

0 commit comments

Comments
 (0)