summaryrefslogtreecommitdiffstats
path: root/polly/lib/CodeGen/IRBuilder.cpp
blob: 2fc8419177420cd5ad26b4a11c79546c03f14b0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//===------ PollyIRBuilder.cpp --------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The Polly IRBuilder file contains Polly specific extensions for the IRBuilder
// that are used e.g. to emit the llvm.loop.parallel metadata.
//
//===----------------------------------------------------------------------===//

#include "polly/CodeGen/IRBuilder.h"

#include "llvm/IR/Metadata.h"
#include "llvm/Support/Debug.h"

using namespace llvm;
using namespace polly;

/// @brief Get the loop id metadata node.
///
/// Each loop is identified by a self referencing metadata node of the form:
///
///    '!n = metadata !{metadata !n}'
///
/// This functions creates such metadata on demand if not yet available.
///
/// @return The loop id metadata node.
static MDNode *getLoopID(Loop *L) {
  Value *Args[] = {0};
  MDNode *LoopID = MDNode::get(L->getHeader()->getContext(), Args);
  LoopID->replaceOperandWith(0, LoopID);
  return LoopID;
}

void polly::LoopAnnotator::pushLoop(Loop *L, bool IsParallel) {
  ActiveLoops.push_back(L);
  if (!IsParallel)
    return;

  BasicBlock *Header = L->getHeader();
  MDNode *Id = getLoopID(L);
  Value *Args[] = {Id};
  MDNode *Ids = ParallelLoops.empty()
                    ? MDNode::get(Header->getContext(), Args)
                    : MDNode::concatenate(ParallelLoops.back(), Id);
  ParallelLoops.push_back(Ids);
}

void polly::LoopAnnotator::popLoop(bool IsParallel) {
  ActiveLoops.pop_back();
  if (!IsParallel)
    return;

  assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
  ParallelLoops.pop_back();
}

void polly::LoopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L,
                                             bool IsParallel) const {
  if (!IsParallel)
    return;

  assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
  MDNode *Ids = ParallelLoops.back();
  MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
  B->setMetadata("llvm.loop", Id);
}

void polly::LoopAnnotator::annotate(Instruction *Inst) {
  if (!Inst->mayReadOrWriteMemory() || ParallelLoops.empty())
    return;

  Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
}
OpenPOWER on IntegriCloud