Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/GCRootLowering.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- GCRootLowering.cpp - Garbage collection infrastructure ------------===//
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
// This file implements the lowering for the gc.root mechanism.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/CodeGen/GCMetadata.h"
14
#include "llvm/CodeGen/GCStrategy.h"
15
#include "llvm/CodeGen/MachineFrameInfo.h"
16
#include "llvm/CodeGen/MachineFunctionPass.h"
17
#include "llvm/CodeGen/MachineInstrBuilder.h"
18
#include "llvm/CodeGen/MachineModuleInfo.h"
19
#include "llvm/CodeGen/Passes.h"
20
#include "llvm/CodeGen/TargetFrameLowering.h"
21
#include "llvm/CodeGen/TargetInstrInfo.h"
22
#include "llvm/CodeGen/TargetRegisterInfo.h"
23
#include "llvm/CodeGen/TargetSubtargetInfo.h"
24
#include "llvm/IR/Dominators.h"
25
#include "llvm/IR/IntrinsicInst.h"
26
#include "llvm/IR/Module.h"
27
#include "llvm/Support/Debug.h"
28
#include "llvm/Support/ErrorHandling.h"
29
#include "llvm/Support/raw_ostream.h"
30
31
using namespace llvm;
32
33
namespace {
34
35
/// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or
36
/// llvm.gcwrite intrinsics, replacing them with simple loads and stores as
37
/// directed by the GCStrategy. It also performs automatic root initialization
38
/// and custom intrinsic lowering.
39
class LowerIntrinsics : public FunctionPass {
40
  bool DoLowering(Function &F, GCStrategy &S);
41
42
public:
43
  static char ID;
44
45
  LowerIntrinsics();
46
  StringRef getPassName() const override;
47
  void getAnalysisUsage(AnalysisUsage &AU) const override;
48
49
  bool doInitialization(Module &M) override;
50
  bool runOnFunction(Function &F) override;
51
};
52
53
/// GCMachineCodeAnalysis - This is a target-independent pass over the machine
54
/// function representation to identify safe points for the garbage collector
55
/// in the machine code. It inserts labels at safe points and populates a
56
/// GCMetadata record for each function.
57
class GCMachineCodeAnalysis : public MachineFunctionPass {
58
  GCFunctionInfo *FI;
59
  MachineModuleInfo *MMI;
60
  const TargetInstrInfo *TII;
61
62
  void FindSafePoints(MachineFunction &MF);
63
  void VisitCallPoint(MachineBasicBlock::iterator CI);
64
  MCSymbol *InsertLabel(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
65
                        const DebugLoc &DL) const;
66
67
  void FindStackOffsets(MachineFunction &MF);
68
69
public:
70
  static char ID;
71
72
  GCMachineCodeAnalysis();
73
  void getAnalysisUsage(AnalysisUsage &AU) const override;
74
75
  bool runOnMachineFunction(MachineFunction &MF) override;
76
};
77
}
78
79
// -----------------------------------------------------------------------------
80
81
42.3k
INITIALIZE_PASS_BEGIN(LowerIntrinsics, "gc-lowering", "GC Lowering", false,
82
42.3k
                      false)
83
42.3k
INITIALIZE_PASS_DEPENDENCY(GCModuleInfo)
84
42.3k
INITIALIZE_PASS_END(LowerIntrinsics, "gc-lowering", "GC Lowering", false, false)
85
86
36.3k
FunctionPass *llvm::createGCLoweringPass() { return new LowerIntrinsics(); }
87
88
char LowerIntrinsics::ID = 0;
89
90
36.3k
LowerIntrinsics::LowerIntrinsics() : FunctionPass(ID) {
91
36.3k
  initializeLowerIntrinsicsPass(*PassRegistry::getPassRegistry());
92
36.3k
}
93
94
499k
StringRef LowerIntrinsics::getPassName() const {
95
499k
  return "Lower Garbage Collection Instructions";
96
499k
}
97
98
36.1k
void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
99
36.1k
  FunctionPass::getAnalysisUsage(AU);
100
36.1k
  AU.addRequired<GCModuleInfo>();
101
36.1k
  AU.addPreserved<DominatorTreeWrapperPass>();
