OmniSciDB  dfae7c3b14
anonymous_namespace{ResultSetReductionCodegen.cpp} Namespace Reference

Functions

llvm::ICmpInst::Predicate llvm_predicate (const ICmp::Predicate predicate)
 
llvm::BinaryOperator::BinaryOps llvm_binary_op (const BinaryOperator::BinaryOp op)
 
llvm::Instruction::CastOps llvm_cast_op (const Cast::CastOp op)
 
void return_early (llvm::Value *cond, const ReductionCode &reduction_code, llvm::Function *func, llvm::Value *error_code)
 
llvm::Value * mapped_value (const Value *val, const std::unordered_map< const Value *, llvm::Value *> &m)
 
llvm::Function * mapped_function (const Function *function, const std::unordered_map< const Function *, llvm::Function *> &f)
 
std::vector< llvm::Value * > llvm_args (const std::vector< const Value *> args, const std::unordered_map< const Value *, llvm::Value *> &m)
 
void translate_for (const For *for_loop, Function *ir_reduce_loop, const ReductionCode &reduction_code, std::unordered_map< const Value *, llvm::Value *> &m, const std::unordered_map< const Function *, llvm::Function *> &f)
 
void translate_body (const std::vector< std::unique_ptr< Instruction >> &body, const Function *function, llvm::Function *llvm_function, const ReductionCode &reduction_code, std::unordered_map< const Value *, llvm::Value *> &m, const std::unordered_map< const Function *, llvm::Function *> &f)
 
void create_entry_block (llvm::Function *function, CgenState *cgen_state)
 

Function Documentation

◆ create_entry_block()

void anonymous_namespace{ResultSetReductionCodegen.cpp}::create_entry_block ( llvm::Function *  function,
CgenState cgen_state 
)

Definition at line 350 of file ResultSetReductionCodegen.cpp.

References AUTOMATIC_IR_METADATA, CgenState::context_, and CgenState::ir_builder_.

Referenced by translate_function().

350  {
351  AUTOMATIC_IR_METADATA(cgen_state);
352  const auto bb_entry =
353  llvm::BasicBlock::Create(cgen_state->context_, ".entry", function, 0);
354  cgen_state->ir_builder_.SetInsertPoint(bb_entry);
355 }
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
llvm::LLVMContext & context_
Definition: CgenState.h:339
#define AUTOMATIC_IR_METADATA(CGENSTATE)
+ Here is the caller graph for this function:

◆ llvm_args()

std::vector<llvm::Value*> anonymous_namespace{ResultSetReductionCodegen.cpp}::llvm_args ( const std::vector< const Value *>  args,
const std::unordered_map< const Value *, llvm::Value *> &  m 
)

Definition at line 184 of file ResultSetReductionCodegen.cpp.

References mapped_value(), and translate_for().

Referenced by translate_body().

186  {
187  std::vector<llvm::Value*> llvm_args;
188  std::transform(
189  args.begin(), args.end(), std::back_inserter(llvm_args), [&m](const Value* value) {
190  return mapped_value(value, m);
191  });
192  return llvm_args;
193 }
llvm::Value * mapped_value(const Value *val, const std::unordered_map< const Value *, llvm::Value *> &m)
std::vector< llvm::Value * > llvm_args(const std::vector< const Value *> args, const std::unordered_map< const Value *, llvm::Value *> &m)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ llvm_binary_op()

llvm::BinaryOperator::BinaryOps anonymous_namespace{ResultSetReductionCodegen.cpp}::llvm_binary_op ( const BinaryOperator::BinaryOp  op)

Definition at line 99 of file ResultSetReductionCodegen.cpp.

References BinaryOperator::Add, logger::FATAL, LOG, BinaryOperator::Mul, and UNREACHABLE.

Referenced by translate_body().

99  {
100  switch (op) {
102  return llvm::Instruction::Add;
103  }
105  return llvm::Instruction::Mul;
106  }
107  default: {
108  LOG(FATAL) << "Invalid binary operator: " << static_cast<int>(op);
109  }
110  }
111  UNREACHABLE();
112  return llvm::Instruction::Add;
113 }
#define LOG(tag)
Definition: Logger.h:188
#define UNREACHABLE()
Definition: Logger.h:241
+ Here is the caller graph for this function:

