Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/NVPTX/NVPTXLowerAlloca.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- NVPTXLowerAlloca.cpp - Make alloca to use local memory =====--===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// For all alloca instructions, and add a pair of cast to local address for
11
// each of them. For example,
12
//
13
//   %A = alloca i32
14
//   store i32 0, i32* %A ; emits st.u32
15
//
16
// will be transformed to
17
//
18
//   %A = alloca i32
19
//   %Local = addrspacecast i32* %A to i32 addrspace(5)*
20
//   %Generic = addrspacecast i32 addrspace(5)* %A to i32*
21
//   store i32 0, i32 addrspace(5)* %Generic ; emits st.local.u32
22
//
23
// And we will rely on NVPTXInferAddressSpaces to combine the last two
24
// instructions.
25
//
26
//===----------------------------------------------------------------------===//
27
28
#include "NVPTX.h"
29
#include "NVPTXUtilities.h"
30
#include "llvm/IR/Function.h"
31
#include "llvm/IR/Instructions.h"
32
#include "llvm/IR/IntrinsicInst.h"
33
#include "llvm/IR/Module.h"
34
#include "llvm/IR/Type.h"
35
#include "llvm/Pass.h"
36
37
using namespace llvm;
38
39
namespace llvm {
40
void initializeNVPTXLowerAllocaPass(PassRegistry &);
41
}
42
43
namespace {
44
class NVPTXLowerAlloca : public BasicBlockPass {
45
  bool runOnBasicBlock(BasicBlock &BB) override;
46
47
public:
48
  static char ID; // Pass identification, replacement for typeid
49
207
  NVPTXLowerAlloca() : BasicBlockPass(ID) {}
50
0
  StringRef getPassName() const override {
51
0
    return "convert address space of alloca'ed memory to local";
52
0
  }
53
};
54
} // namespace
55
56
char NVPTXLowerAlloca::ID = 1;
57
58
INITIALIZE_PASS(NVPTXLowerAlloca, "nvptx-lower-alloca",
59
                "Lower Alloca", false, false)
60
61
// =============================================================================
62
// Main function for this pass.
63
// =============================================================================
64
1.05k
bool NVPTXLowerAlloca::runOnBasicBlock(BasicBlock &BB) {
65
1.05k
  if (skipBasicBlock(BB))
66
0
    return false;
67
1.05k
68
1.05k
  bool Changed = false;
69
3.66k
  for (auto &I : BB) {
70
3.66k
    if (auto 
allocaInst3.66k
= dyn_cast<AllocaInst>(&I)) {
71
14
      Changed = true;
72
14
      auto PTy = dyn_cast<PointerType>(allocaInst->getType());
73
14
      auto ETy = PTy->getElementType();
74
14
      auto LocalAddrTy = PointerType::get(ETy, ADDRESS_SPACE_LOCAL);
75
14
      auto NewASCToLocal = new AddrSpaceCastInst(allocaInst, LocalAddrTy, "");
76
14
      auto GenericAddrTy = PointerType::get(ETy, ADDRESS_SPACE_GENERIC);
77
14
      auto NewASCToGeneric = new AddrSpaceCastInst(NewASCToLocal,
78
14
                                                    GenericAddrTy, "");
79
14
      NewASCToLocal->insertAfter(allocaInst);
80
14
      NewASCToGeneric->insertAfter(NewASCToLocal);
81
14
      for (Value::use_iterator UI = allocaInst->use_begin(),
82
14
                                UE = allocaInst->use_end();
83
55
            
UI != UE55
; ) {
84
41
        // Check Load, Store, GEP, and BitCast Uses on alloca and make them
85
41
        // use the converted generic address, in order to expose non-generic
86
41
        // addrspacecast to NVPTXInferAddressSpaces. For other types
87
41
        // of instructions this is unnecessary and may introduce redundant
88
41
        // address cast.
89
41
        const auto &AllocaUse = *UI++;
90
41
        auto LI = dyn_cast<LoadInst>(AllocaUse.getUser());
91
41
        if (
LI && 41
LI->getPointerOperand() == allocaInst0
&&
!LI->isVolatile()0
) {
92
0
          LI->setOperand(LI->getPointerOperandIndex(), NewASCToGeneric);
93
0
          continue;
94
0
        }
95
41
        auto SI = dyn_cast<StoreInst>(AllocaUse.getUser());
96
41
        if (
SI && 41
SI->getPointerOperand() == allocaInst11
&&
!SI->isVolatile()11
) {
97
9
          SI->setOperand(SI->getPointerOperandIndex(), NewASCToGeneric);
98
9
          continue;
99
9
        }
100
32
        auto GI = dyn_cast<GetElementPtrInst>(AllocaUse.getUser());
101
32
        if (
GI && 32
GI->getPointerOperand() == allocaInst4
) {
102
4
          GI->setOperand(GI->getPointerOperandIndex(), NewASCToGeneric);
103
4
          continue;
104
4
        }
105
28
        auto BI = dyn_cast<BitCastInst>(AllocaUse.getUser());
106
28
        if (
BI && 28
BI->getOperand(0) == allocaInst3
) {
107
3
          BI->setOperand(0, NewASCToGeneric);
108
3
          continue;
109
3
        }
110
41
      }
111
14
    }
112
3.66k
  }
113
1.05k
  return Changed;
114
1.05k
}
115
116
206
BasicBlockPass *llvm::createNVPTXLowerAllocaPass() {
117
206
  return new NVPTXLowerAlloca();
118
206
}