1import contextlib 2import functools 3 4from llvmlite.ir import instructions, types, values 5 6_CMP_MAP = { 7 '>': 'gt', 8 '<': 'lt', 9 '==': 'eq', 10 '!=': 'ne', 11 '>=': 'ge', 12 '<=': 'le', 13} 14 15 16def _binop(opname, cls=instructions.Instruction): 17 def wrap(fn): 18 @functools.wraps(fn) 19 def wrapped(self, lhs, rhs, name='', flags=()): 20 if lhs.type != rhs.type: 21 raise ValueError("Operands must be the same type, got (%s, %s)" 22 % (lhs.type, rhs.type)) 23 instr = cls(self.block, lhs.type, opname, (lhs, rhs), name, flags) 24 self._insert(instr) 25 return instr 26 27 return wrapped 28 29 return wrap 30 31 32def _binop_with_overflow(opname, cls=instructions.Instruction): 33 def wrap(fn): 34 @functools.wraps(fn) 35 def wrapped(self, lhs, rhs, name=''): 36 if lhs.type != rhs.type: 37 raise ValueError("Operands must be the same type, got (%s, %s)" 38 % (lhs.type, rhs.type)) 39 ty = lhs.type 40 if not isinstance(ty, types.IntType): 41 raise TypeError("expected an integer type, got %s" % (ty,)) 42 bool_ty = types.IntType(1) 43 44 mod = self.module 45 fnty = types.FunctionType(types.LiteralStructType([ty, bool_ty]), 46 [ty, ty]) 47 fn = mod.declare_intrinsic("llvm.%s.with.overflow" % (opname,), 48 [ty], fnty) 49 ret = self.call(fn, [lhs, rhs], name=name) 50 return ret 51 52 return wrapped 53 54 return wrap 55 56 57def _uniop(opname, cls=instructions.Instruction): 58 def wrap(fn): 59 @functools.wraps(fn) 60 def wrapped(self, operand, name=''): 61 instr = cls(self.block, operand.type, opname, [operand], name) 62 self._insert(instr) 63 return instr 64 65 return wrapped 66 67 return wrap 68 69 70def _uniop_intrinsic_int(opname): 71 def wrap(fn): 72 @functools.wraps(fn) 73 def wrapped(self, operand, name=''): 74 if not isinstance(operand.type, types.IntType): 75 raise TypeError( 76 "expected an integer type, got %s" % 77 operand.type) 78 fn = self.module.declare_intrinsic(opname, [operand.type]) 79 return self.call(fn, [operand], name) 80 81 return wrapped 82 83 return wrap 84 85 86def _uniop_intrinsic_float(opname): 87 def wrap(fn): 88 @functools.wraps(fn) 89 def wrapped(self, operand, name=''): 90 if not isinstance( 91 operand.type, (types.FloatType, types.DoubleType)): 92 raise TypeError("expected a float type, got %s" % operand.type) 93 fn = self.module.declare_intrinsic(opname, [operand.type]) 94 return self.call(fn, [operand], name) 95 96 return wrapped 97 98 return wrap 99 100 101def _uniop_intrinsic_with_flag(opname): 102 def wrap(fn): 103 @functools.wraps(fn) 104 def wrapped(self, operand, flag, name=''): 105 if not isinstance(operand.type, types.IntType): 106 raise TypeError( 107 "expected an integer type, got %s" % 108 operand.type) 109 if not(isinstance(flag.type, types.IntType) and 110 flag.type.width == 1): 111 raise TypeError("expected an i1 type, got %s" % flag.type) 112 fn = self.module.declare_intrinsic( 113 opname, [operand.type, flag.type]) 114 return self.call(fn, [operand, flag], name) 115 116 return wrapped 117 118 return wrap 119 120 121def _triop_intrinsic(opname): 122 def wrap(fn): 123 @functools.wraps(fn) 124 def wrapped(self, a, b, c, name=''): 125 if a.type != b.type or b.type != c.type: 126 raise TypeError( 127 "expected types to be the same, got %s, %s, %s" % ( 128 a.type, 129 b.type, 130 c.type)) 131 elif not isinstance( 132 a.type, 133 (types.HalfType, types.FloatType, types.DoubleType)): 134 raise TypeError( 135 "expected an floating point type, got %s" % 136 a.type) 137 fn = self.module.declare_intrinsic(opname, [a.type, b.type, c.type]) 138 return self.call(fn, [a, b, c], name) 139 140 return wrapped 141 142 return wrap 143 144 145def _castop(opname, cls=instructions.CastInstr): 146 def wrap(fn): 147 @functools.wraps(fn) 148 def wrapped(self, val, typ, name=''): 149 if val.type == typ: 150 return val 151 instr = cls(self.block, opname, val, typ, name) 152 self._insert(instr) 153 return instr 154 155 return wrapped 156 157 return wrap 158 159 160def _label_suffix(label, suffix): 161 """Returns (label + suffix) or a truncated version if it's too long. 162 Parameters 163 ---------- 164 label : str 165 Label name 166 suffix : str 167 Label suffix 168 """ 169 if len(label) > 50: 170 nhead = 25 171 return ''.join([label[:nhead], '..', suffix]) 172 else: 173 return label + suffix 174 175 176class IRBuilder(object): 177 def __init__(self, block=None): 178 self._block = block 179 self._anchor = len(block.instructions) if block else 0 180 self.debug_metadata = None 181 182 @property 183 def block(self): 184 """ 185 The current basic block. 186 """ 187 return self._block 188 189 basic_block = block 190 191 @property 192 def function(self): 193 """ 194 The current function. 195 """ 196 return self.block.parent 197 198 @property 199 def module(self): 200 """ 201 The current module. 202 """ 203 return self.block.parent.module 204 205 def position_before(self, instr): 206 """ 207 Position immediately before the given instruction. The current block 208 is also changed to the instruction's basic block. 209 """ 210 self._block = instr.parent 211 self._anchor = self._block.instructions.index(instr) 212 213 def position_after(self, instr): 214 """ 215 Position immediately after the given instruction. The current block 216 is also changed to the instruction's basic block. 217 """ 218 self._block = instr.parent 219 self._anchor = self._block.instructions.index(instr) + 1 220 221 def position_at_start(self, block): 222 """ 223 Position at the start of the basic *block*. 224 """ 225 self._block = block 226 self._anchor = 0 227 228 def position_at_end(self, block): 229 """ 230 Position at the end of the basic *block*. 231 """ 232 self._block = block 233 self._anchor = len(block.instructions) 234 235 def append_basic_block(self, name=''): 236 """ 237 Append a basic block, with the given optional *name*, to the current 238 function. The current block is not changed. The new block is returned. 239 """ 240 return self.function.append_basic_block(name) 241 242 def remove(self, instr): 243 """Remove the given instruction.""" 244 idx = self._block.instructions.index(instr) 245 del self._block.instructions[idx] 246 if self._block.terminator == instr: 247 self._block.terminator = None 248 if self._anchor > idx: 249 self._anchor -= 1 250 251 @contextlib.contextmanager 252 def goto_block(self, block): 253 """ 254 A context manager which temporarily positions the builder at the end 255 of basic block *bb* (but before any terminator). 256 """ 257 old_block = self.basic_block 258 term = block.terminator 259 if term is not None: 260 self.position_before(term) 261 else: 262 self.position_at_end(block) 263 try: 264 yield 265 finally: 266 self.position_at_end(old_block) 267 268 @contextlib.contextmanager 269 def goto_entry_block(self): 270 """ 271 A context manager which temporarily positions the builder at the 272 end of the function's entry block. 273 """ 274 with self.goto_block(self.function.entry_basic_block): 275 yield 276 277 @contextlib.contextmanager 278 def _branch_helper(self, bbenter, bbexit): 279 self.position_at_end(bbenter) 280 yield bbexit 281 if self.basic_block.terminator is None: 282 self.branch(bbexit) 283 284 @contextlib.contextmanager 285 def if_then(self, pred, likely=None): 286 """ 287 A context manager which sets up a conditional basic block based 288 on the given predicate (a i1 value). If the conditional block 289 is not explicitly terminated, a branch will be added to the next 290 block. 291 If *likely* is given, its boolean value indicates whether the 292 predicate is likely to be true or not, and metadata is issued 293 for LLVM's optimizers to account for that. 294 """ 295 bb = self.basic_block 296 bbif = self.append_basic_block(name=_label_suffix(bb.name, '.if')) 297 bbend = self.append_basic_block(name=_label_suffix(bb.name, '.endif')) 298 br = self.cbranch(pred, bbif, bbend) 299 if likely is not None: 300 br.set_weights([99, 1] if likely else [1, 99]) 301 302 with self._branch_helper(bbif, bbend): 303 yield bbend 304 305 self.position_at_end(bbend) 306 307 @contextlib.contextmanager 308 def if_else(self, pred, likely=None): 309 """ 310 A context manager which sets up two conditional basic blocks based 311 on the given predicate (a i1 value). 312 A tuple of context managers is yield'ed. Each context manager 313 acts as a if_then() block. 314 *likely* has the same meaning as in if_then(). 315 316 Typical use:: 317 with builder.if_else(pred) as (then, otherwise): 318 with then: 319 # emit instructions for when the predicate is true 320 with otherwise: 321 # emit instructions for when the predicate is false 322 """ 323 bb = self.basic_block 324 bbif = self.append_basic_block(name=_label_suffix(bb.name, '.if')) 325 bbelse = self.append_basic_block(name=_label_suffix(bb.name, '.else')) 326 bbend = self.append_basic_block(name=_label_suffix(bb.name, '.endif')) 327 br = self.cbranch(pred, bbif, bbelse) 328 if likely is not None: 329 br.set_weights([99, 1] if likely else [1, 99]) 330 331 then = self._branch_helper(bbif, bbend) 332 otherwise = self._branch_helper(bbelse, bbend) 333 334 yield then, otherwise 335 336 self.position_at_end(bbend) 337 338 def _insert(self, instr): 339 if self.debug_metadata is not None and 'dbg' not in instr.metadata: 340 instr.metadata['dbg'] = self.debug_metadata 341 self._block.instructions.insert(self._anchor, instr) 342 self._anchor += 1 343 344 def _set_terminator(self, term): 345 assert not self.block.is_terminated 346 self._insert(term) 347 self.block.terminator = term 348 return term 349 350 # 351 # Arithmetic APIs 352 # 353 354 @_binop('shl') 355 def shl(self, lhs, rhs, name=''): 356 """ 357 Left integer shift: 358 name = lhs << rhs 359 """ 360 361 @_binop('lshr') 362 def lshr(self, lhs, rhs, name=''): 363 """ 364 Logical (unsigned) right integer shift: 365 name = lhs >> rhs 366 """ 367 368 @_binop('ashr') 369 def ashr(self, lhs, rhs, name=''): 370 """ 371 Arithmetic (signed) right integer shift: 372 name = lhs >> rhs 373 """ 374 375 @_binop('add') 376 def add(self, lhs, rhs, name=''): 377 """ 378 Integer addition: 379 name = lhs + rhs 380 """ 381 382 @_binop('fadd') 383 def fadd(self, lhs, rhs, name=''): 384 """ 385 Floating-point addition: 386 name = lhs + rhs 387 """ 388 389 @_binop('sub') 390 def sub(self, lhs, rhs, name=''): 391 """ 392 Integer subtraction: 393 name = lhs - rhs 394 """ 395 396 @_binop('fsub') 397 def fsub(self, lhs, rhs, name=''): 398 """ 399 Floating-point subtraction: 400 name = lhs - rhs 401 """ 402 403 @_binop('mul') 404 def mul(self, lhs, rhs, name=''): 405 """ 406 Integer multiplication: 407 name = lhs * rhs 408 """ 409 410 @_binop('fmul') 411 def fmul(self, lhs, rhs, name=''): 412 """ 413 Floating-point multiplication: 414 name = lhs * rhs 415 """ 416 417 @_binop('udiv') 418 def udiv(self, lhs, rhs, name=''): 419 """ 420 Unsigned integer division: 421 name = lhs / rhs 422 """ 423 424 @_binop('sdiv') 425 def sdiv(self, lhs, rhs, name=''): 426 """ 427 Signed integer division: 428 name = lhs / rhs 429 """ 430 431 @_binop('fdiv') 432 def fdiv(self, lhs, rhs, name=''): 433 """ 434 Floating-point division: 435 name = lhs / rhs 436 """ 437 438 @_binop('urem') 439 def urem(self, lhs, rhs, name=''): 440 """ 441 Unsigned integer remainder: 442 name = lhs % rhs 443 """ 444 445 @_binop('srem') 446 def srem(self, lhs, rhs, name=''): 447 """ 448 Signed integer remainder: 449 name = lhs % rhs 450 """ 451 452 @_binop('frem') 453 def frem(self, lhs, rhs, name=''): 454 """ 455 Floating-point remainder: 456 name = lhs % rhs 457 """ 458 459 @_binop('or') 460 def or_(self, lhs, rhs, name=''): 461 """ 462 Bitwise integer OR: 463 name = lhs | rhs 464 """ 465 466 @_binop('and') 467 def and_(self, lhs, rhs, name=''): 468 """ 469 Bitwise integer AND: 470 name = lhs & rhs 471 """ 472 473 @_binop('xor') 474 def xor(self, lhs, rhs, name=''): 475 """ 476 Bitwise integer XOR: 477 name = lhs ^ rhs 478 """ 479 480 @_binop_with_overflow('sadd') 481 def sadd_with_overflow(self, lhs, rhs, name=''): 482 """ 483 Signed integer addition with overflow: 484 name = {result, overflow bit} = lhs + rhs 485 """ 486 487 @_binop_with_overflow('smul') 488 def smul_with_overflow(self, lhs, rhs, name=''): 489 """ 490 Signed integer multiplication with overflow: 491 name = {result, overflow bit} = lhs * rhs 492 """ 493 494 @_binop_with_overflow('ssub') 495 def ssub_with_overflow(self, lhs, rhs, name=''): 496 """ 497 Signed integer subtraction with overflow: 498 name = {result, overflow bit} = lhs - rhs 499 """ 500 501 @_binop_with_overflow('uadd') 502 def uadd_with_overflow(self, lhs, rhs, name=''): 503 """ 504 Unsigned integer addition with overflow: 505 name = {result, overflow bit} = lhs + rhs 506 """ 507 508 @_binop_with_overflow('umul') 509 def umul_with_overflow(self, lhs, rhs, name=''): 510 """ 511 Unsigned integer multiplication with overflow: 512 name = {result, overflow bit} = lhs * rhs 513 """ 514 515 @_binop_with_overflow('usub') 516 def usub_with_overflow(self, lhs, rhs, name=''): 517 """ 518 Unsigned integer subtraction with overflow: 519 name = {result, overflow bit} = lhs - rhs 520 """ 521 522 # 523 # Unary APIs 524 # 525 526 def not_(self, value, name=''): 527 """ 528 Bitwise integer complement: 529 name = ~value 530 """ 531 if isinstance(value.type, types.VectorType): 532 rhs = values.Constant(value.type, (-1,) * value.type.count) 533 else: 534 rhs = values.Constant(value.type, -1) 535 return self.xor(value, rhs, name=name) 536 537 def neg(self, value, name=''): 538 """ 539 Integer negative: 540 name = -value 541 """ 542 return self.sub(values.Constant(value.type, 0), value, name=name) 543 544 # 545 # Comparison APIs 546 # 547 548 def _icmp(self, prefix, cmpop, lhs, rhs, name): 549 try: 550 op = _CMP_MAP[cmpop] 551 except KeyError: 552 raise ValueError("invalid comparison %r for icmp" % (cmpop,)) 553 if cmpop not in ('==', '!='): 554 op = prefix + op 555 instr = instructions.ICMPInstr(self.block, op, lhs, rhs, name=name) 556 self._insert(instr) 557 return instr 558 559 def icmp_signed(self, cmpop, lhs, rhs, name=''): 560 """ 561 Signed integer comparison: 562 name = lhs <cmpop> rhs 563 564 where cmpop can be '==', '!=', '<', '<=', '>', '>=' 565 """ 566 return self._icmp('s', cmpop, lhs, rhs, name) 567 568 def icmp_unsigned(self, cmpop, lhs, rhs, name=''): 569 """ 570 Unsigned integer (or pointer) comparison: 571 name = lhs <cmpop> rhs 572 573 where cmpop can be '==', '!=', '<', '<=', '>', '>=' 574 """ 575 return self._icmp('u', cmpop, lhs, rhs, name) 576 577 def fcmp_ordered(self, cmpop, lhs, rhs, name='', flags=[]): 578 """ 579 Floating-point ordered comparison: 580 name = lhs <cmpop> rhs 581 582 where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno' 583 """ 584 if cmpop in _CMP_MAP: 585 op = 'o' + _CMP_MAP[cmpop] 586 else: 587 op = cmpop 588 instr = instructions.FCMPInstr( 589 self.block, op, lhs, rhs, name=name, flags=flags) 590 self._insert(instr) 591 return instr 592 593 def fcmp_unordered(self, cmpop, lhs, rhs, name='', flags=[]): 594 """ 595 Floating-point unordered comparison: 596 name = lhs <cmpop> rhs 597 598 where cmpop can be '==', '!=', '<', '<=', '>', '>=', 'ord', 'uno' 599 """ 600 if cmpop in _CMP_MAP: 601 op = 'u' + _CMP_MAP[cmpop] 602 else: 603 op = cmpop 604 instr = instructions.FCMPInstr( 605 self.block, op, lhs, rhs, name=name, flags=flags) 606 self._insert(instr) 607 return instr 608 609 def select(self, cond, lhs, rhs, name=''): 610 """ 611 Ternary select operator: 612 name = cond ? lhs : rhs 613 """ 614 instr = instructions.SelectInstr(self.block, cond, lhs, rhs, name=name) 615 self._insert(instr) 616 return instr 617 618 # 619 # Cast APIs 620 # 621 622 @_castop('trunc') 623 def trunc(self, value, typ, name=''): 624 """ 625 Truncating integer downcast to a smaller type: 626 name = (typ) value 627 """ 628 629 @_castop('zext') 630 def zext(self, value, typ, name=''): 631 """ 632 Zero-extending integer upcast to a larger type: 633 name = (typ) value 634 """ 635 636 @_castop('sext') 637 def sext(self, value, typ, name=''): 638 """ 639 Sign-extending integer upcast to a larger type: 640 name = (typ) value 641 """ 642 643 @_castop('fptrunc') 644 def fptrunc(self, value, typ, name=''): 645 """ 646 Floating-point downcast to a less precise type: 647 name = (typ) value 648 """ 649 650 @_castop('fpext') 651 def fpext(self, value, typ, name=''): 652 """ 653 Floating-point upcast to a more precise type: 654 name = (typ) value 655 """ 656 657 @_castop('bitcast') 658 def bitcast(self, value, typ, name=''): 659 """ 660 Pointer cast to a different pointer type: 661 name = (typ) value 662 """ 663 664 @_castop('addrspacecast') 665 def addrspacecast(self, value, typ, name=''): 666 """ 667 Pointer cast to a different address space: 668 name = (typ) value 669 """ 670 671 @_castop('fptoui') 672 def fptoui(self, value, typ, name=''): 673 """ 674 Convert floating-point to unsigned integer: 675 name = (typ) value 676 """ 677 678 @_castop('uitofp') 679 def uitofp(self, value, typ, name=''): 680 """ 681 Convert unsigned integer to floating-point: 682 name = (typ) value 683 """ 684 685 @_castop('fptosi') 686 def fptosi(self, value, typ, name=''): 687 """ 688 Convert floating-point to signed integer: 689 name = (typ) value 690 """ 691 692 @_castop('sitofp') 693 def sitofp(self, value, typ, name=''): 694 """ 695 Convert signed integer to floating-point: 696 name = (typ) value 697 """ 698 699 @_castop('ptrtoint') 700 def ptrtoint(self, value, typ, name=''): 701 """ 702 Cast pointer to integer: 703 name = (typ) value 704 """ 705 706 @_castop('inttoptr') 707 def inttoptr(self, value, typ, name=''): 708 """ 709 Cast integer to pointer: 710 name = (typ) value 711 """ 712 713 # 714 # Memory APIs 715 # 716 717 def alloca(self, typ, size=None, name=''): 718 """ 719 Stack-allocate a slot for *size* elements of the given type. 720 (default one element) 721 """ 722 if size is None: 723 pass 724 elif isinstance(size, (values.Value, values.Constant)): 725 assert isinstance(size.type, types.IntType) 726 else: 727 # If it is not a Value instance, 728 # assume to be a Python integer. 729 size = values.Constant(types.IntType(32), size) 730 731 al = instructions.AllocaInstr(self.block, typ, size, name) 732 self._insert(al) 733 return al 734 735 def load(self, ptr, name='', align=None): 736 """ 737 Load value from pointer, with optional guaranteed alignment: 738 name = *ptr 739 """ 740 if not isinstance(ptr.type, types.PointerType): 741 msg = "cannot load from value of type %s (%r): not a pointer" 742 raise TypeError(msg % (ptr.type, str(ptr))) 743 ld = instructions.LoadInstr(self.block, ptr, name) 744 ld.align = align 745 self._insert(ld) 746 return ld 747 748 def store(self, value, ptr, align=None): 749 """ 750 Store value to pointer, with optional guaranteed alignment: 751 *ptr = name 752 """ 753 if not isinstance(ptr.type, types.PointerType): 754 msg = "cannot store to value of type %s (%r): not a pointer" 755 raise TypeError(msg % (ptr.type, str(ptr))) 756 if ptr.type.pointee != value.type: 757 raise TypeError("cannot store %s to %s: mismatching types" 758 % (value.type, ptr.type)) 759 st = instructions.StoreInstr(self.block, value, ptr) 760 st.align = align 761 self._insert(st) 762 return st 763 764 def load_atomic(self, ptr, ordering, align, name=''): 765 """ 766 Load value from pointer, with optional guaranteed alignment: 767 name = *ptr 768 """ 769 if not isinstance(ptr.type, types.PointerType): 770 msg = "cannot load from value of type %s (%r): not a pointer" 771 raise TypeError(msg % (ptr.type, str(ptr))) 772 ld = instructions.LoadAtomicInstr( 773 self.block, ptr, ordering, align, name) 774 self._insert(ld) 775 return ld 776 777 def store_atomic(self, value, ptr, ordering, align): 778 """ 779 Store value to pointer, with optional guaranteed alignment: 780 *ptr = name 781 """ 782 if not isinstance(ptr.type, types.PointerType): 783 msg = "cannot store to value of type %s (%r): not a pointer" 784 raise TypeError(msg % (ptr.type, str(ptr))) 785 if ptr.type.pointee != value.type: 786 raise TypeError("cannot store %s to %s: mismatching types" 787 % (value.type, ptr.type)) 788 st = instructions.StoreAtomicInstr( 789 self.block, value, ptr, ordering, align) 790 self._insert(st) 791 return st 792 793 # 794 # Terminators APIs 795 # 796 797 def switch(self, value, default): 798 """ 799 Create a switch-case with a single *default* target. 800 """ 801 swt = instructions.SwitchInstr(self.block, 'switch', value, default) 802 self._set_terminator(swt) 803 return swt 804 805 def branch(self, target): 806 """ 807 Unconditional branch to *target*. 808 """ 809 br = instructions.Branch(self.block, "br", [target]) 810 self._set_terminator(br) 811 return br 812 813 def cbranch(self, cond, truebr, falsebr): 814 """ 815 Conditional branch to *truebr* if *cond* is true, else to *falsebr*. 816 """ 817 br = instructions.ConditionalBranch(self.block, "br", 818 [cond, truebr, falsebr]) 819 self._set_terminator(br) 820 return br 821 822 def branch_indirect(self, addr): 823 """ 824 Indirect branch to target *addr*. 825 """ 826 br = instructions.IndirectBranch(self.block, "indirectbr", addr) 827 self._set_terminator(br) 828 return br 829 830 def ret_void(self): 831 """ 832 Return from function without a value. 833 """ 834 return self._set_terminator( 835 instructions.Ret(self.block, "ret void")) 836 837 def ret(self, value): 838 """ 839 Return from function with the given *value*. 840 """ 841 return self._set_terminator( 842 instructions.Ret(self.block, "ret", value)) 843 844 def resume(self, landingpad): 845 """ 846 Resume an in-flight exception. 847 """ 848 br = instructions.Branch(self.block, "resume", [landingpad]) 849 self._set_terminator(br) 850 return br 851 852 # Call APIs 853 854 def call(self, fn, args, name='', cconv=None, tail=False, fastmath=()): 855 """ 856 Call function *fn* with *args*: 857 name = fn(args...) 858 """ 859 inst = instructions.CallInstr(self.block, fn, args, name=name, 860 cconv=cconv, tail=tail, fastmath=fastmath) 861 self._insert(inst) 862 return inst 863 864 def asm(self, ftype, asm, constraint, args, side_effect, name=''): 865 """ 866 Inline assembler. 867 """ 868 asm = instructions.InlineAsm(ftype, asm, constraint, side_effect) 869 return self.call(asm, args, name) 870 871 def load_reg(self, reg_type, reg_name, name=''): 872 """ 873 Load a register value into an LLVM value. 874 Example: v = load_reg(IntType(32), "eax") 875 """ 876 ftype = types.FunctionType(reg_type, []) 877 return self.asm(ftype, "", "={%s}" % reg_name, [], False, name) 878 879 def store_reg(self, value, reg_type, reg_name, name=''): 880 """ 881 Store an LLVM value inside a register 882 Example: 883 store_reg(Constant(IntType(32), 0xAAAAAAAA), IntType(32), "eax") 884 """ 885 ftype = types.FunctionType(types.VoidType(), [reg_type]) 886 return self.asm(ftype, "", "{%s}" % reg_name, [value], True, name) 887 888 def invoke(self, fn, args, normal_to, unwind_to, 889 name='', cconv=None, tail=False): 890 inst = instructions.InvokeInstr(self.block, fn, args, normal_to, 891 unwind_to, name=name, cconv=cconv) 892 self._set_terminator(inst) 893 return inst 894 895 # GEP APIs 896 897 def gep(self, ptr, indices, inbounds=False, name=''): 898 """ 899 Compute effective address (getelementptr): 900 name = getelementptr ptr, <indices...> 901 """ 902 instr = instructions.GEPInstr(self.block, ptr, indices, 903 inbounds=inbounds, name=name) 904 self._insert(instr) 905 return instr 906 907 # Vector Operations APIs 908 909 def extract_element(self, vector, idx, name=''): 910 """ 911 Returns the value at position idx. 912 """ 913 instr = instructions.ExtractElement(self.block, vector, idx, name=name) 914 self._insert(instr) 915 return instr 916 917 def insert_element(self, vector, value, idx, name=''): 918 """ 919 Returns vector with vector[idx] replaced by value. 920 The result is undefined if the idx is larger or equal the vector length. 921 """ 922 instr = instructions.InsertElement(self.block, vector, value, idx, 923 name=name) 924 self._insert(instr) 925 return instr 926 927 def shuffle_vector(self, vector1, vector2, mask, name=''): 928 """ 929 Constructs a permutation of elements from *vector1* and *vector2*. 930 Returns a new vector in the same length of *mask*. 931 932 * *vector1* and *vector2* must have the same element type. 933 * *mask* must be a constant vector of integer types. 934 """ 935 instr = instructions.ShuffleVector(self.block, vector1, vector2, mask, 936 name=name) 937 self._insert(instr) 938 return instr 939 940 # Aggregate APIs 941 942 def extract_value(self, agg, idx, name=''): 943 """ 944 Extract member number *idx* from aggregate. 945 """ 946 if not isinstance(idx, (tuple, list)): 947 idx = [idx] 948 instr = instructions.ExtractValue(self.block, agg, idx, name=name) 949 self._insert(instr) 950 return instr 951 952 def insert_value(self, agg, value, idx, name=''): 953 """ 954 Insert *value* into member number *idx* from aggregate. 955 """ 956 if not isinstance(idx, (tuple, list)): 957 idx = [idx] 958 instr = instructions.InsertValue(self.block, agg, value, idx, name=name) 959 self._insert(instr) 960 return instr 961 962 # PHI APIs 963 964 def phi(self, typ, name=''): 965 inst = instructions.PhiInstr(self.block, typ, name=name) 966 self._insert(inst) 967 return inst 968 969 # Special API 970 971 def unreachable(self): 972 inst = instructions.Unreachable(self.block) 973 self._set_terminator(inst) 974 return inst 975 976 def atomic_rmw(self, op, ptr, val, ordering, name=''): 977 inst = instructions.AtomicRMW( 978 self.block, op, ptr, val, ordering, name=name) 979 self._insert(inst) 980 return inst 981 982 def cmpxchg(self, ptr, cmp, val, ordering, failordering=None, name=''): 983 """ 984 Atomic compared-and-set: 985 atomic { 986 old = *ptr 987 success = (old == cmp) 988 if (success) 989 *ptr = val 990 } 991 name = { old, success } 992 993 If failordering is `None`, the value of `ordering` is used. 994 """ 995 failordering = ordering if failordering is None else failordering 996 inst = instructions.CmpXchg(self.block, ptr, cmp, val, ordering, 997 failordering, name=name) 998 self._insert(inst) 999 return inst 1000 1001 def landingpad(self, typ, name='', cleanup=False): 1002 inst = instructions.LandingPadInstr(self.block, typ, name, cleanup) 1003 self._insert(inst) 1004 return inst 1005 1006 def assume(self, cond): 1007 """ 1008 Optimizer hint: assume *cond* is always true. 1009 """ 1010 fn = self.module.declare_intrinsic("llvm.assume") 1011 return self.call(fn, [cond]) 1012 1013 def fence(self, ordering, targetscope=None, name=''): 1014 """ 1015 Add a memory barrier, preventing certain reorderings of load and/or 1016 store accesses with 1017 respect to other processors and devices. 1018 """ 1019 inst = instructions.Fence(self.block, ordering, targetscope, name=name) 1020 self._insert(inst) 1021 return inst 1022 1023 @_uniop_intrinsic_int("llvm.bswap") 1024 def bswap(self, cond): 1025 """ 1026 Used to byte swap integer values with an even number of bytes (positive 1027 multiple of 16 bits) 1028 """ 1029 1030 @_uniop_intrinsic_int("llvm.bitreverse") 1031 def bitreverse(self, cond): 1032 """ 1033 Reverse the bitpattern of an integer value; for example 0b10110110 1034 becomes 0b01101101. 1035 """ 1036 1037 @_uniop_intrinsic_int("llvm.ctpop") 1038 def ctpop(self, cond): 1039 """ 1040 Counts the number of bits set in a value. 1041 """ 1042 1043 @_uniop_intrinsic_with_flag("llvm.ctlz") 1044 def ctlz(self, cond, flag): 1045 """ 1046 Counts leading zero bits in *value*. Boolean *flag* indicates whether 1047 the result is defined for ``0``. 1048 """ 1049 1050 @_uniop_intrinsic_with_flag("llvm.cttz") 1051 def cttz(self, cond, flag): 1052 """ 1053 Counts trailing zero bits in *value*. Boolean *flag* indicates whether 1054 the result is defined for ``0``. 1055 """ 1056 1057 @_triop_intrinsic("llvm.fma") 1058 def fma(self, a, b, c): 1059 """ 1060 Perform the fused multiply-add operation. 1061 """ 1062 1063 def convert_from_fp16(self, a, to=None, name=''): 1064 """ 1065 Convert from an i16 to the given FP type 1066 """ 1067 if not to: 1068 raise TypeError("expected a float return type") 1069 if not isinstance(to, (types.FloatType, types.DoubleType)): 1070 raise TypeError("expected a float type, got %s" % to) 1071 if not (isinstance(a.type, types.IntType) and a.type.width == 16): 1072 raise TypeError("expected an i16 type, got %s" % a.type) 1073 1074 opname = 'llvm.convert.from.fp16' 1075 fn = self.module.declare_intrinsic(opname, [to]) 1076 return self.call(fn, [a], name) 1077 1078 @_uniop_intrinsic_float("llvm.convert.to.fp16") 1079 def convert_to_fp16(self, a): 1080 """ 1081 Convert the given FP number to an i16 1082 """ 1083