◆ llvm_cast_op()

llvm::Instruction::CastOps anonymous_namespace{ResultSetReductionCodegen.cpp}::llvm_cast_op ( const Cast::CastOp  op)

Definition at line 116 of file ResultSetReductionCodegen.cpp.

References Cast::BitCast, logger::FATAL, LOG, Cast::SExt, Cast::Trunc, and UNREACHABLE.

Referenced by translate_body().

116  {
117  switch (op) {
118  case Cast::CastOp::Trunc: {
119  return llvm::Instruction::Trunc;
120  }
121  case Cast::CastOp::SExt: {
122  return llvm::Instruction::SExt;
123  }
124  case Cast::CastOp::BitCast: {
125  return llvm::Instruction::BitCast;
126  }
127  default: {
128  LOG(FATAL) << "Invalid cast operator: " << static_cast<int>(op);
129  }
130  }
131  UNREACHABLE();
132  return llvm::Instruction::SExt;
133 }
#define LOG(tag)
Definition: Logger.h:188
#define UNREACHABLE()
Definition: Logger.h:241
+ Here is the caller graph for this function:

◆ llvm_predicate()

llvm::ICmpInst::Predicate anonymous_namespace{ResultSetReductionCodegen.cpp}::llvm_predicate ( const ICmp::Predicate  predicate)

Definition at line 82 of file ResultSetReductionCodegen.cpp.

References ICmp::EQ, logger::FATAL, LOG, ICmp::NE, and UNREACHABLE.

Referenced by translate_body().

82  {
83  switch (predicate) {
84  case ICmp::Predicate::EQ: {
85  return llvm::ICmpInst::ICMP_EQ;
86  }
87  case ICmp::Predicate::NE: {
88  return llvm::ICmpInst::ICMP_NE;
89  }
90  default: {
91  LOG(FATAL) << "Invalid predicate: " << static_cast<int>(predicate);
92  }
93  }
94  UNREACHABLE();
95  return llvm::ICmpInst::ICMP_EQ;
96 }
#define LOG(tag)
Definition: Logger.h:188
#define UNREACHABLE()
Definition: Logger.h:241
+ Here is the caller graph for this function:

◆ mapped_function()

llvm::Function* anonymous_namespace{ResultSetReductionCodegen.cpp}::mapped_function ( const Function function,
const std::unordered_map< const Function *, llvm::Function *> &  f 
)

Definition at line 174 of file ResultSetReductionCodegen.cpp.

References CHECK.

Referenced by translate_body(), and translate_for().

176  {
177  const auto it = f.find(function);
178  CHECK(it != f.end()) << function->name() << " not found.";
179  return it->second;
180 }
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the caller graph for this function:

◆ mapped_value()

llvm::Value* anonymous_namespace{ResultSetReductionCodegen.cpp}::mapped_value ( const Value val,
const std::unordered_map< const Value *, llvm::Value *> &  m 
)

Definition at line 162 of file ResultSetReductionCodegen.cpp.

References CHECK.

Referenced by llvm_args(), translate_body(), and translate_for().

163  {
164  if (val) {
165  const auto it = m.find(val);
166  CHECK(it != m.end());
167  return it->second;
168  } else {
169  return nullptr;
170  }
171 }
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the caller graph for this function:

◆ return_early()

void anonymous_namespace{ResultSetReductionCodegen.cpp}::return_early ( llvm::Value *  cond,
const ReductionCode reduction_code,
llvm::Function *  func,
llvm::Value *  error_code 
)

Definition at line 139 of file ResultSetReductionCodegen.cpp.

References AUTOMATIC_IR_METADATA, ReductionCode::cgen_state, and CHECK.

Referenced by translate_body().

