1*0b57cec5SDimitry Andric //===- StripGCRelocates.cpp - Remove gc.relocates inserted by RewriteStatePoints===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This is a little utility pass that removes the gc.relocates inserted by
10*0b57cec5SDimitry Andric // RewriteStatepointsForGC. Note that the generated IR is incorrect,
11*0b57cec5SDimitry Andric // but this is useful as a single pass in itself, for analysis of IR, without
1281ad6265SDimitry Andric // the GC.relocates. The statepoint and gc.result intrinsics would still be
13*0b57cec5SDimitry Andric // present.
14*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15*0b57cec5SDimitry Andric
16e8d8bef9SDimitry Andric #include "llvm/Transforms/Utils/StripGCRelocates.h"
17*0b57cec5SDimitry Andric #include "llvm/IR/Function.h"
18*0b57cec5SDimitry Andric #include "llvm/IR/InstIterator.h"
19*0b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
20*0b57cec5SDimitry Andric #include "llvm/IR/Statepoint.h"
21*0b57cec5SDimitry Andric
22*0b57cec5SDimitry Andric using namespace llvm;
23*0b57cec5SDimitry Andric
stripGCRelocates(Function & F)24e8d8bef9SDimitry Andric static bool stripGCRelocates(Function &F) {
25*0b57cec5SDimitry Andric // Nothing to do for declarations.
26*0b57cec5SDimitry Andric if (F.isDeclaration())
27*0b57cec5SDimitry Andric return false;
28*0b57cec5SDimitry Andric SmallVector<GCRelocateInst *, 20> GCRelocates;
29*0b57cec5SDimitry Andric // TODO: We currently do not handle gc.relocates that are in landing pads,
30*0b57cec5SDimitry Andric // i.e. not bound to a single statepoint token.
31*0b57cec5SDimitry Andric for (Instruction &I : instructions(F)) {
32*0b57cec5SDimitry Andric if (auto *GCR = dyn_cast<GCRelocateInst>(&I))
335ffd83dbSDimitry Andric if (isa<GCStatepointInst>(GCR->getOperand(0)))
34*0b57cec5SDimitry Andric GCRelocates.push_back(GCR);
35*0b57cec5SDimitry Andric }
36*0b57cec5SDimitry Andric // All gc.relocates are bound to a single statepoint token. The order of
37*0b57cec5SDimitry Andric // visiting gc.relocates for deletion does not matter.
38*0b57cec5SDimitry Andric for (GCRelocateInst *GCRel : GCRelocates) {
39*0b57cec5SDimitry Andric Value *OrigPtr = GCRel->getDerivedPtr();
40*0b57cec5SDimitry Andric Value *ReplaceGCRel = OrigPtr;
41*0b57cec5SDimitry Andric
42*0b57cec5SDimitry Andric // All gc_relocates are i8 addrspace(1)* typed, we need a bitcast from i8
43*0b57cec5SDimitry Andric // addrspace(1)* to the type of the OrigPtr, if the are not the same.
44*0b57cec5SDimitry Andric if (GCRel->getType() != OrigPtr->getType())
45*0b57cec5SDimitry Andric ReplaceGCRel = new BitCastInst(OrigPtr, GCRel->getType(), "cast", GCRel);
46*0b57cec5SDimitry Andric
47*0b57cec5SDimitry Andric // Replace all uses of gc.relocate and delete the gc.relocate
48*0b57cec5SDimitry Andric // There maybe unncessary bitcasts back to the OrigPtr type, an instcombine
49*0b57cec5SDimitry Andric // pass would clear this up.
50*0b57cec5SDimitry Andric GCRel->replaceAllUsesWith(ReplaceGCRel);
51*0b57cec5SDimitry Andric GCRel->eraseFromParent();
52*0b57cec5SDimitry Andric }
53*0b57cec5SDimitry Andric return !GCRelocates.empty();
54*0b57cec5SDimitry Andric }
55*0b57cec5SDimitry Andric
run(Function & F,FunctionAnalysisManager & AM)56e8d8bef9SDimitry Andric PreservedAnalyses StripGCRelocates::run(Function &F,
57e8d8bef9SDimitry Andric FunctionAnalysisManager &AM) {
58e8d8bef9SDimitry Andric if (!stripGCRelocates(F))
59e8d8bef9SDimitry Andric return PreservedAnalyses::all();
60e8d8bef9SDimitry Andric
61e8d8bef9SDimitry Andric // Removing gc.relocate preserves the CFG, but most other analysis probably
62e8d8bef9SDimitry Andric // need to re-run.
63e8d8bef9SDimitry Andric PreservedAnalyses PA;
64e8d8bef9SDimitry Andric PA.preserveSet<CFGAnalyses>();
65e8d8bef9SDimitry Andric return PA;
66e8d8bef9SDimitry Andric }
67