102
36.1k
}
103
104
/// doInitialization - If this module uses the GC intrinsics, find them now.
105
36.1k
bool LowerIntrinsics::doInitialization(Module &M) {
106
36.1k
  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
107
36.1k
  assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
108
736k
  for (Module::iterator I = M.begin(), E = M.end(); I != E; 
++I700k
)
109
700k
    if (!I->isDeclaration() && 
I->hasGC()499k
)
110
81
      MI->getFunctionInfo(*I); // Instantiate the GC strategy.
111
36.1k
112
36.1k
  return false;
113
36.1k
}
114
115
/// CouldBecomeSafePoint - Predicate to conservatively determine whether the
116
/// instruction could introduce a safe point.
117
5
static bool CouldBecomeSafePoint(Instruction *I) {
118
5
  // The natural definition of instructions which could introduce safe points
119
5
  // are:
120
5
  //
121
5
  //   - call, invoke (AfterCall, BeforeCall)
122
5
  //   - phis (Loops)
123
5
  //   - invoke, ret, unwind (Exit)
124
5
  //
125
5
  // However, instructions as seemingly inoccuous as arithmetic can become
126
5
  // libcalls upon lowering (e.g., div i64 on a 32-bit platform), so instead
127
5
  // it is necessary to take a conservative approach.
128
5
129
5
  if (isa<AllocaInst>(I) || isa<GetElementPtrInst>(I) || isa<StoreInst>(I) ||
130
5
      isa<LoadInst>(I))
131
0
    return false;
132
5
133
5
  // llvm.gcroot is safe because it doesn't do anything at runtime.
134
5
  if (CallInst *CI = dyn_cast<CallInst>(I))
135
2
    if (Function *F = CI->getCalledFunction())
136
2
      if (Intrinsic::ID IID = F->getIntrinsicID())
137
1
        if (IID == Intrinsic::gcroot)
138
1
          return false;
139
4
140
4
  return true;
141
4
}
142
143
4
static bool InsertRootInitializers(Function &F, ArrayRef<AllocaInst *> Roots) {
144
4
  // Scroll past alloca instructions.
145
4
  BasicBlock::iterator IP = F.getEntryBlock().begin();
146
8
  while (isa<AllocaInst>(IP))
147
4
    ++IP;
148
4
149
4
  // Search for initializers in the initial BB.
150
4
  SmallPtrSet<AllocaInst *, 16> InitedRoots;
151
5
  for (; !CouldBecomeSafePoint(&*IP); 
++IP1
)
152
1
    if (StoreInst *SI = dyn_cast<StoreInst>(IP))
153
0
      if (AllocaInst *AI =
154
0
              dyn_cast<AllocaInst>(SI->getOperand(1)->stripPointerCasts()))
155
0
        InitedRoots.insert(AI);
156
4
157
4
  // Add root initializers.
158
4
  bool MadeChange = false;
159
4
160
4
  for (AllocaInst *Root : Roots)
161
5
    if (!InitedRoots.count(Root)) {
162
5
      StoreInst *SI = new StoreInst(
163
5
          ConstantPointerNull::get(cast<PointerType>(Root->getAllocatedType())),
164
5
          Root);
165
5
      SI->insertAfter(Root);
166
5
      MadeChange = true;
167
5
    }
168
4
169
4
  return MadeChange;
170
4
}
171
172
/// runOnFunction - Replace gcread/gcwrite intrinsics with loads and stores.
173
/// Leave gcroot intrinsics; the code generator needs to see those.
174
499k
bool LowerIntrinsics::runOnFunction(Function &F) {
175
499k
  // Quick exit for functions that do not use GC.
176
499k
  if (!F.hasGC())
177
499k
    return false;
178
79
179
79
  GCFunctionInfo &FI = getAnalysis<GCModuleInfo>().getFunctionInfo(F);
180
79
  GCStrategy &S = FI.getStrategy();
181
79
182
79
  return DoLowering(F, S);
183
79
}
184
185
/// Lower barriers out of existance (if the associated GCStrategy hasn't
186
/// already done so...), and insert initializing stores to roots as a defensive
187
/// measure.  Given we're going to report all roots live at all safepoints, we
188
/// need to be able to ensure each root has been initialized by the point the
189
/// first safepoint is reached.  This really should have been done by the
190
/// frontend, but the old API made this non-obvious, so we do a potentially
191
/// redundant store just in case.  
192
81
bool LowerIntrinsics::DoLowering(Function &F, GCStrategy &S) {
193
81
  SmallVector<AllocaInst *, 32> Roots;
194
81
195
81
  bool MadeChange = false;
196
81
  for (BasicBlock &BB : F) 
197
630
    
for (BasicBlock::iterator II = BB.begin(), E = BB.end(); 120
II != E;) {
198
510
      IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++);
199
510
      if (!CI)
200
331
        continue;
201
179
202
179
      Function *F = CI->getCalledFunction();
203
179
      switch (F->getIntrinsicID()) {
204
179
      
default: break173
;
205
179
      case Intrinsic::gcwrite: {
206
1
        // Replace a write barrier with a simple store.
207
1
        Value *St = new StoreInst(CI->getArgOperand(0),
208
1
                                  CI->getArgOperand(2), CI);
209
1
        CI->replaceAllUsesWith(St);
210
1
        CI->eraseFromParent();
211
1
        MadeChange = true;
212
1
        break;
213
179
      }
214
179
      case Intrinsic::gcread: {
215
0
        // Replace a read barrier with a simple load.
216
0
        Value *Ld = new LoadInst(CI->getType(), CI->getArgOperand(1), "", CI);
217
0
        Ld->takeName(CI);
218
0
        CI->replaceAllUsesWith(Ld);
219
0
        CI->eraseFromParent();
220
0
        MadeChange = true;
221
0
        break;
222
179
      }
223
179
      case Intrinsic::gcroot: {
224
5
        // Initialize the GC root, but do not delete the intrinsic. The
225
5
        // backend needs the intrinsic to flag the stack slot.
226
5
        Roots.push_back(
227
5
            cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts()));
228
5
        break;
229
179
      }
230
179
      }
