1-- LLVM back-end for ortho. 2-- Copyright (C) 2014 Tristan Gingold 3-- 4-- This program is free software: you can redistribute it and/or modify 5-- it under the terms of the GNU General Public License as published by 6-- the Free Software Foundation, either version 2 of the License, or 7-- (at your option) any later version. 8-- 9-- This program is distributed in the hope that it will be useful, 10-- but WITHOUT ANY WARRANTY; without even the implied warranty of 11-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12-- GNU General Public License for more details. 13-- 14-- You should have received a copy of the GNU General Public License 15-- along with this program. If not, see <gnu.org/licenses>. 16 17with Interfaces; use Interfaces; 18with Interfaces.C; use Interfaces.C; 19with Ortho_Ident; use Ortho_Ident; 20with LLVM.Core; use LLVM.Core; 21with LLVM.TargetMachine; 22with LLVM.Target; 23 24-- Interface to create nodes. 25package Ortho_LLVM is 26 procedure Init; 27 28 -- LLVM specific: the module. 29 Module : ModuleRef; 30 31 -- Descriptor for the layout. 32 Target_Data : LLVM.Target.TargetDataRef; 33 34 Target_Machine : LLVM.TargetMachine.TargetMachineRef; 35 36 -- Optimization level 37 Optimization : LLVM.TargetMachine.CodeGenOptLevel := 38 LLVM.TargetMachine.CodeGenLevelDefault; 39 40private 41 -- No support for nested subprograms in LLVM. 42 Has_Nested_Subprograms : constant Boolean := False; 43 44 type O_Tnode_Type (<>); 45 type O_Tnode is access O_Tnode_Type; 46 O_Tnode_Null : constant O_Tnode := null; 47 48 type ON_Type_Kind is 49 (ON_No_Type, 50 ON_Unsigned_Type, ON_Signed_Type, ON_Enum_Type, ON_Boolean_Type, 51 ON_Float_Type, 52 ON_Array_Type, ON_Array_Sub_Type, 53 ON_Incomplete_Record_Type, 54 ON_Record_Type, ON_Union_Type, 55 ON_Incomplete_Access_Type, ON_Access_Type); 56 57 subtype ON_Scalar_Types is ON_Type_Kind range 58 ON_Unsigned_Type .. ON_Float_Type; 59 60 subtype ON_Integer_Types is ON_Type_Kind range 61 ON_Unsigned_Type .. ON_Boolean_Type; 62 63 type O_Tnode_Type (Kind : ON_Type_Kind := ON_No_Type) is record 64 LLVM : TypeRef; 65 Dbg : ValueRef; 66 case Kind is 67 when ON_No_Type => 68 null; 69 when ON_Union_Type => 70 Un_Size : unsigned; 71 Un_Main_Field : TypeRef; 72 when ON_Access_Type 73 | ON_Incomplete_Access_Type => 74 Acc_Type : O_Tnode; 75 when ON_Scalar_Types => 76 Scal_Size : Natural; 77 when ON_Array_Type 78 | ON_Array_Sub_Type => 79 -- Type of the element 80 Arr_El_Type : O_Tnode; 81 when ON_Record_Type 82 | ON_Incomplete_Record_Type => 83 null; 84 end case; 85 end record; 86 87 type O_Inter; 88 type O_Inter_Acc is access O_Inter; 89 type O_Inter is record 90 Itype : O_Tnode; 91 Ival : ValueRef; 92 Ident : O_Ident; 93 Next : O_Inter_Acc; 94 end record; 95 96 type On_Decl_Kind is 97 (ON_Type_Decl, ON_Completed_Type_Decl, 98 ON_Const_Decl, 99 ON_Var_Decl, ON_Local_Decl, ON_Interface_Decl, 100 ON_Subprg_Decl, 101 ON_No_Decl); 102 103 type O_Dnode (Kind : On_Decl_Kind := ON_No_Decl) is record 104 Dtype : O_Tnode; 105 LLVM : ValueRef; 106 case Kind is 107 when ON_Var_Decl 108 | ON_Const_Decl 109 | ON_Local_Decl => 110 null; 111 when ON_Subprg_Decl => 112 Subprg_Id : O_Ident; 113 Nbr_Args : unsigned; 114 Subprg_Inters : O_Inter_Acc; 115 when ON_Interface_Decl => 116 Inter : O_Inter_Acc; 117 when others => 118 null; 119 end case; 120 end record; 121 122 O_Dnode_Null : constant O_Dnode := (Kind => ON_No_Decl, 123 Dtype => O_Tnode_Null, 124 LLVM => Null_ValueRef); 125 126 type OF_Kind is (OF_None, OF_Record, OF_Union); 127 type O_Fnode (Kind : OF_Kind := OF_None) is record 128 -- Type of the field. 129 Ftype : O_Tnode; 130 case Kind is 131 when OF_None => 132 null; 133 when OF_Record => 134 -- Field index (starting from 0). 135 Index : Natural; 136 when OF_Union => 137 Utype : TypeRef; 138 Ptr_Type : TypeRef; 139 end case; 140 end record; 141 142 O_Fnode_Null : constant O_Fnode := (Kind => OF_None, 143 Ftype => O_Tnode_Null); 144 145 type O_Anode_Type; 146 type O_Anode is access O_Anode_Type; 147 type O_Anode_Type is record 148 Next : O_Anode; 149 Formal : O_Dnode; 150 Actual : O_Enode; 151 end record; 152 153 type O_Cnode is record 154 LLVM : ValueRef; 155 Ctype : O_Tnode; 156 end record; 157 O_Cnode_Null : constant O_Cnode := (LLVM => Null_ValueRef, 158 Ctype => O_Tnode_Null); 159 160 type O_Enode is record 161 LLVM : ValueRef; 162 Etype : O_Tnode; 163 end record; 164 O_Enode_Null : constant O_Enode := (LLVM => Null_ValueRef, 165 Etype => O_Tnode_Null); 166 167 168 type O_Lnode is record 169 -- If True, the LLVM component is the value (used for arguments). 170 -- If False, the LLVM component is the address of the value (used 171 -- for everything else). 172 Direct : Boolean; 173 LLVM : ValueRef; 174 Ltype : O_Tnode; 175 end record; 176 177 O_Lnode_Null : constant O_Lnode := (False, Null_ValueRef, O_Tnode_Null); 178 179 type O_Gnode is record 180 LLVM : ValueRef; 181 Ltype : O_Tnode; 182 end record; 183 184 O_Gnode_Null : constant O_Gnode := (Null_ValueRef, O_Tnode_Null); 185 186 type O_Snode is record 187 -- First BB in the loop body. 188 Bb_Entry : BasicBlockRef; 189 190 -- BB after the loop. 191 Bb_Exit : BasicBlockRef; 192 end record; 193 194 O_Snode_Null : constant O_Snode := (Null_BasicBlockRef, 195 Null_BasicBlockRef); 196 197 type O_Inter_List is record 198 Ident : O_Ident; 199 Storage : O_Storage; 200 Res_Type : O_Tnode; 201 Nbr_Inter : Natural; 202 First_Inter, Last_Inter : O_Inter_Acc; 203 end record; 204 205 type O_Element; 206 type O_Element_Acc is access O_Element; 207 type O_Element is record 208 -- Identifier for the element 209 Ident : O_Ident; 210 211 -- Type of the element 212 Etype : O_Tnode; 213 214 -- Next element (in the linked list) 215 Next : O_Element_Acc; 216 end record; 217 218 -- Record and union builder. 219 type O_Element_List is record 220 Kind : OF_Kind; 221 222 -- Number of fields. 223 Nbr_Elements : Natural; 224 225 -- For record: the access to the incomplete (but named) type. 226 Rec_Type : O_Tnode; 227 228 -- For unions: biggest for size and alignment 229 Size : unsigned; 230 Align : Unsigned_32; 231 Align_Type : TypeRef; 232 233 First_Elem, Last_Elem : O_Element_Acc; 234 end record; 235 236 type ValueRefArray_Acc is access ValueRefArray; 237 238 type O_Record_Aggr_List is record 239 -- Current number of elements in Vals. 240 Len : unsigned; 241 242 -- Value of elements. 243 Vals : ValueRefArray_Acc; 244 245 -- Type of the aggregate. 246 Atype : O_Tnode; 247 end record; 248 249 type O_Array_Aggr_List is record 250 -- Current number of elements in Vals. 251 Len : unsigned; 252 253 -- Value of elements. 254 Vals : ValueRefArray_Acc; 255 El_Type : TypeRef; 256 257 -- Type of the aggregate. 258 Atype : O_Tnode; 259 end record; 260 261 type O_Assoc_List is record 262 Subprg : O_Dnode; 263 Idx : unsigned; 264 Vals : ValueRefArray_Acc; 265 end record; 266 267 type O_Enum_List is record 268 LLVM : TypeRef; 269 Num : Natural; 270 Etype : O_Tnode; 271 end record; 272 273 type O_Choice_Type is record 274 Low, High : ValueRef; 275 Bb : BasicBlockRef; 276 end record; 277 278 type O_Choice_Array is array (Natural range <>) of O_Choice_Type; 279 type O_Choice_Array_Acc is access O_Choice_Array; 280 281 type O_Case_Block is record 282 -- BB before the case. 283 BB_Prev : BasicBlockRef; 284 285 -- Select expression 286 Value : ValueRef; 287 Vtype : O_Tnode; 288 289 -- BB after the case statement. 290 BB_Next : BasicBlockRef; 291 292 -- BB for others 293 BB_Others : BasicBlockRef; 294 295 -- BB for the current choice 296 BB_Choice : BasicBlockRef; 297 298 -- List of choices. 299 Nbr_Choices : Natural; 300 Choices : O_Choice_Array_Acc; 301 end record; 302 303 type O_If_Block is record 304 -- The next basic block. 305 -- After the 'If', this is the BB for the else part. If there is no 306 -- else part, this is the BB for statements after the if. 307 -- After the 'else', this is the BB for statements after the if. 308 Bb : BasicBlockRef; 309 end record; 310 311 function Get_LLVM_Type (Atype : O_Tnode) return TypeRef; 312end Ortho_LLVM; 313