~ryan-rmarcus/pocl/pocl

« back to all changes in this revision

Viewing changes to lib/llvmopencl/CanonicalizeBarriers.cc

  • Committer: Carlos Sánchez de La Lama
  • Date: 2011-11-11 11:51:00 UTC
  • mfrom: (57.1.16 pocl.loopbarriers)
  • Revision ID: carlos.delalama@urjc.es-20111111115100-mcchrwx8o16g0ymc
Merge.
Barriers in for loops are still not fully tested but I merge to
include the ReferenceMap indexing fix in trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// LLVM function pass to canonicalize barriers.
 
2
// 
 
3
// Copyright (c) 2011 Universidad Rey Juan Carlos
 
4
// 
 
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
6
// of this software and associated documentation files (the "Software"), to deal
 
7
// in the Software without restriction, including without limitation the rights
 
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
9
// copies of the Software, and to permit persons to whom the Software is
 
10
// furnished to do so, subject to the following conditions:
 
11
// 
 
12
// The above copyright notice and this permission notice shall be included in
 
13
// all copies or substantial portions of the Software.
 
14
// 
 
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
21
// THE SOFTWARE.
 
22
 
 
23
#include "CanonicalizeBarriers.h"
 
24
#include "llvm/ADT/SmallString.h"
 
25
#include "llvm/Instructions.h"
 
26
 
 
27
using namespace llvm;
 
28
using namespace pocl;
 
29
 
 
30
#define BARRIER_FUNCTION_NAME "barrier"
 
31
 
 
32
namespace {
 
33
  static
 
34
  RegisterPass<CanonicalizeBarriers> X("barriers",
 
35
                                       "Barrier canizalization pass");
 
36
}
 
37
 
 
38
char CanonicalizeBarriers::ID = 0;
 
39
 
 
40
void
 
41
CanonicalizeBarriers::getAnalysisUsage(AnalysisUsage &AU) const
 
42
{
 
43
  AU.addRequired<LoopInfo>();
 
44
  AU.addPreserved<LoopInfo>();
 
45
}
 
46
 
 
47
bool
 
48
CanonicalizeBarriers::runOnFunction(Function &F)
 
49
{
 
50
  LI = &getAnalysis<LoopInfo>();
 
51
 
 
52
  return ProcessFunction(F);
 
53
}
 
54
 
 
55
// Canonicalize barriers: ensure all barriers are in a separate BB
 
56
// containint only the barrier and the terminator, with just one
 
57
// predecessor and one successor. This allows us to use
 
58
// those BBs as markers only, they will not be replicated.
 
59
bool
 
60
CanonicalizeBarriers::ProcessFunction(Function &F)
 
61
{
 
62
  bool changed = false;
 
63
 
 
64
  InstructionSet PreSplitPoints;
 
65
  InstructionSet PostSplitPoints;
 
66
  InstructionSet BarriersToAdd;
 
67
 
 
68
  CallInst *barrier = NULL;
 
69
 
 
70
  for (Function::iterator i = F.begin(), e = F.end();
 
71
       i != e; ++i) {
 
72
    BasicBlock *b = i;
 
73
    for (BasicBlock::iterator i = b->begin(), e = b->end();
 
74
         i != e; ++i) {
 
75
      if (CallInst *c = dyn_cast<CallInst>(i)) {
 
76
        if (Function *f = c->getCalledFunction()) {
 
77
          if (f->getName().equals(BARRIER_FUNCTION_NAME)) {
 
78
            barrier = c;
 
79
            
 
80
            // We found a barrier, add the split points.
 
81
            BasicBlock::iterator j = i;
 
82
            PreSplitPoints.insert(j);
 
83
            PostSplitPoints.insert(++j);
 
84
            
 
85
            // Is this barrier inside of a loop?
 
86
            Loop *loop = LI->getLoopFor(b);
 
87
            if (loop != NULL) {
 
88
              // We need loops to be canonicalized.  If the barrier
 
89
              // is in a loop, add a barrier in the preheader.
 
90
              BasicBlock *preheader = loop->getLoopPreheader();
 
91
              assert(preheader != NULL);
 
92
              Instruction *new_barrier = barrier->clone();
 
93
              new_barrier->insertBefore(preheader->getFirstNonPHI());
 
94
              changed = true;
 
95
              // No split point after preheader barriers, so we ensure
 
96
              // WI 0,0,0 starts at the loop header.  But still we need
 
97
              // a split before.
 
98
              PreSplitPoints.insert(new_barrier);
 
99
 
 
100
              // Add barriers before any loop backedge.  This
 
101
              // is to ensure all workitems run to the end of the loop
 
102
              // (because otherwise first WI will jump back to the
 
103
              // header and other WIs will skip portion of the
 
104
              // loop body).
 
105
              // We cannot add the barriers directly here to avoid
 
106
              // processing them when going on trough the loop, schedule
 
107
              // them to be added later. 
 
108
              BasicBlock *latch = loop->getLoopLatch();
 
109
              assert(latch != NULL);
 
110
              BarriersToAdd.insert(latch->getTerminator());
 
111
            }
 
112
          }
 
113
        }
 
114
      }
 
115
    }
 
116
  }
 
117
 
 
118
  // Add scheduled barriers.
 
119
  for (InstructionSet::iterator i = BarriersToAdd.begin(), e = BarriersToAdd.end();
 
120
       i != e; ++i) {
 
121
    assert(barrier != NULL);
 
122
    Instruction *new_barrier = barrier->clone();
 
123
    new_barrier->insertBefore(*i);
 
124
    changed = true;
 
125
    BasicBlock::iterator j = new_barrier;
 
126
    PreSplitPoints.insert(j);
 
127
    PostSplitPoints.insert(++j);
 
128
  }
 
129
 
 
130
  // Finally add all the split points, now that we are done with the
 
131
  // iterators.
 
132
  for (InstructionSet::iterator i = PreSplitPoints.begin(), e = PreSplitPoints.end();
 
133
       i != e; ++i) {
 
134
    BasicBlock *b = (*i)->getParent();
 
135
    BasicBlock *new_b = b->splitBasicBlock(*i);
 
136
    new_b->takeName(b);
 
137
    b->setName(new_b->getName() + ".prebarrier");
 
138
    Loop *l = LI->getLoopFor(b);
 
139
    if (l)
 
140
      l->addBasicBlockToLoop(new_b, LI->getBase());
 
141
    changed = true;
 
142
  }
 
143
  for (InstructionSet::iterator i = PostSplitPoints.begin(), e = PostSplitPoints.end();
 
144
       i != e; ++i) {
 
145
    BasicBlock *b = (*i)->getParent();
 
146
    BasicBlock *new_b = b->splitBasicBlock(*i, b->getName() + ".postbarrier");
 
147
    Loop *l = LI->getLoopFor(b);
 
148
    if (l)
 
149
      l->addBasicBlockToLoop(new_b, LI->getBase());
 
150
    changed = true;
 
151
  }
 
152
 
 
153
  LI->verifyAnalysis();
 
154
  
 
155
  return changed;
 
156
}