142  {
143  auto cgen_state = reduction_code.cgen_state.get();
144  AUTOMATIC_IR_METADATA(cgen_state);
145  auto& ctx = cgen_state->context_;
146  const auto early_return = llvm::BasicBlock::Create(ctx, ".early_return", func, 0);
147  const auto do_reduction = llvm::BasicBlock::Create(ctx, ".do_reduction", func, 0);
148  cgen_state->ir_builder_.CreateCondBr(cond, early_return, do_reduction);
149  cgen_state->ir_builder_.SetInsertPoint(early_return);
150 
151  if (func->getReturnType()->isVoidTy()) {
152  cgen_state->ir_builder_.CreateRetVoid();
153  } else {
154  CHECK(error_code);
155  cgen_state->ir_builder_.CreateRet(error_code);
156  }
157 
158  cgen_state->ir_builder_.SetInsertPoint(do_reduction);
159 }
std::unique_ptr< CgenState > cgen_state
const int8_t const int64_t const uint64_t const int32_t const int64_t int64_t uint32_t const int64_t int32_t * error_code
#define AUTOMATIC_IR_METADATA(CGENSTATE)
#define CHECK(condition)
Definition: Logger.h:197
+ Here is the caller graph for this function:

◆ translate_body()

void anonymous_namespace{ResultSetReductionCodegen.cpp}::translate_body ( const std::vector< std::unique_ptr< Instruction >> &  body,
const Function function,
llvm::Function *  llvm_function,
const ReductionCode reduction_code,
std::unordered_map< const Value *, llvm::Value *> &  m,
const std::unordered_map< const Function *, llvm::Function *> &  f 
)

Definition at line 202 of file ResultSetReductionCodegen.cpp.

References run_benchmark_import::args, AUTOMATIC_IR_METADATA, ReductionCode::cgen_state, CHECK, logger::FATAL, ReductionCode::ir_reduce_loop, llvm_args(), llvm_binary_op(), llvm_cast_op(), LLVM_MAYBE_ALIGN, llvm_predicate(), llvm_type(), LOG, mapped_function(), mapped_value(), pointee_type(), return_early(), and translate_for().

Referenced by translate_for(), and translate_function().