231
179
    }
232
81
233
81
  if (Roots.size())
234
4
    MadeChange |= InsertRootInitializers(F, Roots);
235
81
236
81
  return MadeChange;
237
81
}
238
239
// -----------------------------------------------------------------------------
240
241
char GCMachineCodeAnalysis::ID = 0;
242
char &llvm::GCMachineCodeAnalysisID = GCMachineCodeAnalysis::ID;
243
244
INITIALIZE_PASS(GCMachineCodeAnalysis, "gc-analysis",
245
                "Analyze Machine Code For Garbage Collection", false, false)
246
247
33.2k
GCMachineCodeAnalysis::GCMachineCodeAnalysis() : MachineFunctionPass(ID) {}
248
249
32.9k
void GCMachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
250
32.9k
  MachineFunctionPass::getAnalysisUsage(AU);
251
32.9k
  AU.setPreservesAll();
252
32.9k
  AU.addRequired<MachineModuleInfo>();
253
32.9k
  AU.addRequired<GCModuleInfo>();
254
32.9k
}
255
256
MCSymbol *GCMachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,
257
                                             MachineBasicBlock::iterator MI,
258
4
                                             const DebugLoc &DL) const {
259
4
  MCSymbol *Label = MBB.getParent()->getContext().createTempSymbol();
260
4
  BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label);
261
4
  return Label;
262
4
}
263
264
4
void GCMachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) {
265
4
  // Find the return address (next instruction), since that's what will be on
266
4
  // the stack when the call is suspended and we need to inspect the stack.
267
4
  MachineBasicBlock::iterator RAI = CI;
268
4
  ++RAI;
269
4
270
4
  MCSymbol *Label = InsertLabel(*CI->getParent(), RAI, CI->getDebugLoc());
271
4
  FI->addSafePoint(Label, CI->getDebugLoc());
272
4
}
273
274
6
void GCMachineCodeAnalysis::FindSafePoints(MachineFunction &MF) {
275
6
  for (MachineBasicBlock &MBB : MF)
276
6
    for (MachineBasicBlock::iterator MI = MBB.begin(), ME = MBB.end();
277
45
         MI != ME; 
++MI39
)
278
39
      if (MI->isCall()) {
279
4
        // Do not treat tail or sibling call sites as safe points.  This is
280
4
        // legal since any arguments passed to the callee which live in the
281
4
        // remnants of the callers frame will be owned and updated by the
282
4
        // callee if required.
283
4
        if (MI->isTerminator())
284
0
          continue;
285
4
        VisitCallPoint(MI);
286
4
      }
287
6
}
288
289
81
void GCMachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) {
290
81
  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
291
81
  assert(TFI && "TargetRegisterInfo not available!");
292
81
293
81
  for (GCFunctionInfo::roots_iterator RI = FI->roots_begin();
294
83
       RI != FI->roots_end();) {
295
2
    // If the root references a dead object, no need to keep it.
296
2
    if (MF.getFrameInfo().isDeadObjectIndex(RI->Num)) {
297
0
      RI = FI->removeStackRoot(RI);
298
2
    } else {
299
2
      unsigned FrameReg; // FIXME: surely GCRoot ought to store the
300
2
                         // register that the offset is from?
301
2
      RI->StackOffset = TFI->getFrameIndexReference(MF, RI->Num, FrameReg);
302
2
      ++RI;
303
2
    }
304
2
  }
305
81
}
306
307
466k
bool GCMachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
308
466k
  // Quick exit for functions that do not use GC.
309
466k
  if (!MF.getFunction().hasGC())
310
466k
    return false;
311
80
312
80
  FI = &getAnalysis<GCModuleInfo>().getFunctionInfo(MF.getFunction());
313
80
  MMI = &getAnalysis<MachineModuleInfo>();
314
80
  TII = MF.getSubtarget().getInstrInfo();
315
80
316
80
  // Find the size of the stack frame.  There may be no correct static frame
317
80
  // size, we use UINT64_MAX to represent this.
318
80
  const MachineFrameInfo &MFI = MF.getFrameInfo();
319
80
  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
320
80
  const bool DynamicFrameSize = MFI.hasVarSizedObjects() ||
321
81
    RegInfo->needsStackRealignment(MF);
322
80
  FI->setFrameSize(DynamicFrameSize ? UINT64_MAX : 
MFI.getStackSize()78
);
323
80
324
80
  // Find all safe points.
325
80
  if (FI->getStrategy().needsSafePoints())
326
6
    FindSafePoints(MF);
327
80
328
80
  // Find the concrete stack offsets for all roots (stack slots)
329
80
  FindStackOffsets(MF);
330
80
331
80
  return false;
332
80
}