Jlm
GetElementPtr.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #ifndef JLM_LLVM_IR_OPERATORS_GETELEMENTPTR_HPP
7 #define JLM_LLVM_IR_OPERATORS_GETELEMENTPTR_HPP
8 
9 #include <jlm/llvm/ir/tac.hpp>
10 #include <jlm/llvm/ir/types.hpp>
13 
14 namespace jlm::llvm
15 {
16 
24 {
25 public:
26  ~GetElementPtrOperation() noexcept override;
27 
28 public:
30  const std::vector<std::shared_ptr<const rvsdg::BitType>> & offsetTypes,
31  std::shared_ptr<const rvsdg::Type> pointeeType)
33  PointeeType_(std::move(pointeeType))
34  {}
35 
37 
38  GetElementPtrOperation(GetElementPtrOperation && other) noexcept = default;
39 
40  bool
41  operator==(const Operation & other) const noexcept override;
42 
43  [[nodiscard]] std::string
44  debug_string() const override;
45 
46  [[nodiscard]] std::unique_ptr<Operation>
47  copy() const override;
48 
49  [[nodiscard]] const rvsdg::Type &
50  GetPointeeType() const noexcept
51  {
52  return *PointeeType_.get();
53  }
54 
68  static std::unique_ptr<llvm::ThreeAddressCode>
70  const Variable * baseAddress,
71  const std::vector<const Variable *> & offsets,
72  std::shared_ptr<const rvsdg::Type> pointeeType,
73  std::shared_ptr<const rvsdg::Type> resultType)
74  {
75  CheckPointerType(baseAddress->type());
76  auto offsetTypes = CheckAndExtractOffsetTypes<const Variable>(offsets);
77  CheckPointerType(*resultType);
78 
79  auto operation = std::make_unique<GetElementPtrOperation>(offsetTypes, std::move(pointeeType));
80  std::vector<const Variable *> operands(1, baseAddress);
81  operands.insert(operands.end(), offsets.begin(), offsets.end());
82 
83  return ThreeAddressCode::create(std::move(operation), operands);
84  }
85 
99  static rvsdg::Output *
101  rvsdg::Output * baseAddress,
102  const std::vector<rvsdg::Output *> & offsets,
103  std::shared_ptr<const rvsdg::Type> pointeeType,
104  std::shared_ptr<const rvsdg::Type> resultType)
105  {
106  CheckPointerType(*baseAddress->Type());
107  auto offsetTypes = CheckAndExtractOffsetTypes<rvsdg::Output>(offsets);
108  CheckPointerType(*resultType);
109 
110  std::vector operands(1, baseAddress);
111  operands.insert(operands.end(), offsets.begin(), offsets.end());
112 
113  return rvsdg::CreateOpNode<GetElementPtrOperation>(
114  operands,
115  offsetTypes,
116  std::move(pointeeType))
117  .output(0);
118  }
119 
120 private:
121  static void
123  {
124  if (!is<PointerType>(type))
125  {
126  throw util::Error("Expected pointer type.");
127  }
128  }
129 
130  template<class T>
131  static std::vector<std::shared_ptr<const rvsdg::BitType>>
132  CheckAndExtractOffsetTypes(const std::vector<T *> & offsets)
133  {
134  std::vector<std::shared_ptr<const rvsdg::BitType>> offsetTypes;
135  for (const auto & offset : offsets)
136  {
137  if (auto offsetType = std::dynamic_pointer_cast<const rvsdg::BitType>(offset->Type()))
138  {
139  offsetTypes.emplace_back(std::move(offsetType));
140  continue;
141  }
142 
143  throw util::Error("Expected bitstring type.");
144  }
145 
146  return offsetTypes;
147  }
148 
149  static std::vector<std::shared_ptr<const rvsdg::Type>>
150  CreateOperandTypes(const std::vector<std::shared_ptr<const rvsdg::BitType>> & indexTypes)
151  {
152  std::vector<std::shared_ptr<const rvsdg::Type>> types({ PointerType::Create() });
153  types.insert(types.end(), indexTypes.begin(), indexTypes.end());
154 
155  return types;
156  }
157 
158  std::shared_ptr<const rvsdg::Type> PointeeType_;
159 };
160 
161 }
162 
163 #endif
std::string debug_string() const override
GetElementPtrOperation(GetElementPtrOperation &&other) noexcept=default
GetElementPtrOperation(const GetElementPtrOperation &other)=default
bool operator==(const Operation &other) const noexcept override
std::shared_ptr< const rvsdg::Type > PointeeType_
const rvsdg::Type & GetPointeeType() const noexcept
static void CheckPointerType(const rvsdg::Type &type)
~GetElementPtrOperation() noexcept override
static std::vector< std::shared_ptr< const rvsdg::BitType > > CheckAndExtractOffsetTypes(const std::vector< T * > &offsets)
static rvsdg::Output * Create(rvsdg::Output *baseAddress, const std::vector< rvsdg::Output * > &offsets, std::shared_ptr< const rvsdg::Type > pointeeType, std::shared_ptr< const rvsdg::Type > resultType)
std::unique_ptr< Operation > copy() const override
static std::vector< std::shared_ptr< const rvsdg::Type > > CreateOperandTypes(const std::vector< std::shared_ptr< const rvsdg::BitType >> &indexTypes)
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *baseAddress, const std::vector< const Variable * > &offsets, std::shared_ptr< const rvsdg::Type > pointeeType, std::shared_ptr< const rvsdg::Type > resultType)
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
Definition: tac.hpp:135
const jlm::rvsdg::Type & type() const noexcept
Definition: variable.hpp:56
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition: node.hpp:366
SimpleOperation(std::vector< std::shared_ptr< const jlm::rvsdg::Type >> operands, std::vector< std::shared_ptr< const jlm::rvsdg::Type >> results)
Definition: operation.hpp:61
Global memory state passed between functions.
static std::string type(const Node *n)
Definition: view.cpp:255
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049