207  {
208  auto cgen_state = reduction_code.cgen_state.get();
209  AUTOMATIC_IR_METADATA(cgen_state);
210  auto& ctx = cgen_state->context_;
211  for (const auto& instr : body) {
212  const auto instr_ptr = instr.get();
213  llvm::Value* translated{nullptr};
214  if (auto gep = dynamic_cast<const GetElementPtr*>(instr_ptr)) {
215  translated = cgen_state->ir_builder_.CreateGEP(
216  mapped_value(gep->base(), m), mapped_value(gep->index(), m), gep->label());
217  } else if (auto load = dynamic_cast<const Load*>(instr_ptr)) {
218  translated = cgen_state->ir_builder_.CreateLoad(mapped_value(load->source(), m),
219  load->label());
220  } else if (auto icmp = dynamic_cast<const ICmp*>(instr_ptr)) {
221  translated = cgen_state->ir_builder_.CreateICmp(llvm_predicate(icmp->predicate()),
222  mapped_value(icmp->lhs(), m),
223  mapped_value(icmp->rhs(), m),
224  icmp->label());
225  } else if (auto binary_operator = dynamic_cast<const BinaryOperator*>(instr_ptr)) {
226  translated =
227  cgen_state->ir_builder_.CreateBinOp(llvm_binary_op(binary_operator->op()),
228  mapped_value(binary_operator->lhs(), m),
229  mapped_value(binary_operator->rhs(), m),
230  binary_operator->label());
231  } else if (auto cast = dynamic_cast<const Cast*>(instr_ptr)) {
232  translated = cgen_state->ir_builder_.CreateCast(llvm_cast_op(cast->op()),
233  mapped_value(cast->source(), m),
234  llvm_type(cast->type(), ctx),
235  cast->label());
236  } else if (auto ret = dynamic_cast<const Ret*>(instr_ptr)) {
237  if (ret->value()) {
238  cgen_state->ir_builder_.CreateRet(mapped_value(ret->value(), m));
239  } else {
240  cgen_state->ir_builder_.CreateRetVoid();
241  }
242  } else if (auto call = dynamic_cast<const Call*>(instr_ptr)) {
243  std::vector<llvm::Value*> llvm_args;
244  const auto args = call->arguments();
245  std::transform(args.begin(),
246  args.end(),
247  std::back_inserter(llvm_args),
248  [&m](const Value* value) { return mapped_value(value, m); });
249  if (call->callee()) {
250  translated = cgen_state->ir_builder_.CreateCall(
251  mapped_function(call->callee(), f), llvm_args, call->label());
252  } else {
253  translated = cgen_state->emitCall(call->callee_name(), llvm_args);
254  }
255  } else if (auto external_call = dynamic_cast<const ExternalCall*>(instr_ptr)) {
256  translated = cgen_state->emitExternalCall(external_call->callee_name(),
257  llvm_type(external_call->type(), ctx),
258  llvm_args(external_call->arguments(), m));
259  } else if (auto alloca = dynamic_cast<const Alloca*>(instr_ptr)) {
260  translated = cgen_state->ir_builder_.CreateAlloca(
261  llvm_type(pointee_type(alloca->type()), ctx),
262  mapped_value(alloca->array_size(), m),
263  alloca->label());
264  } else if (auto memcpy = dynamic_cast<const MemCpy*>(instr_ptr)) {
265  cgen_state->ir_builder_.CreateMemCpy(mapped_value(memcpy->dest(), m),
266  LLVM_MAYBE_ALIGN(0),
267  mapped_value(memcpy->source(), m),
268  LLVM_MAYBE_ALIGN(0),
269  mapped_value(memcpy->size(), m));
270  } else if (auto ret_early = dynamic_cast<const ReturnEarly*>(instr_ptr)) {
271  return_early(mapped_value(ret_early->cond(), m),
272  reduction_code,
273  llvm_function,
274  mapped_value(ret_early->error_code(), m));
275  } else if (auto for_loop = dynamic_cast<const For*>(instr_ptr)) {
276  translate_for(for_loop, reduction_code.ir_reduce_loop.get(), reduction_code, m, f);
277  } else {
278  LOG(FATAL) << "Instruction not supported yet";
279  }
280  if (translated) {
281  const auto it_ok = m.emplace(instr_ptr, translated);
282  CHECK(it_ok.second);
283  }
284  }
285 }
std::unique_ptr< CgenState > cgen_state
void translate_for(const For *for_loop, Function *ir_reduce_loop, const ReductionCode &reduction_code, std::unordered_map< const Value *, llvm::Value *> &m, const std::unordered_map< const Function *, llvm::Function *> &f)
std::unique_ptr< Function > ir_reduce_loop
#define LOG(tag)
Definition: Logger.h:188
llvm::ICmpInst::Predicate llvm_predicate(const ICmp::Predicate predicate)
Type pointee_type(const Type pointer)
llvm::Instruction::CastOps llvm_cast_op(const Cast::CastOp op)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Type * llvm_type(const Type type, llvm::LLVMContext &ctx)
void return_early(llvm::Value *cond, const ReductionCode &reduction_code, llvm::Function *func, llvm::Value *error_code)
#define LLVM_MAYBE_ALIGN(alignment)
llvm::Value * mapped_value(const Value *val, const std::unordered_map< const Value *, llvm::Value *> &m)
#define CHECK(condition)
Definition: Logger.h:197
std::vector< llvm::Value * > llvm_args(const std::vector< const Value *> args, const std::unordered_map< const Value *, llvm::Value *> &m)
llvm::Function * mapped_function(const Function *function, const std::unordered_map< const Function *, llvm::Function *> &f)
llvm::BinaryOperator::BinaryOps llvm_binary_op(const BinaryOperator::BinaryOp op)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ translate_for()

void anonymous_namespace{ResultSetReductionCodegen.cpp}::translate_for ( const For for_loop,
Function ir_reduce_loop,
const ReductionCode reduction_code,
std::unordered_map< const Value *, llvm::Value *> &  m,
const std::unordered_map< const Function *, llvm::Function *> &  f 
)

Definition at line 288 of file ResultSetReductionCodegen.cpp.

