blob: f1b2f764fe12f32b5deb873adb79e72aa2b69b11 [file] [log] [blame]
David Neto22f144c2017-06-12 14:26:21 -04001// Copyright 2017 The Clspv Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
David Neto118188e2018-08-24 11:27:54 -040015#include "llvm/IR/Constants.h"
David Neto118188e2018-08-24 11:27:54 -040016#include "llvm/IR/IRBuilder.h"
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040017#include "llvm/IR/Instructions.h"
David Neto118188e2018-08-24 11:27:54 -040018#include "llvm/IR/Module.h"
19#include "llvm/Pass.h"
20#include "llvm/Transforms/Utils/Cloning.h"
David Neto22f144c2017-06-12 14:26:21 -040021
Diego Novilloa4c44fa2019-04-11 10:56:15 -040022#include "Passes.h"
23
David Neto22f144c2017-06-12 14:26:21 -040024using namespace llvm;
25
26#define DEBUG_TYPE "UndoGetElementPtrConstantExpr"
27
28namespace {
29struct UndoGetElementPtrConstantExprPass : public ModulePass {
30 static char ID;
31 UndoGetElementPtrConstantExprPass() : ModulePass(ID) {}
32
33 bool runOnModule(Module &M) override;
34
35 bool replaceGetElementPtrConstantExpr(ConstantExpr *CE);
36};
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040037} // namespace
David Neto22f144c2017-06-12 14:26:21 -040038
39char UndoGetElementPtrConstantExprPass::ID = 0;
Diego Novilloa4c44fa2019-04-11 10:56:15 -040040INITIALIZE_PASS(UndoGetElementPtrConstantExprPass,
41 "UndoGetElementPtrConstantExpr", "Undo GEP Constant Expr Pass",
42 false, false)
David Neto22f144c2017-06-12 14:26:21 -040043
44namespace clspv {
45ModulePass *createUndoGetElementPtrConstantExprPass() {
46 return new UndoGetElementPtrConstantExprPass();
47}
Diego Novillo3cc8d7a2019-04-10 13:30:34 -040048} // namespace clspv
David Neto22f144c2017-06-12 14:26:21 -040049
50bool UndoGetElementPtrConstantExprPass::runOnModule(Module &M) {
51 bool changed = false;
52
53 for (GlobalVariable &GV : M.globals()) {
54 // Walk the users of the global variable.
55 const SmallVector<User *, 8> GVUsers(GV.user_begin(), GV.user_end());
56 for (User *U : GVUsers) {
57 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
58 if (Instruction::GetElementPtr == CE->getOpcode()) {
59 changed |= replaceGetElementPtrConstantExpr(CE);
60 }
61 }
62 }
63 }
64
65 return changed;
66}
67
68bool UndoGetElementPtrConstantExprPass::replaceGetElementPtrConstantExpr(
69 ConstantExpr *CE) {
70 SmallVector<Instruction *, 8> WorkList;
71
72 // Walk the users of the constant expression.
73 for (User *U : CE->users()) {
74 if (Instruction *I = dyn_cast<Instruction>(U)) {
75 WorkList.push_back(I);
David Neto22f144c2017-06-12 14:26:21 -040076 }
77 }
78
79 for (Instruction *I : WorkList) {
80 // Create the instruction equivalent of the constant expression.
81 Instruction *NewI = CE->getAsInstruction();
82
83 if (PHINode *PHI = dyn_cast<PHINode>(I)) {
84 // If PHINode uses CE, put new instruction of CE at end of the incoming
85 // block.
86 for (unsigned i = 0; i < PHI->getNumIncomingValues(); i++) {
87 if (PHI->getIncomingValue(i) == CE) {
88 NewI->insertBefore(PHI->getIncomingBlock(i)->getTerminator());
89 }
90 }
91 } else {
92 // Insert it just before the instruction that will use it.
93 NewI->insertBefore(I);
94 }
95
96 // Walk the operands of the instruction to find where the constant
97 // expression was used.
98 for (unsigned i = 0; i < I->getNumOperands(); i++) {
99 if (CE == I->getOperand(i)) {
100 I->setOperand(i, NewI);
101 break;
102 }
103 }
104 }
105
Diego Novillo3cc8d7a2019-04-10 13:30:34 -0400106 if (CE->user_empty())
107 CE->destroyConstant();
David Neto22f144c2017-06-12 14:26:21 -0400108
109 return true;
110}