comparison src/pt-jit.h @ 14980:bb1f3a9bb122

Reduce code duplication in JIT * src/pt-jit.h (jit_function::overload::overload, jit_function::add_overload, jit_typeinfo::create_function, jit_instruction::jit_instruction, jit_terminator::jit_terminator, jit_call::jit_call, jit_convert::create, jit_convert::create_checked): Define similar overloads with macros. (jit_terminator::branch_llm): Remove dead function. (jit_terminator::successor_llvm): Remove dead code. * liboctave/lo-macros.h (OCT_MAKE_ARG_LIST): New macro.
author Max Brister <max@2bass.com>
date Thu, 05 Jul 2012 17:25:25 -0500
parents f649b66ef1af
children a5f75de0dab1
comparison
equal deleted inserted replaced
14979:8b4606e3be32 14980:bb1f3a9bb122
318 struct 318 struct
319 overload 319 overload
320 { 320 {
321 overload (void) : function (0), can_error (false), result (0) {} 321 overload (void) : function (0), can_error (false), result (0) {}
322 322
323 overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0) : 323 #define ASSIGN_ARG(i) arguments[i] = arg ## i;
324 function (f), can_error (e), result (r), arguments (1) 324 #define OVERLOAD_CTOR(N) \
325 { 325 overload (llvm::Function *f, bool e, jit_type *ret, \
326 arguments[0] = arg0; 326 OCT_MAKE_DECL_LIST (jit_type *, arg, N)) \
327 : function (f), can_error (e), result (ret), arguments (N) \
328 { \
329 OCT_ITERATE_MACRO (ASSIGN_ARG, N); \
327 } 330 }
328 331
329 overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0, 332 OVERLOAD_CTOR (1)
330 jit_type *arg1) : function (f), can_error (e), 333 OVERLOAD_CTOR (2)
331 result (r), arguments (2) 334 OVERLOAD_CTOR (3)
332 { 335
333 arguments[0] = arg0; 336 #undef ASSIGN_ARG
334 arguments[1] = arg1; 337 #undef OVERLOAD_CTOR
335 }
336
337 overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0,
338 jit_type *arg1, jit_type *arg2) : function (f), can_error (e),
339 result (r), arguments (3)
340 {
341 arguments[0] = arg0;
342 arguments[1] = arg1;
343 arguments[2] = arg2;
344 }
345 338
346 overload (llvm::Function *f, bool e, jit_type *r, 339 overload (llvm::Function *f, bool e, jit_type *r,
347 const std::vector<jit_type *>& aarguments) 340 const std::vector<jit_type *>& aarguments)
348 : function (f), can_error (e), result (r), arguments (aarguments) 341 : function (f), can_error (e), result (r), arguments (aarguments)
349 {} 342 {}
357 void add_overload (const overload& func) 350 void add_overload (const overload& func)
358 { 351 {
359 add_overload (func, func.arguments); 352 add_overload (func, func.arguments);
360 } 353 }
361 354
362 void add_overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0) 355 #define ADD_OVERLOAD(N) \
363 { 356 void add_overload (llvm::Function *f, bool e, jit_type *ret, \
364 overload ol (f, e, r, arg0); 357 OCT_MAKE_DECL_LIST (jit_type *, arg, N)) \
365 add_overload (ol); 358 { \
366 } 359 overload ol (f, e, ret, OCT_MAKE_ARG_LIST (arg, N)); \
367 360 add_overload (ol); \
368 void add_overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0, 361 }
369 jit_type *arg1) 362
370 { 363 ADD_OVERLOAD (1);
371 overload ol (f, e, r, arg0, arg1); 364 ADD_OVERLOAD (2);
372 add_overload (ol); 365 ADD_OVERLOAD (3);
373 } 366
374 367 #undef ADD_OVERLOAD
375 void add_overload (llvm::Function *f, bool e, jit_type *r, jit_type *arg0,
376 jit_type *arg1, jit_type *arg2)
377 {
378 overload ol (f, e, r, arg0, arg1, arg2);
379 add_overload (ol);
380 }
381 368
382 void add_overload (llvm::Function *f, bool e, jit_type *r, 369 void add_overload (llvm::Function *f, bool e, jit_type *r,
383 const std::vector<jit_type *>& args) 370 const std::vector<jit_type *>& args)
384 { 371 {
385 overload ol (f, e, r, args); 372 overload ol (f, e, r, args);
618 605
619 void add_binary_icmp (jit_type *ty, int op, int llvm_op); 606 void add_binary_icmp (jit_type *ty, int op, int llvm_op);
620 607
621 void add_binary_fcmp (jit_type *ty, int op, int llvm_op); 608 void add_binary_fcmp (jit_type *ty, int op, int llvm_op);
622 609
610
623 llvm::Function *create_function (const llvm::Twine& name, llvm::Type *ret) 611 llvm::Function *create_function (const llvm::Twine& name, llvm::Type *ret)
624 { 612 {
625 std::vector<llvm::Type *> args; 613 std::vector<llvm::Type *> args;
626 return create_function (name, ret, args); 614 return create_function (name, ret, args);
627 } 615 }
628 616
629 llvm::Function *create_function (const llvm::Twine& name, llvm::Type *ret, 617 #define ASSIGN_ARG(i) args[i] = arg ## i;
630 llvm::Type *arg0) 618 #define CREATE_FUNCTIONT(TYPE, N) \
631 { 619 llvm::Function *create_function (const llvm::Twine& name, TYPE *ret, \
632 std::vector<llvm::Type *> args (1, arg0); 620 OCT_MAKE_DECL_LIST (TYPE *, arg, N)) \
633 return create_function (name, ret, args); 621 { \
634 } 622 std::vector<TYPE *> args (N); \
635 623 OCT_ITERATE_MACRO (ASSIGN_ARG, N); \
636 llvm::Function *create_function (const llvm::Twine& name, jit_type *ret, 624 return create_function (name, ret, args); \
637 jit_type *arg0) 625 }
638 { 626
639 return create_function (name, ret->to_llvm (), arg0->to_llvm ()); 627 #define CREATE_FUNCTION(N) \
640 } 628 CREATE_FUNCTIONT(llvm::Type, N) \
641 629 CREATE_FUNCTIONT(jit_type, N)
642 llvm::Function *create_function (const llvm::Twine& name, llvm::Type *ret, 630
643 llvm::Type *arg0, llvm::Type *arg1) 631 CREATE_FUNCTION(1)
644 { 632 CREATE_FUNCTION(2)
645 std::vector<llvm::Type *> args (2); 633 CREATE_FUNCTION(3)
646 args[0] = arg0; 634 CREATE_FUNCTION(4)
647 args[1] = arg1; 635
648 return create_function (name, ret, args); 636 #undef ASSIGN_ARG
649 } 637 #undef CREATE_FUNCTIONT
650 638 #undef CREATE_FUNCTION
651 llvm::Function *create_function (const llvm::Twine& name, jit_type *ret,
652 jit_type *arg0, jit_type *arg1)
653 {
654 return create_function (name, ret->to_llvm (), arg0->to_llvm (),
655 arg1->to_llvm ());
656 }
657
658 llvm::Function *create_function (const llvm::Twine& name, llvm::Type *ret,
659 llvm::Type *arg0, llvm::Type *arg1,
660 llvm::Type *arg2)
661 {
662 std::vector<llvm::Type *> args (3);
663 args[0] = arg0;
664 args[1] = arg1;
665 args[2] = arg2;
666 return create_function (name, ret, args);
667 }
668
669 llvm::Function *create_function (const llvm::Twine& name, jit_type *ret,
670 jit_type *arg0, jit_type *arg1,
671 jit_type *arg2)
672 {
673 return create_function (name, ret->to_llvm (), arg0->to_llvm (),
674 arg1->to_llvm (), arg2->to_llvm ());
675 }
676
677 llvm::Function *create_function (const llvm::Twine& name, llvm::Type *ret,
678 llvm::Type *arg0, llvm::Type *arg1,
679 llvm::Type *arg2, llvm::Type *arg3)
680 {
681 std::vector<llvm::Type *> args (4);
682 args[0] = arg0;
683 args[1] = arg1;
684 args[2] = arg2;
685 args[3] = arg3;
686 return create_function (name, ret, args);
687 }
688 639
689 llvm::Function *create_function (const llvm::Twine& name, jit_type *ret, 640 llvm::Function *create_function (const llvm::Twine& name, jit_type *ret,
690 const std::vector<jit_type *>& args); 641 const std::vector<jit_type *>& args);
691 642
692 llvm::Function *create_function (const llvm::Twine& name, llvm::Type *ret, 643 llvm::Function *create_function (const llvm::Twine& name, llvm::Type *ret,
956 public: 907 public:
957 // FIXME: this code could be so much pretier with varadic templates... 908 // FIXME: this code could be so much pretier with varadic templates...
958 jit_instruction (void) : mid (next_id ()), mparent (0) 909 jit_instruction (void) : mid (next_id ()), mparent (0)
959 {} 910 {}
960 911
961 jit_instruction (size_t nargs) 912 jit_instruction (size_t nargs) : mid (next_id ()), mparent (0)
962 : already_infered (nargs, reinterpret_cast<jit_type *>(0)), 913 {
963 mid (next_id ()), mparent (0) 914 already_infered.reserve (nargs);
964 {
965 marguments.reserve (nargs); 915 marguments.reserve (nargs);
966 } 916 }
967 917
968 jit_instruction (jit_value *arg0) 918 #define STASH_ARG(i) stash_argument (i, arg ## i);
969 : already_infered (1, reinterpret_cast<jit_type *>(0)), marguments (1), 919 #define JIT_INSTRUCTION_CTOR(N) \
970 mid (next_id ()), mparent (0) 920 jit_instruction (OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \
971 { 921 : already_infered (N), marguments (N), mid (next_id ()), mparent (0) \
972 stash_argument (0, arg0); 922 { \
973 } 923 OCT_ITERATE_MACRO (STASH_ARG, N); \
974 924 }
975 jit_instruction (jit_value *arg0, jit_value *arg1) 925
976 : already_infered (2, reinterpret_cast<jit_type *>(0)), marguments (2), 926 JIT_INSTRUCTION_CTOR(1)
977 mid (next_id ()), mparent (0) 927 JIT_INSTRUCTION_CTOR(2)
978 { 928 JIT_INSTRUCTION_CTOR(3)
979 stash_argument (0, arg0); 929 JIT_INSTRUCTION_CTOR(4)
980 stash_argument (1, arg1); 930
981 } 931 #undef STASH_ARG
982 932 #undef JIT_INSTRUCTION_CTOR
983 jit_instruction (jit_value *arg0, jit_value *arg1, jit_value *arg2)
984 : already_infered (3, reinterpret_cast<jit_type *>(0)), marguments (3),
985 mid (next_id ()), mparent (0)
986 {
987 stash_argument (0, arg0);
988 stash_argument (1, arg1);
989 stash_argument (2, arg2);
990 }
991
992 jit_instruction (jit_value *arg0, jit_value *arg1, jit_value *arg2,
993 jit_value *arg3)
994 : already_infered (3, reinterpret_cast<jit_type *>(0)), marguments (4),
995 mid (next_id ()), mparent (0)
996 {
997 stash_argument (0, arg0);
998 stash_argument (1, arg1);
999 stash_argument (2, arg2);
1000 stash_argument (3, arg3);
1001 }
1002 933
1003 static void reset_ids (void) 934 static void reset_ids (void)
1004 { 935 {
1005 next_id (true); 936 next_id (true);
1006 } 937 }
1682 1613
1683 class 1614 class
1684 jit_terminator : public jit_instruction 1615 jit_terminator : public jit_instruction
1685 { 1616 {
1686 public: 1617 public:
1687 jit_terminator (size_t asuccessor_count, jit_value *arg0) 1618 #define JIT_TERMINATOR_CONST(N) \
1688 : jit_instruction (arg0), malive (asuccessor_count, false), 1619 jit_terminator (size_t asuccessor_count, \
1689 mbranch_llvm (asuccessor_count, 0) {} 1620 OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \
1690 1621 : jit_instruction (OCT_MAKE_ARG_LIST (arg, N)), \
1691 jit_terminator (size_t asuccessor_count, jit_value *arg0, jit_value *arg1) 1622 malive (asuccessor_count, false) {}
1692 : jit_instruction (arg0, arg1), malive (asuccessor_count, false), 1623
1693 mbranch_llvm (asuccessor_count, 0) {} 1624 JIT_TERMINATOR_CONST (1)
1694 1625 JIT_TERMINATOR_CONST (2)
1695 jit_terminator (size_t asuccessor_count, jit_value *arg0, jit_value *arg1, 1626 JIT_TERMINATOR_CONST (3)
1696 jit_value *arg2) 1627
1697 : jit_instruction (arg0, arg1, arg2), malive (asuccessor_count, false), 1628 #undef JIT_TERMINATOR_CONST
1698 mbranch_llvm (asuccessor_count, 0) {}
1699 1629
1700 jit_block *successor (size_t idx = 0) const 1630 jit_block *successor (size_t idx = 0) const
1701 { 1631 {
1702 return static_cast<jit_block *> (argument (idx)); 1632 return static_cast<jit_block *> (argument (idx));
1703 } 1633 }
1704 1634
1705 // the llvm block between our parent and the given successor
1706 llvm::BasicBlock *branch_llvm (size_t idx = 0) const
1707 {
1708 return mbranch_llvm[idx] ? mbranch_llvm[idx] : parent ()->to_llvm ();
1709 }
1710
1711 llvm::BasicBlock *branch_llvm (int idx) const
1712 {
1713 return branch_llvm (static_cast<size_t> (idx));
1714 }
1715
1716 llvm::BasicBlock *branch_llvm (const jit_block *asuccessor) const
1717 {
1718 return branch_llvm (successor_index (asuccessor));
1719 }
1720
1721 llvm::BasicBlock *successor_llvm (size_t idx = 0) const 1635 llvm::BasicBlock *successor_llvm (size_t idx = 0) const
1722 { 1636 {
1723 return mbranch_llvm[idx] ? mbranch_llvm[idx] : successor (idx)->to_llvm (); 1637 return successor (idx)->to_llvm ();
1724 } 1638 }
1725 1639
1726 size_t successor_index (const jit_block *asuccessor) const; 1640 size_t successor_index (const jit_block *asuccessor) const;
1727 1641
1728 std::ostream& print_successor (std::ostream& os, size_t idx = 0) const 1642 std::ostream& print_successor (std::ostream& os, size_t idx = 0) const
1752 llvm::TerminatorInst *to_llvm (void) const; 1666 llvm::TerminatorInst *to_llvm (void) const;
1753 protected: 1667 protected:
1754 virtual bool check_alive (size_t) const { return true; } 1668 virtual bool check_alive (size_t) const { return true; }
1755 private: 1669 private:
1756 std::vector<bool> malive; 1670 std::vector<bool> malive;
1757 std::vector<llvm::BasicBlock *> mbranch_llvm;
1758 }; 1671 };
1759 1672
1760 class 1673 class
1761 jit_branch : public jit_terminator 1674 jit_branch : public jit_terminator
1762 { 1675 {
1808 1721
1809 class 1722 class
1810 jit_call : public jit_instruction 1723 jit_call : public jit_instruction
1811 { 1724 {
1812 public: 1725 public:
1813 jit_call (const jit_function& afunction, 1726 #define JIT_CALL_CONST(N) \
1814 jit_value *arg0) : jit_instruction (arg0), mfunction (afunction) 1727 jit_call (const jit_function& afunction, \
1815 {} 1728 OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \
1816 1729 : jit_instruction (OCT_MAKE_ARG_LIST (arg, N)), mfunction (afunction) {} \
1817 jit_call (const jit_function& (*afunction) (void), 1730 \
1818 jit_value *arg0) : jit_instruction (arg0), 1731 jit_call (const jit_function& (*afunction) (void), \
1819 mfunction (afunction ()) {} 1732 OCT_MAKE_DECL_LIST (jit_value *, arg, N)) \
1820 1733 : jit_instruction (OCT_MAKE_ARG_LIST (arg, N)), mfunction (afunction ()) {}
1821 jit_call (const jit_function& afunction, 1734
1822 jit_value *arg0, jit_value *arg1) : jit_instruction (arg0, arg1), 1735 JIT_CALL_CONST (1)
1823 mfunction (afunction) {} 1736 JIT_CALL_CONST (2)
1824 1737 JIT_CALL_CONST (3)
1825 jit_call (const jit_function& (*afunction) (void), 1738 JIT_CALL_CONST (4)
1826 jit_value *arg0, jit_value *arg1) : jit_instruction (arg0, arg1), 1739
1827 mfunction (afunction ()) {} 1740 #undef JIT_CALL_CONST
1828
1829 jit_call (const jit_function& (*afunction) (void),
1830 jit_value *arg0, jit_value *arg1, jit_value *arg2)
1831 : jit_instruction (arg0, arg1, arg2), mfunction (afunction ()) {}
1832
1833 jit_call (const jit_function& (*afunction) (void),
1834 jit_value *arg0, jit_value *arg1, jit_value *arg2, jit_value *arg3)
1835 : jit_instruction (arg0, arg1, arg2, arg3), mfunction (afunction ()) {}
1836 1741
1837 1742
1838 const jit_function& function (void) const { return mfunction; } 1743 const jit_function& function (void) const { return mfunction; }
1839 1744
1840 bool can_error (void) const 1745 bool can_error (void) const
2124 T *ret = new T(); 2029 T *ret = new T();
2125 track_value (ret); 2030 track_value (ret);
2126 return ret; 2031 return ret;
2127 } 2032 }
2128 2033
2129 template <typename T, typename ARG0> 2034 #define DECL_ARG(n) const ARG ## n& arg ## n
2130 T *create (const ARG0& arg0) 2035 #define JIT_CREATE(N) \
2131 { 2036 template <typename T, OCT_MAKE_DECL_LIST (typename, ARG, N)> \
2132 T *ret = new T(arg0); 2037 T *create (OCT_MAKE_LIST (DECL_ARG, N)) \
2133 track_value (ret); 2038 { \
2134 return ret; 2039 T *ret = new T (OCT_MAKE_ARG_LIST (arg, N)); \
2135 } 2040 track_value (ret); \
2136 2041 return ret; \
2137 template <typename T, typename ARG0, typename ARG1> 2042 }
2138 T *create (const ARG0& arg0, const ARG1& arg1) 2043
2139 { 2044 JIT_CREATE (1)
2140 T *ret = new T(arg0, arg1); 2045 JIT_CREATE (2)
2141 track_value (ret); 2046 JIT_CREATE (3)
2142 return ret; 2047 JIT_CREATE (4)
2143 } 2048
2144 2049 #undef JIT_CREATE
2145 template <typename T, typename ARG0, typename ARG1, typename ARG2> 2050
2146 T *create (const ARG0& arg0, const ARG1& arg1, const ARG2& arg2) 2051 #define JIT_CREATE_CHECKED(N) \
2147 { 2052 template <OCT_MAKE_DECL_LIST (typename, ARG, N)> \
2148 T *ret = new T(arg0, arg1, arg2); 2053 jit_call *create_checked (OCT_MAKE_LIST (DECL_ARG, N)) \
2149 track_value (ret); 2054 { \
2150 return ret; 2055 jit_call *ret = create<jit_call> (OCT_MAKE_ARG_LIST (arg, N)); \
2151 } 2056 return create_checked_impl (ret); \
2152 2057 }
2153 template <typename T, typename ARG0, typename ARG1, typename ARG2, 2058
2154 typename ARG3> 2059 JIT_CREATE_CHECKED (1)
2155 T *create (const ARG0& arg0, const ARG1& arg1, const ARG2& arg2, 2060 JIT_CREATE_CHECKED (2)
2156 const ARG3& arg3) 2061 JIT_CREATE_CHECKED (3)
2157 { 2062 JIT_CREATE_CHECKED (4)
2158 T *ret = new T(arg0, arg1, arg2, arg3); 2063
2159 track_value (ret); 2064 #undef JIT_CREATE_CHECKED
2160 return ret; 2065 #undef DECL_ARG
2161 }
2162
2163 template <typename ARG0, typename ARG1>
2164 jit_call *create_checked (const ARG0& arg0, const ARG1& arg1)
2165 {
2166 jit_call *ret = create<jit_call> (arg0, arg1);
2167 return create_checked_impl (ret);
2168 }
2169
2170 template <typename ARG0, typename ARG1, typename ARG2>
2171 jit_call *create_checked (const ARG0& arg0, const ARG1& arg1,
2172 const ARG2& arg2)
2173 {
2174 jit_call *ret = create<jit_call> (arg0, arg1, arg2);
2175 return create_checked_impl (ret);
2176 }
2177
2178 template <typename ARG0, typename ARG1, typename ARG2, typename ARG3>
2179 jit_call *create_checked (const ARG0& arg0, const ARG1& arg1,
2180 const ARG2& arg2, const ARG3& arg3)
2181 {
2182 jit_call *ret = create<jit_call> (arg0, arg1, arg2, arg3);
2183 return create_checked_impl (ret);
2184 }
2185 2066
2186 typedef std::list<jit_block *> block_list; 2067 typedef std::list<jit_block *> block_list;
2187 typedef block_list::iterator block_iterator; 2068 typedef block_list::iterator block_iterator;
2188 2069
2189 void append (jit_block *ablock); 2070 void append (jit_block *ablock);