References AUTOMATIC_IR_METADATA, ReductionCode::cgen_state, JoinLoop::codegen(), For::end(), get_int_type(), INNER, mapped_function(), mapped_value(), For::start(), translate_body(), JoinLoopDomain::upper_bound, and UpperBound.

Referenced by llvm_args(), and translate_body().

292  {
293  auto cgen_state = reduction_code.cgen_state.get();
294  AUTOMATIC_IR_METADATA(cgen_state);
295  const auto bb_entry = cgen_state->ir_builder_.GetInsertBlock();
296  auto& ctx = cgen_state->context_;
297  const auto i64_type = get_int_type(64, cgen_state->context_);
298  const auto end_index = mapped_value(for_loop->end(), m);
299  const auto start_index = mapped_value(for_loop->start(), m);
300  // The start and end indices are absolute. Subtract the start index from the iterator.
301  const auto iteration_count =
302  cgen_state->ir_builder_.CreateSub(end_index, start_index, "iteration_count");
303  const auto upper_bound = cgen_state->ir_builder_.CreateSExt(iteration_count, i64_type);
304  const auto bb_exit =
305  llvm::BasicBlock::Create(ctx, ".exit", mapped_function(ir_reduce_loop, f));
306  JoinLoop join_loop(
309  [upper_bound](const std::vector<llvm::Value*>& v) {
310  JoinLoopDomain domain{{0}};
311  domain.upper_bound = upper_bound;
312  return domain;
313  },
314  nullptr,
315  nullptr,
316  nullptr,
317  "reduction_loop");
318  const auto bb_loop_body = JoinLoop::codegen(
319  {join_loop},
320  [cgen_state, for_loop, ir_reduce_loop, &f, &m, &reduction_code](
321  const std::vector<llvm::Value*>& iterators) {
322  const auto loop_body_bb = llvm::BasicBlock::Create(
323  cgen_state->context_,
324  ".loop_body",
325  cgen_state->ir_builder_.GetInsertBlock()->getParent());
326  cgen_state->ir_builder_.SetInsertPoint(loop_body_bb);
327  // Make the iterator the same type as start and end indices (32-bit integer).
328  const auto loop_iter =
329  cgen_state->ir_builder_.CreateTrunc(iterators.back(),
330  get_int_type(32, cgen_state->context_),
331  "relative_entry_idx");
332  m.emplace(for_loop->iter(), loop_iter);
333  translate_body(for_loop->body(),
334  ir_reduce_loop,
335  mapped_function(ir_reduce_loop, f),
336  reduction_code,
337  m,
338  f);
339  return loop_body_bb;
340  },
341  nullptr,
342  bb_exit,
343  cgen_state);
344  cgen_state->ir_builder_.SetInsertPoint(bb_entry);
345  cgen_state->ir_builder_.CreateBr(bb_loop_body);
346  cgen_state->ir_builder_.SetInsertPoint(bb_exit);
347 }
std::unique_ptr< CgenState > cgen_state
void translate_body(const std::vector< std::unique_ptr< Instruction >> &body, const Function *function, llvm::Function *llvm_function, const ReductionCode &reduction_code, std::unordered_map< const Value *, llvm::Value *> &m, const std::unordered_map< const Function *, llvm::Function *> &f)
const Value * start() const
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
static llvm::BasicBlock * codegen(const std::vector< JoinLoop > &join_loops, const std::function< llvm::BasicBlock *(const std::vector< llvm::Value *> &)> &body_codegen, llvm::Value *outer_iter, llvm::BasicBlock *exit_bb, CgenState *cgen_state)
Definition: JoinLoop.cpp:46
const Value * end() const
#define AUTOMATIC_IR_METADATA(CGENSTATE)
llvm::Value * upper_bound
Definition: JoinLoop.h:44
llvm::Value * mapped_value(const Value *val, const std::unordered_map< const Value *, llvm::Value *> &m)
llvm::Function * mapped_function(const Function *function, const std::unordered_map< const Function *, llvm::Function *> &f)
+ Here is the call graph for this function:
+ Here is the caller graph for this function: