llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
call_lowering.h
1 // This file if part of the llir-opt project.
2 // Licensing information can be found in the LICENSE file.
3 // (C) 2018 Nandor Licker. All rights reserved.
4 
5 #pragma once
6 
7 #include <llvm/CodeGen/Register.h>
8 #include <llvm/CodeGen/TargetRegisterInfo.h>
9 
10 #include "core/type.h"
11 #include "core/calling_conv.h"
12 #include "core/insts.h"
13 
14 class Func;
15 
16 
17 
21 class CallLowering {
22 public:
24  struct ArgPart {
26  enum Kind {
27  REG,
28  STK,
29  BYVAL,
30  };
31 
35  llvm::MVT VT;
36 
38  llvm::Register Reg = 0u;
39 
41  unsigned Offset = 0;
43  unsigned Size = 0;
45  llvm::Align Align;
46 
47  ArgPart(llvm::MVT vt, llvm::Register reg)
48  : K(Kind::REG), VT(vt), Reg(reg) {}
49 
50  ArgPart(llvm::MVT vt, unsigned offset, unsigned size)
51  : K(Kind::STK), VT(vt), Offset(offset), Size(size) {}
52 
53  ArgPart(llvm::MVT vt, unsigned offset, unsigned size, llvm::Align align)
54  : K(Kind::BYVAL), VT(vt), Offset(offset), Size(size), Align(align) {}
55  };
56 
58  struct ArgLoc {
60  unsigned Index;
62  Type ArgType;
64  llvm::SmallVector<ArgPart, 2> Parts;
65 
66  ArgLoc(unsigned index, FlaggedType argType)
67  : Index(index), ArgType(argType.GetType())
68  {
69  }
70  };
71 
72  // Iterator over the arguments.
73  using arg_iterator = std::vector<ArgLoc>::iterator;
74  using const_arg_iterator = std::vector<ArgLoc>::const_iterator;
75 
77  struct RetPart {
79  llvm::MVT VT;
81  llvm::Register Reg;
82 
83  RetPart(llvm::MVT partVT, llvm::Register reg)
84  : VT(partVT), Reg(reg)
85  {
86  }
87  };
88 
90  struct RetLoc {
92  unsigned Index;
94  llvm::SmallVector<RetPart, 2> Parts;
95 
96  RetLoc(unsigned index) : Index(index) {}
97  };
98 
99  // Iterator over the returns.
100  using ret_iterator = std::vector<RetLoc>::iterator;
101  using const_ret_iterator = std::vector<RetLoc>::const_iterator;
102 
103 public:
104  CallLowering(const Func *func);
105  CallLowering(const CallSite *call);
106  CallLowering(const RaiseInst *inst);
107  CallLowering(const LandingPadInst *inst);
108  CallLowering(const ReturnInst *inst);
109 
110  virtual ~CallLowering();
111 
113  unsigned GetNumArgs() const { return args_.size(); }
115  virtual unsigned GetFrameSize() const = 0;
116 
117  // Iterator over argument info.
118  arg_iterator arg_begin() { return args_.begin(); }
119  arg_iterator arg_end() { return args_.end(); }
120  const_arg_iterator arg_begin() const { return args_.begin(); }
121  const_arg_iterator arg_end() const { return args_.end(); }
122 
124  llvm::iterator_range<arg_iterator> args()
125  {
126  return llvm::make_range(arg_begin(), arg_end());
127  }
128 
130  llvm::iterator_range<const_arg_iterator> args() const
131  {
132  return llvm::make_range(arg_begin(), arg_end());
133  }
134 
136  const ArgLoc &Argument(size_t idx) const { return args_[idx]; }
137 
138  // Iterator over argument info.
139  ret_iterator ret_begin() { return rets_.begin(); }
140  ret_iterator ret_end() { return rets_.end(); }
141  const_ret_iterator ret_begin() const { return rets_.begin(); }
142  const_ret_iterator ret_end() const { return rets_.end(); }
143 
145  llvm::iterator_range<ret_iterator> rets()
146  {
147  return llvm::make_range(ret_begin(), ret_end());
148  }
149 
151  llvm::iterator_range<const_ret_iterator> rets() const
152  {
153  return llvm::make_range(ret_begin(), ret_end());
154  }
155 
157  const RetLoc &Return(unsigned idx) const { return rets_[idx]; }
158 
159 protected:
161  virtual void AssignArgC(unsigned i, FlaggedType type) = 0;
163  virtual void AssignArgOCaml(unsigned i, FlaggedType type) = 0;
165  virtual void AssignArgOCamlAlloc(unsigned i, FlaggedType type) = 0;
167  virtual void AssignArgOCamlGc(unsigned i, FlaggedType type) = 0;
169  virtual void AssignArgXen(unsigned i, FlaggedType type) = 0;
171  virtual void AssignArgMultiboot(unsigned i, FlaggedType type)
172  {
173  llvm_unreachable("no args to multiboot");
174  }
176  virtual void AssignArgWin64(unsigned i, FlaggedType type) = 0;
177 
179  virtual void AssignRetC(unsigned i, FlaggedType type) = 0;
181  virtual void AssignRetOCaml(unsigned i, FlaggedType type) = 0;
183  virtual void AssignRetOCamlAlloc(unsigned i, FlaggedType type) = 0;
185  virtual void AssignRetOCamlGc(unsigned i, FlaggedType type) = 0;
187  virtual void AssignRetXen(unsigned i, FlaggedType type) = 0;
189  virtual void AssignRetWin64(unsigned i, FlaggedType type) = 0;
190 
191 protected:
193  void AnalyseFunc(const Func *func);
195  void AnalyseCall(const CallSite *call);
197  void AnalyseReturn(const ReturnInst *inst);
199  void AnalyseRaise(const RaiseInst *inst);
201  void AnalysePad(const LandingPadInst *inst);
202 
204  void AssignArg(unsigned i, FlaggedType type);
206  void AssignRet(unsigned i, FlaggedType type);
207 
208 protected:
210  CallingConv conv_;
212  std::vector<ArgLoc> args_;
214  std::vector<RetLoc> rets_;
215 };
Func
Definition: func.h:30
CallLowering::GetFrameSize
virtual unsigned GetFrameSize() const =0
Returns the size of the call frame.
CallLowering::conv_
CallingConv conv_
Calling convention.
Definition: call_lowering.h:210
CallLowering::AssignArgMultiboot
virtual void AssignArgMultiboot(unsigned i, FlaggedType type)
Location assignment for multiboot.
Definition: call_lowering.h:171
CallLowering::AssignRetXen
virtual void AssignRetXen(unsigned i, FlaggedType type)=0
Location assignment for Xen hypercalls.
CallLowering::args
llvm::iterator_range< arg_iterator > args()
Returns a range over all arguments.
Definition: call_lowering.h:124
CallLowering::AnalyseFunc
void AnalyseFunc(const Func *func)
Analyse a function.
Definition: call_lowering.cpp:64
CallLowering::AnalyseReturn
void AnalyseReturn(const ReturnInst *inst)
Analyse a return instruction.
Definition: call_lowering.cpp:73
CallLowering::AssignArgC
virtual void AssignArgC(unsigned i, FlaggedType type)=0
Location assignment for C.
CallLowering
Definition: call_lowering.h:21
CallLowering::RetLoc
Location of a return value.
Definition: call_lowering.h:90
CallLowering::args_
std::vector< ArgLoc > args_
Locations where arguments are assigned.
Definition: call_lowering.h:212
CallLowering::AssignArgXen
virtual void AssignArgXen(unsigned i, FlaggedType type)=0
Location assignment for Xen hypercalls.
CallLowering::AnalyseRaise
void AnalyseRaise(const RaiseInst *inst)
Analyse a raise instruction.
Definition: call_lowering.cpp:82
FlaggedType
Definition: type.h:77
CallLowering::ArgLoc::ArgType
Type ArgType
Type of the argument.
Definition: call_lowering.h:62
CallLowering::AssignRetC
virtual void AssignRetC(unsigned i, FlaggedType type)=0
Location assignment for C.
CallLowering::AssignRetOCamlAlloc
virtual void AssignRetOCamlAlloc(unsigned i, FlaggedType type)=0
Location assignment for OCaml to C allocator calls.
CallLowering::AssignRetOCamlGc
virtual void AssignRetOCamlGc(unsigned i, FlaggedType type)=0
Location assignment for OCaml to GC trampolines.
CallLowering::ArgPart::Offset
unsigned Offset
Stack index.
Definition: call_lowering.h:41
CallLowering::ArgPart::Reg
llvm::Register Reg
Register assigned to.
Definition: call_lowering.h:38
CallLowering::rets
llvm::iterator_range< const_ret_iterator > rets() const
Return an immutable range over all returns.
Definition: call_lowering.h:151
CallLowering::AssignArgWin64
virtual void AssignArgWin64(unsigned i, FlaggedType type)=0
Location assignment for Win64.
CallLowering::AnalyseCall
void AnalyseCall(const CallSite *call)
Analyse a call.
Definition: call_lowering.cpp:48
CallLowering::ArgLoc::Index
unsigned Index
Argument index.
Definition: call_lowering.h:60
CallLowering::RetLoc::Parts
llvm::SmallVector< RetPart, 2 > Parts
Parts of the return value.
Definition: call_lowering.h:94
CallLowering::AssignRet
void AssignRet(unsigned i, FlaggedType type)
Assigns a location to a return value based on callig conv.
Definition: call_lowering.cpp:117
CallLowering::ArgPart
Location storing the part of an argument.
Definition: call_lowering.h:24
CallLowering::AssignRetOCaml
virtual void AssignRetOCaml(unsigned i, FlaggedType type)=0
Location assignment for Ocaml.
CallLowering::RetLoc::Index
unsigned Index
Index of the return value.
Definition: call_lowering.h:92
CallLowering::AssignArgOCamlAlloc
virtual void AssignArgOCamlAlloc(unsigned i, FlaggedType type)=0
Location assignment for OCaml to C allocator calls.
CallLowering::ArgPart::Align
llvm::Align Align
Alignment.
Definition: call_lowering.h:45
CallLowering::ArgLoc::Parts
llvm::SmallVector< ArgPart, 2 > Parts
Parts of the argument.
Definition: call_lowering.h:64
CallLowering::AssignRetWin64
virtual void AssignRetWin64(unsigned i, FlaggedType type)=0
Location assignment for Win64 calls.
CallLowering::AnalysePad
void AnalysePad(const LandingPadInst *inst)
Analyse a landing pad instruction.
Definition: call_lowering.cpp:91
CallLowering::GetNumArgs
unsigned GetNumArgs() const
Returns the number of arguments.
Definition: call_lowering.h:113
CallLowering::ArgPart::VT
llvm::MVT VT
Target value type.
Definition: call_lowering.h:35
CallLowering::ArgPart::Size
unsigned Size
Size on stack.
Definition: call_lowering.h:43
CallLowering::Return
const RetLoc & Return(unsigned idx) const
Returns the type of a return value.
Definition: call_lowering.h:157
CallLowering::ArgLoc
Location of an argument.
Definition: call_lowering.h:58
CallLowering::AssignArg
void AssignArg(unsigned i, FlaggedType type)
Assigns a location to an argument based on calling conv.
Definition: call_lowering.cpp:100
CallLowering::args
llvm::iterator_range< const_arg_iterator > args() const
Return an immutable range over all arguments.
Definition: call_lowering.h:130
CallLowering::ArgPart::K
Kind K
Location kind.
Definition: call_lowering.h:33
CallLowering::RetPart::VT
llvm::MVT VT
Original value type.
Definition: call_lowering.h:79
CallLowering::AssignArgOCamlGc
virtual void AssignArgOCamlGc(unsigned i, FlaggedType type)=0
Location assignment for OCaml to GC trampolines.
CallLowering::AssignArgOCaml
virtual void AssignArgOCaml(unsigned i, FlaggedType type)=0
Location assignment for Ocaml.
CallLowering::rets_
std::vector< RetLoc > rets_
Locations where return values are assigned.
Definition: call_lowering.h:214
CallLowering::RetPart::Reg
llvm::Register Reg
Register assigned to.
Definition: call_lowering.h:81
CallLowering::Argument
const ArgLoc & Argument(size_t idx) const
Returns a given argument.
Definition: call_lowering.h:136
CallLowering::rets
llvm::iterator_range< ret_iterator > rets()
Returns a range over all returns.
Definition: call_lowering.h:145
CallLowering::ArgPart::Kind
Kind
Location: register or stack.
Definition: call_lowering.h:26
CallLowering::RetPart
Storage for a return value.
Definition: call_lowering.h:77