diff --git a/.gitignore b/.gitignore index 6d0cc2b..6d6296f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ build _build *.pyc +*.so /llvm/_intrinsic_ids.py +llvm_ +newbinding/api/* \ No newline at end of file diff --git a/llvm/2.9_update.diff b/llvm/2.9_update.diff deleted file mode 100644 index 5572286..0000000 --- a/llvm/2.9_update.diff +++ /dev/null @@ -1,2117 +0,0 @@ -Index: core.py -=================================================================== ---- core.py (revision 105) -+++ core.py (working copy) -@@ -51,14 +51,15 @@ - TYPE_FP128 = 4 - TYPE_PPC_FP128 = 5 - TYPE_LABEL = 6 --TYPE_INTEGER = 7 --TYPE_FUNCTION = 8 --TYPE_STRUCT = 9 --TYPE_ARRAY = 10 --TYPE_POINTER = 11 --TYPE_OPAQUE = 12 --TYPE_VECTOR = 13 --TYPE_METADATA = 14 -+TYPE_METADATA = 7 -+TYPE_X86_MMX = 8 -+TYPE_INTEGER = 9 -+TYPE_FUNCTION = 10 -+TYPE_STRUCT = 11 -+TYPE_ARRAY = 12 -+TYPE_POINTER = 13 -+TYPE_OPAQUE = 14 -+TYPE_VECTOR = 15 - - # value IDs (llvm::Value::ValueTy enum) - VALUE_ARGUMENT = 0 -@@ -140,11 +141,21 @@ - OPCODE_INSERTVALUE = 54 - - # calling conventions --CC_C = 0 --CC_FASTCALL = 8 --CC_COLDCALL = 9 --CC_X86_STDCALL = 64 --CC_X86_FASTCALL = 65 -+CC_C = 0 -+CC_FASTCALL = 8 -+CC_COLDCALL = 9 -+CC_GHC = 10 -+CC_X86_STDCALL = 64 -+CC_X86_FASTCALL = 65 -+CC_ARM_APCS = 66 -+CC_ARM_AAPCS = 67 -+CC_ARM_AAPCS_VFP = 68 -+CC_MSP430_INTR = 69 -+CC_X86_THISCALL = 70 -+CC_PTX_KERNEL = 71 -+CC_PTX_DEVICE = 72 -+CC_MBLAZE_INTR = 73 -+CC_MBLAZE_SVOL = 74 - - # int predicates - ICMP_EQ = 32 -@@ -248,11 +259,14 @@ - ATTR_OPTIMIZE_FOR_SIZE = 1<<13 - ATTR_STACK_PROTECT = 1<<14 - ATTR_STACK_PROTECT_REQ = 1<<15 -+ATTR_ALIGNMENT = 1<<16 - ATTR_NO_CAPTURE = 1<<21 - ATTR_NO_REDZONE = 1<<22 - ATTR_NO_IMPLICIT_FLOAT = 1<<23 - ATTR_NAKED = 1<<24 - ATTR_INLINE_HINT = 1<<25 -+ATTR_STACK_ALIGNMENT = 7<<26 -+ATTR_HOTPATCH = 1<<29 - - # intrinsic IDs - from llvm._intrinsic_ids import * -Index: extra.cpp -=================================================================== ---- extra.cpp (revision 105) -+++ extra.cpp (working copy) -@@ -54,7 +54,7 @@ - #include "llvm/IntrinsicInst.h" - #include "llvm/Analysis/Verifier.h" - #include "llvm/Assembly/Parser.h" --#include "llvm/System/DynamicLibrary.h" -+#include "llvm/Support/DynamicLibrary.h" - #include "llvm/PassManager.h" - #include "llvm/ExecutionEngine/ExecutionEngine.h" - #include "llvm/Analysis/LoopPass.h" -@@ -452,12 +452,19 @@ - return eep->getPointerToFunction(fnp); - } - -+ - int LLVMInlineFunction(LLVMValueRef call) - { - llvm::Value *callp = llvm::unwrap(call); - assert(callp); - -- llvm::CallSite cs = llvm::CallSite::get(callp); -+// llvm::CallSite cs = llvm::CallSite::get(callp); -+ llvm::CallSite cs; -+ llvm::Instruction *II = llvm::dyn_cast(callp); -+ if (II->getOpcode() == llvm::Instruction::Call) -+ cs = llvm::CallSite(static_cast(II)); -+ else if (II->getOpcode() == llvm::Instruction::Invoke) -+ cs = llvm::CallSite(static_cast(II)); - - llvm::InlineFunctionInfo unused; - return llvm::InlineFunction(cs, unused); -@@ -501,13 +508,13 @@ - define_pass( DomPrinter ) - define_pass( DomViewer ) - define_pass( EdgeProfiler ) --define_pass( GEPSplitter ) -+//define_pass( GEPSplitter ) - define_pass( GlobalsModRef ) - define_pass( InstCount ) - define_pass( InstructionNamer ) - define_pass( LazyValueInfo ) - define_pass( LCSSA ) --define_pass( LiveValues ) -+//define_pass( LiveValues ) - define_pass( LoopDependenceAnalysis ) - define_pass( LoopExtractor ) - define_pass( LoopSimplify ) -@@ -519,7 +526,7 @@ - define_pass( NoProfileInfo ) - define_pass( OptimalEdgeProfiler ) - define_pass( PartialInlining ) --define_pass( PartialSpecialization ) -+//define_pass( PartialSpecialization ) - define_pass( PostDomOnlyPrinter ) - define_pass( PostDomOnlyViewer ) - define_pass( PostDomPrinter ) -@@ -528,7 +535,7 @@ - define_pass( ProfileLoader ) - define_pass( ProfileVerifier ) - define_pass( ScalarEvolutionAliasAnalysis ) --define_pass( SimplifyHalfPowrLibCalls ) -+//define_pass( SimplifyHalfPowrLibCalls ) - define_pass( SingleLoopExtractor ) - define_pass( StripNonDebugSymbols ) - define_pass( StructRetPromotion ) -Index: passes.py -=================================================================== ---- passes.py (revision 105) -+++ passes.py (working copy) -@@ -68,7 +68,7 @@ - PASS_EDGE_PROFILER = 25 - PASS_FUNCTION_ATTRS = 26 - PASS_FUNCTION_INLINING = 27 --PASS_GEP_SPLITTER = 28 -+#PASS_GEP_SPLITTER = 28 - PASS_GLOBAL_DCE = 29 - PASS_GLOBAL_OPTIMIZER = 30 - PASS_GLOBALS_MOD_REF = 31 -@@ -83,11 +83,11 @@ - PASS_LAZY_VALUE_INFO = 40 - PASS_LCSSA = 41 - PASS_LICM = 42 --PASS_LIVE_VALUES = 43 -+#PASS_LIVE_VALUES = 43 - PASS_LOOP_DELETION = 44 - PASS_LOOP_DEPENDENCE_ANALYSIS = 45 - PASS_LOOP_EXTRACTOR = 46 --PASS_LOOP_INDEX_SPLIT = 47 -+#PASS_LOOP_INDEX_SPLIT = 47 - PASS_LOOP_ROTATE = 48 - PASS_LOOP_SIMPLIFY = 49 - PASS_LOOP_STRENGTH_REDUCE = 50 -@@ -102,11 +102,11 @@ - PASS_NO_PROFILE_INFO = 59 - PASS_OPTIMAL_EDGE_PROFILER = 60 - PASS_PARTIAL_INLINING = 61 --PASS_PARTIAL_SPECIALIZATION = 62 --PASS_POST_DOM_ONLY_PRINTER = 63 --PASS_POST_DOM_ONLY_VIEWER = 64 --PASS_POST_DOM_PRINTER = 65 --PASS_POST_DOM_VIEWER = 66 -+#PASS_PARTIAL_SPECIALIZATION = 62 -+#PASS_POST_DOM_ONLY_PRINTER = 63 -+#PASS_POST_DOM_ONLY_VIEWER = 64 -+#PASS_POST_DOM_PRINTER = 65 -+#PASS_POST_DOM_VIEWER = 66 - PASS_PROFILE_ESTIMATOR = 67 - PASS_PROFILE_LOADER = 68 - PASS_PROFILE_VERIFIER = 69 -@@ -116,7 +116,7 @@ - PASS_SCALAR_EVOLUTION_ALIAS_ANALYSIS = 73 - PASS_SCALAR_REPL_AGGREGATES = 74 - PASS_SCCP = 76 --PASS_SIMPLIFY_HALF_POWR_LIB_CALLS = 77 -+#PASS_SIMPLIFY_HALF_POWR_LIB_CALLS = 77 - PASS_SIMPLIFY_LIB_CALLS = 78 - PASS_SINGLE_LOOP_EXTRACTOR = 79 - PASS_STRIP_DEAD_PROTOTYPES = 82 -@@ -161,7 +161,7 @@ - PASS_EDGE_PROFILER : _core.LLVMAddEdgeProfilerPass, - PASS_FUNCTION_ATTRS : _core.LLVMAddFunctionAttrsPass, - PASS_FUNCTION_INLINING : _core.LLVMAddFunctionInliningPass, -- PASS_GEP_SPLITTER : _core.LLVMAddGEPSplitterPass, -+ #PASS_GEP_SPLITTER : _core.LLVMAddGEPSplitterPass, - PASS_GLOBAL_DCE : _core.LLVMAddGlobalDCEPass, - PASS_GLOBAL_OPTIMIZER : _core.LLVMAddGlobalOptimizerPass, - PASS_GLOBALS_MOD_REF : _core.LLVMAddGlobalsModRefPass, -@@ -176,11 +176,11 @@ - PASS_LAZY_VALUE_INFO : _core.LLVMAddLazyValueInfoPass, - PASS_LCSSA : _core.LLVMAddLCSSAPass, - PASS_LICM : _core.LLVMAddLICMPass, -- PASS_LIVE_VALUES : _core.LLVMAddLiveValuesPass, -+ #PASS_LIVE_VALUES : _core.LLVMAddLiveValuesPass, - PASS_LOOP_DELETION : _core.LLVMAddLoopDeletionPass, - PASS_LOOP_DEPENDENCE_ANALYSIS : _core.LLVMAddLoopDependenceAnalysisPass, - PASS_LOOP_EXTRACTOR : _core.LLVMAddLoopExtractorPass, -- PASS_LOOP_INDEX_SPLIT : _core.LLVMAddLoopIndexSplitPass, -+ #PASS_LOOP_INDEX_SPLIT : _core.LLVMAddLoopIndexSplitPass, - PASS_LOOP_ROTATE : _core.LLVMAddLoopRotatePass, - PASS_LOOP_SIMPLIFY : _core.LLVMAddLoopSimplifyPass, - PASS_LOOP_STRENGTH_REDUCE : _core.LLVMAddLoopStrengthReducePass, -@@ -195,11 +195,11 @@ - PASS_NO_PROFILE_INFO : _core.LLVMAddNoProfileInfoPass, - PASS_OPTIMAL_EDGE_PROFILER : _core.LLVMAddOptimalEdgeProfilerPass, - PASS_PARTIAL_INLINING : _core.LLVMAddPartialInliningPass, -- PASS_PARTIAL_SPECIALIZATION : _core.LLVMAddPartialSpecializationPass, -- PASS_POST_DOM_ONLY_PRINTER : _core.LLVMAddPostDomOnlyPrinterPass, -- PASS_POST_DOM_ONLY_VIEWER : _core.LLVMAddPostDomOnlyViewerPass, -- PASS_POST_DOM_PRINTER : _core.LLVMAddPostDomPrinterPass, -- PASS_POST_DOM_VIEWER : _core.LLVMAddPostDomViewerPass, -+ #PASS_PARTIAL_SPECIALIZATION : _core.LLVMAddPartialSpecializationPass, -+ #PASS_POST_DOM_ONLY_PRINTER : _core.LLVMAddPostDomOnlyPrinterPass, -+ #PASS_POST_DOM_ONLY_VIEWER : _core.LLVMAddPostDomOnlyViewerPass, -+ #PASS_POST_DOM_PRINTER : _core.LLVMAddPostDomPrinterPass, -+ #PASS_POST_DOM_VIEWER : _core.LLVMAddPostDomViewerPass, - PASS_PROFILE_ESTIMATOR : _core.LLVMAddProfileEstimatorPass, - PASS_PROFILE_LOADER : _core.LLVMAddProfileLoaderPass, - PASS_PROFILE_VERIFIER : _core.LLVMAddProfileVerifierPass, -@@ -209,7 +209,7 @@ - PASS_SCALAR_EVOLUTION_ALIAS_ANALYSIS : _core.LLVMAddScalarEvolutionAliasAnalysisPass, - PASS_SCALAR_REPL_AGGREGATES : _core.LLVMAddScalarReplAggregatesPass, - PASS_SCCP : _core.LLVMAddSCCPPass, -- PASS_SIMPLIFY_HALF_POWR_LIB_CALLS : _core.LLVMAddSimplifyHalfPowrLibCallsPass, -+ #PASS_SIMPLIFY_HALF_POWR_LIB_CALLS : _core.LLVMAddSimplifyHalfPowrLibCallsPass, - PASS_SIMPLIFY_LIB_CALLS : _core.LLVMAddSimplifyLibCallsPass, - PASS_SINGLE_LOOP_EXTRACTOR : _core.LLVMAddSingleLoopExtractorPass, - PASS_STRIP_DEAD_PROTOTYPES : _core.LLVMAddStripDeadPrototypesPass, -Index: _intrinsic_ids.py -=================================================================== ---- _intrinsic_ids.py (revision 105) -+++ _intrinsic_ids.py (working copy) -@@ -49,854 +49,879 @@ - INTR_ARM_NEON_VCNT = 14 - INTR_ARM_NEON_VCVTFP2FXS = 15 - INTR_ARM_NEON_VCVTFP2FXU = 16 --INTR_ARM_NEON_VCVTFXS2FP = 17 --INTR_ARM_NEON_VCVTFXU2FP = 18 --INTR_ARM_NEON_VHADDS = 19 --INTR_ARM_NEON_VHADDU = 20 --INTR_ARM_NEON_VHSUBS = 21 --INTR_ARM_NEON_VHSUBU = 22 --INTR_ARM_NEON_VLD1 = 23 --INTR_ARM_NEON_VLD2 = 24 --INTR_ARM_NEON_VLD2LANE = 25 --INTR_ARM_NEON_VLD3 = 26 --INTR_ARM_NEON_VLD3LANE = 27 --INTR_ARM_NEON_VLD4 = 28 --INTR_ARM_NEON_VLD4LANE = 29 --INTR_ARM_NEON_VMAXS = 30 --INTR_ARM_NEON_VMAXU = 31 --INTR_ARM_NEON_VMINS = 32 --INTR_ARM_NEON_VMINU = 33 --INTR_ARM_NEON_VMULLP = 34 --INTR_ARM_NEON_VMULP = 35 --INTR_ARM_NEON_VPADALS = 36 --INTR_ARM_NEON_VPADALU = 37 --INTR_ARM_NEON_VPADD = 38 --INTR_ARM_NEON_VPADDLS = 39 --INTR_ARM_NEON_VPADDLU = 40 --INTR_ARM_NEON_VPMAXS = 41 --INTR_ARM_NEON_VPMAXU = 42 --INTR_ARM_NEON_VPMINS = 43 --INTR_ARM_NEON_VPMINU = 44 --INTR_ARM_NEON_VQABS = 45 --INTR_ARM_NEON_VQADDS = 46 --INTR_ARM_NEON_VQADDU = 47 --INTR_ARM_NEON_VQDMLAL = 48 --INTR_ARM_NEON_VQDMLSL = 49 --INTR_ARM_NEON_VQDMULH = 50 --INTR_ARM_NEON_VQDMULL = 51 --INTR_ARM_NEON_VQMOVNS = 52 --INTR_ARM_NEON_VQMOVNSU = 53 --INTR_ARM_NEON_VQMOVNU = 54 --INTR_ARM_NEON_VQNEG = 55 --INTR_ARM_NEON_VQRDMULH = 56 --INTR_ARM_NEON_VQRSHIFTNS = 57 --INTR_ARM_NEON_VQRSHIFTNSU = 58 --INTR_ARM_NEON_VQRSHIFTNU = 59 --INTR_ARM_NEON_VQRSHIFTS = 60 --INTR_ARM_NEON_VQRSHIFTU = 61 --INTR_ARM_NEON_VQSHIFTNS = 62 --INTR_ARM_NEON_VQSHIFTNSU = 63 --INTR_ARM_NEON_VQSHIFTNU = 64 --INTR_ARM_NEON_VQSHIFTS = 65 --INTR_ARM_NEON_VQSHIFTSU = 66 --INTR_ARM_NEON_VQSHIFTU = 67 --INTR_ARM_NEON_VQSUBS = 68 --INTR_ARM_NEON_VQSUBU = 69 --INTR_ARM_NEON_VRADDHN = 70 --INTR_ARM_NEON_VRECPE = 71 --INTR_ARM_NEON_VRECPS = 72 --INTR_ARM_NEON_VRHADDS = 73 --INTR_ARM_NEON_VRHADDU = 74 --INTR_ARM_NEON_VRSHIFTN = 75 --INTR_ARM_NEON_VRSHIFTS = 76 --INTR_ARM_NEON_VRSHIFTU = 77 --INTR_ARM_NEON_VRSQRTE = 78 --INTR_ARM_NEON_VRSQRTS = 79 --INTR_ARM_NEON_VRSUBHN = 80 --INTR_ARM_NEON_VSHIFTINS = 81 --INTR_ARM_NEON_VSHIFTLS = 82 --INTR_ARM_NEON_VSHIFTLU = 83 --INTR_ARM_NEON_VSHIFTN = 84 --INTR_ARM_NEON_VSHIFTS = 85 --INTR_ARM_NEON_VSHIFTU = 86 --INTR_ARM_NEON_VST1 = 87 --INTR_ARM_NEON_VST2 = 88 --INTR_ARM_NEON_VST2LANE = 89 --INTR_ARM_NEON_VST3 = 90 --INTR_ARM_NEON_VST3LANE = 91 --INTR_ARM_NEON_VST4 = 92 --INTR_ARM_NEON_VST4LANE = 93 --INTR_ARM_NEON_VSUBHN = 94 --INTR_ARM_NEON_VTBL1 = 95 --INTR_ARM_NEON_VTBL2 = 96 --INTR_ARM_NEON_VTBL3 = 97 --INTR_ARM_NEON_VTBL4 = 98 --INTR_ARM_NEON_VTBX1 = 99 --INTR_ARM_NEON_VTBX2 = 100 --INTR_ARM_NEON_VTBX3 = 101 --INTR_ARM_NEON_VTBX4 = 102 --INTR_ARM_QADD = 103 --INTR_ARM_QSUB = 104 --INTR_ARM_SET_FPSCR = 105 --INTR_ARM_SSAT = 106 --INTR_ARM_THREAD_POINTER = 107 --INTR_ARM_USAT = 108 --INTR_ARM_VCVTR = 109 --INTR_ARM_VCVTRU = 110 --INTR_ATOMIC_CMP_SWAP = 111 --INTR_ATOMIC_LOAD_ADD = 112 --INTR_ATOMIC_LOAD_AND = 113 --INTR_ATOMIC_LOAD_MAX = 114 --INTR_ATOMIC_LOAD_MIN = 115 --INTR_ATOMIC_LOAD_NAND = 116 --INTR_ATOMIC_LOAD_OR = 117 --INTR_ATOMIC_LOAD_SUB = 118 --INTR_ATOMIC_LOAD_UMAX = 119 --INTR_ATOMIC_LOAD_UMIN = 120 --INTR_ATOMIC_LOAD_XOR = 121 --INTR_ATOMIC_SWAP = 122 --INTR_BSWAP = 123 --INTR_CONVERT_FROM_FP16 = 124 --INTR_CONVERT_TO_FP16 = 125 --INTR_CONVERTFF = 126 --INTR_CONVERTFSI = 127 --INTR_CONVERTFUI = 128 --INTR_CONVERTSIF = 129 --INTR_CONVERTSS = 130 --INTR_CONVERTSU = 131 --INTR_CONVERTUIF = 132 --INTR_CONVERTUS = 133 --INTR_CONVERTUU = 134 --INTR_COS = 135 --INTR_CTLZ = 136 --INTR_CTPOP = 137 --INTR_CTTZ = 138 --INTR_DBG_DECLARE = 139 --INTR_DBG_VALUE = 140 --INTR_EH_DWARF_CFA = 141 --INTR_EH_EXCEPTION = 142 --INTR_EH_RETURN_I32 = 143 --INTR_EH_RETURN_I64 = 144 --INTR_EH_SELECTOR = 145 --INTR_EH_SJLJ_CALLSITE = 146 --INTR_EH_SJLJ_LONGJMP = 147 --INTR_EH_SJLJ_LSDA = 148 --INTR_EH_SJLJ_SETJMP = 149 --INTR_EH_TYPEID_FOR = 150 --INTR_EH_UNWIND_INIT = 151 --INTR_EXP = 152 --INTR_EXP2 = 153 --INTR_FLT_ROUNDS = 154 --INTR_FRAMEADDRESS = 155 --INTR_GCREAD = 156 --INTR_GCROOT = 157 --INTR_GCWRITE = 158 --INTR_INIT_TRAMPOLINE = 159 --INTR_INVARIANT_END = 160 --INTR_INVARIANT_START = 161 --INTR_LIFETIME_END = 162 --INTR_LIFETIME_START = 163 --INTR_LOG = 164 --INTR_LOG10 = 165 --INTR_LOG2 = 166 --INTR_LONGJMP = 167 --INTR_MEMCPY = 168 --INTR_MEMMOVE = 169 --INTR_MEMORY_BARRIER = 170 --INTR_MEMSET = 171 --INTR_OBJECTSIZE = 172 --INTR_PCMARKER = 173 --INTR_POW = 174 --INTR_POWI = 175 --INTR_PPC_ALTIVEC_DSS = 176 --INTR_PPC_ALTIVEC_DSSALL = 177 --INTR_PPC_ALTIVEC_DST = 178 --INTR_PPC_ALTIVEC_DSTST = 179 --INTR_PPC_ALTIVEC_DSTSTT = 180 --INTR_PPC_ALTIVEC_DSTT = 181 --INTR_PPC_ALTIVEC_LVEBX = 182 --INTR_PPC_ALTIVEC_LVEHX = 183 --INTR_PPC_ALTIVEC_LVEWX = 184 --INTR_PPC_ALTIVEC_LVSL = 185 --INTR_PPC_ALTIVEC_LVSR = 186 --INTR_PPC_ALTIVEC_LVX = 187 --INTR_PPC_ALTIVEC_LVXL = 188 --INTR_PPC_ALTIVEC_MFVSCR = 189 --INTR_PPC_ALTIVEC_MTVSCR = 190 --INTR_PPC_ALTIVEC_STVEBX = 191 --INTR_PPC_ALTIVEC_STVEHX = 192 --INTR_PPC_ALTIVEC_STVEWX = 193 --INTR_PPC_ALTIVEC_STVX = 194 --INTR_PPC_ALTIVEC_STVXL = 195 --INTR_PPC_ALTIVEC_VADDCUW = 196 --INTR_PPC_ALTIVEC_VADDSBS = 197 --INTR_PPC_ALTIVEC_VADDSHS = 198 --INTR_PPC_ALTIVEC_VADDSWS = 199 --INTR_PPC_ALTIVEC_VADDUBS = 200 --INTR_PPC_ALTIVEC_VADDUHS = 201 --INTR_PPC_ALTIVEC_VADDUWS = 202 --INTR_PPC_ALTIVEC_VAVGSB = 203 --INTR_PPC_ALTIVEC_VAVGSH = 204 --INTR_PPC_ALTIVEC_VAVGSW = 205 --INTR_PPC_ALTIVEC_VAVGUB = 206 --INTR_PPC_ALTIVEC_VAVGUH = 207 --INTR_PPC_ALTIVEC_VAVGUW = 208 --INTR_PPC_ALTIVEC_VCFSX = 209 --INTR_PPC_ALTIVEC_VCFUX = 210 --INTR_PPC_ALTIVEC_VCMPBFP = 211 --INTR_PPC_ALTIVEC_VCMPBFP_P = 212 --INTR_PPC_ALTIVEC_VCMPEQFP = 213 --INTR_PPC_ALTIVEC_VCMPEQFP_P = 214 --INTR_PPC_ALTIVEC_VCMPEQUB = 215 --INTR_PPC_ALTIVEC_VCMPEQUB_P = 216 --INTR_PPC_ALTIVEC_VCMPEQUH = 217 --INTR_PPC_ALTIVEC_VCMPEQUH_P = 218 --INTR_PPC_ALTIVEC_VCMPEQUW = 219 --INTR_PPC_ALTIVEC_VCMPEQUW_P = 220 --INTR_PPC_ALTIVEC_VCMPGEFP = 221 --INTR_PPC_ALTIVEC_VCMPGEFP_P = 222 --INTR_PPC_ALTIVEC_VCMPGTFP = 223 --INTR_PPC_ALTIVEC_VCMPGTFP_P = 224 --INTR_PPC_ALTIVEC_VCMPGTSB = 225 --INTR_PPC_ALTIVEC_VCMPGTSB_P = 226 --INTR_PPC_ALTIVEC_VCMPGTSH = 227 --INTR_PPC_ALTIVEC_VCMPGTSH_P = 228 --INTR_PPC_ALTIVEC_VCMPGTSW = 229 --INTR_PPC_ALTIVEC_VCMPGTSW_P = 230 --INTR_PPC_ALTIVEC_VCMPGTUB = 231 --INTR_PPC_ALTIVEC_VCMPGTUB_P = 232 --INTR_PPC_ALTIVEC_VCMPGTUH = 233 --INTR_PPC_ALTIVEC_VCMPGTUH_P = 234 --INTR_PPC_ALTIVEC_VCMPGTUW = 235 --INTR_PPC_ALTIVEC_VCMPGTUW_P = 236 --INTR_PPC_ALTIVEC_VCTSXS = 237 --INTR_PPC_ALTIVEC_VCTUXS = 238 --INTR_PPC_ALTIVEC_VEXPTEFP = 239 --INTR_PPC_ALTIVEC_VLOGEFP = 240 --INTR_PPC_ALTIVEC_VMADDFP = 241 --INTR_PPC_ALTIVEC_VMAXFP = 242 --INTR_PPC_ALTIVEC_VMAXSB = 243 --INTR_PPC_ALTIVEC_VMAXSH = 244 --INTR_PPC_ALTIVEC_VMAXSW = 245 --INTR_PPC_ALTIVEC_VMAXUB = 246 --INTR_PPC_ALTIVEC_VMAXUH = 247 --INTR_PPC_ALTIVEC_VMAXUW = 248 --INTR_PPC_ALTIVEC_VMHADDSHS = 249 --INTR_PPC_ALTIVEC_VMHRADDSHS = 250 --INTR_PPC_ALTIVEC_VMINFP = 251 --INTR_PPC_ALTIVEC_VMINSB = 252 --INTR_PPC_ALTIVEC_VMINSH = 253 --INTR_PPC_ALTIVEC_VMINSW = 254 --INTR_PPC_ALTIVEC_VMINUB = 255 --INTR_PPC_ALTIVEC_VMINUH = 256 --INTR_PPC_ALTIVEC_VMINUW = 257 --INTR_PPC_ALTIVEC_VMLADDUHM = 258 --INTR_PPC_ALTIVEC_VMSUMMBM = 259 --INTR_PPC_ALTIVEC_VMSUMSHM = 260 --INTR_PPC_ALTIVEC_VMSUMSHS = 261 --INTR_PPC_ALTIVEC_VMSUMUBM = 262 --INTR_PPC_ALTIVEC_VMSUMUHM = 263 --INTR_PPC_ALTIVEC_VMSUMUHS = 264 --INTR_PPC_ALTIVEC_VMULESB = 265 --INTR_PPC_ALTIVEC_VMULESH = 266 --INTR_PPC_ALTIVEC_VMULEUB = 267 --INTR_PPC_ALTIVEC_VMULEUH = 268 --INTR_PPC_ALTIVEC_VMULOSB = 269 --INTR_PPC_ALTIVEC_VMULOSH = 270 --INTR_PPC_ALTIVEC_VMULOUB = 271 --INTR_PPC_ALTIVEC_VMULOUH = 272 --INTR_PPC_ALTIVEC_VNMSUBFP = 273 --INTR_PPC_ALTIVEC_VPERM = 274 --INTR_PPC_ALTIVEC_VPKPX = 275 --INTR_PPC_ALTIVEC_VPKSHSS = 276 --INTR_PPC_ALTIVEC_VPKSHUS = 277 --INTR_PPC_ALTIVEC_VPKSWSS = 278 --INTR_PPC_ALTIVEC_VPKSWUS = 279 --INTR_PPC_ALTIVEC_VPKUHUS = 280 --INTR_PPC_ALTIVEC_VPKUWUS = 281 --INTR_PPC_ALTIVEC_VREFP = 282 --INTR_PPC_ALTIVEC_VRFIM = 283 --INTR_PPC_ALTIVEC_VRFIN = 284 --INTR_PPC_ALTIVEC_VRFIP = 285 --INTR_PPC_ALTIVEC_VRFIZ = 286 --INTR_PPC_ALTIVEC_VRLB = 287 --INTR_PPC_ALTIVEC_VRLH = 288 --INTR_PPC_ALTIVEC_VRLW = 289 --INTR_PPC_ALTIVEC_VRSQRTEFP = 290 --INTR_PPC_ALTIVEC_VSEL = 291 --INTR_PPC_ALTIVEC_VSL = 292 --INTR_PPC_ALTIVEC_VSLB = 293 --INTR_PPC_ALTIVEC_VSLH = 294 --INTR_PPC_ALTIVEC_VSLO = 295 --INTR_PPC_ALTIVEC_VSLW = 296 --INTR_PPC_ALTIVEC_VSR = 297 --INTR_PPC_ALTIVEC_VSRAB = 298 --INTR_PPC_ALTIVEC_VSRAH = 299 --INTR_PPC_ALTIVEC_VSRAW = 300 --INTR_PPC_ALTIVEC_VSRB = 301 --INTR_PPC_ALTIVEC_VSRH = 302 --INTR_PPC_ALTIVEC_VSRO = 303 --INTR_PPC_ALTIVEC_VSRW = 304 --INTR_PPC_ALTIVEC_VSUBCUW = 305 --INTR_PPC_ALTIVEC_VSUBSBS = 306 --INTR_PPC_ALTIVEC_VSUBSHS = 307 --INTR_PPC_ALTIVEC_VSUBSWS = 308 --INTR_PPC_ALTIVEC_VSUBUBS = 309 --INTR_PPC_ALTIVEC_VSUBUHS = 310 --INTR_PPC_ALTIVEC_VSUBUWS = 311 --INTR_PPC_ALTIVEC_VSUM2SWS = 312 --INTR_PPC_ALTIVEC_VSUM4SBS = 313 --INTR_PPC_ALTIVEC_VSUM4SHS = 314 --INTR_PPC_ALTIVEC_VSUM4UBS = 315 --INTR_PPC_ALTIVEC_VSUMSWS = 316 --INTR_PPC_ALTIVEC_VUPKHPX = 317 --INTR_PPC_ALTIVEC_VUPKHSB = 318 --INTR_PPC_ALTIVEC_VUPKHSH = 319 --INTR_PPC_ALTIVEC_VUPKLPX = 320 --INTR_PPC_ALTIVEC_VUPKLSB = 321 --INTR_PPC_ALTIVEC_VUPKLSH = 322 --INTR_PPC_DCBA = 323 --INTR_PPC_DCBF = 324 --INTR_PPC_DCBI = 325 --INTR_PPC_DCBST = 326 --INTR_PPC_DCBT = 327 --INTR_PPC_DCBTST = 328 --INTR_PPC_DCBZ = 329 --INTR_PPC_DCBZL = 330 --INTR_PPC_SYNC = 331 --INTR_PREFETCH = 332 --INTR_PTR_ANNOTATION = 333 --INTR_READCYCLECOUNTER = 334 --INTR_RETURNADDRESS = 335 --INTR_SADD_WITH_OVERFLOW = 336 --INTR_SETJMP = 337 --INTR_SIGLONGJMP = 338 --INTR_SIGSETJMP = 339 --INTR_SIN = 340 --INTR_SMUL_WITH_OVERFLOW = 341 --INTR_SPU_SI_A = 342 --INTR_SPU_SI_ADDX = 343 --INTR_SPU_SI_AH = 344 --INTR_SPU_SI_AHI = 345 --INTR_SPU_SI_AI = 346 --INTR_SPU_SI_AND = 347 --INTR_SPU_SI_ANDBI = 348 --INTR_SPU_SI_ANDC = 349 --INTR_SPU_SI_ANDHI = 350 --INTR_SPU_SI_ANDI = 351 --INTR_SPU_SI_BG = 352 --INTR_SPU_SI_BGX = 353 --INTR_SPU_SI_CEQ = 354 --INTR_SPU_SI_CEQB = 355 --INTR_SPU_SI_CEQBI = 356 --INTR_SPU_SI_CEQH = 357 --INTR_SPU_SI_CEQHI = 358 --INTR_SPU_SI_CEQI = 359 --INTR_SPU_SI_CG = 360 --INTR_SPU_SI_CGT = 361 --INTR_SPU_SI_CGTB = 362 --INTR_SPU_SI_CGTBI = 363 --INTR_SPU_SI_CGTH = 364 --INTR_SPU_SI_CGTHI = 365 --INTR_SPU_SI_CGTI = 366 --INTR_SPU_SI_CGX = 367 --INTR_SPU_SI_CLGT = 368 --INTR_SPU_SI_CLGTB = 369 --INTR_SPU_SI_CLGTBI = 370 --INTR_SPU_SI_CLGTH = 371 --INTR_SPU_SI_CLGTHI = 372 --INTR_SPU_SI_CLGTI = 373 --INTR_SPU_SI_DFA = 374 --INTR_SPU_SI_DFM = 375 --INTR_SPU_SI_DFMA = 376 --INTR_SPU_SI_DFMS = 377 --INTR_SPU_SI_DFNMA = 378 --INTR_SPU_SI_DFNMS = 379 --INTR_SPU_SI_DFS = 380 --INTR_SPU_SI_FA = 381 --INTR_SPU_SI_FCEQ = 382 --INTR_SPU_SI_FCGT = 383 --INTR_SPU_SI_FCMEQ = 384 --INTR_SPU_SI_FCMGT = 385 --INTR_SPU_SI_FM = 386 --INTR_SPU_SI_FMA = 387 --INTR_SPU_SI_FMS = 388 --INTR_SPU_SI_FNMS = 389 --INTR_SPU_SI_FS = 390 --INTR_SPU_SI_FSMBI = 391 --INTR_SPU_SI_MPY = 392 --INTR_SPU_SI_MPYA = 393 --INTR_SPU_SI_MPYH = 394 --INTR_SPU_SI_MPYHH = 395 --INTR_SPU_SI_MPYHHA = 396 --INTR_SPU_SI_MPYHHAU = 397 --INTR_SPU_SI_MPYHHU = 398 --INTR_SPU_SI_MPYI = 399 --INTR_SPU_SI_MPYS = 400 --INTR_SPU_SI_MPYU = 401 --INTR_SPU_SI_MPYUI = 402 --INTR_SPU_SI_NAND = 403 --INTR_SPU_SI_NOR = 404 --INTR_SPU_SI_OR = 405 --INTR_SPU_SI_ORBI = 406 --INTR_SPU_SI_ORC = 407 --INTR_SPU_SI_ORHI = 408 --INTR_SPU_SI_ORI = 409 --INTR_SPU_SI_SF = 410 --INTR_SPU_SI_SFH = 411 --INTR_SPU_SI_SFHI = 412 --INTR_SPU_SI_SFI = 413 --INTR_SPU_SI_SFX = 414 --INTR_SPU_SI_SHLI = 415 --INTR_SPU_SI_SHLQBI = 416 --INTR_SPU_SI_SHLQBII = 417 --INTR_SPU_SI_SHLQBY = 418 --INTR_SPU_SI_SHLQBYI = 419 --INTR_SPU_SI_XOR = 420 --INTR_SPU_SI_XORBI = 421 --INTR_SPU_SI_XORHI = 422 --INTR_SPU_SI_XORI = 423 --INTR_SQRT = 424 --INTR_SSUB_WITH_OVERFLOW = 425 --INTR_STACKPROTECTOR = 426 --INTR_STACKRESTORE = 427 --INTR_STACKSAVE = 428 --INTR_TRAP = 429 --INTR_UADD_WITH_OVERFLOW = 430 --INTR_UMUL_WITH_OVERFLOW = 431 --INTR_USUB_WITH_OVERFLOW = 432 --INTR_VACOPY = 433 --INTR_VAEND = 434 --INTR_VAR_ANNOTATION = 435 --INTR_VASTART = 436 --INTR_X86_AESNI_AESDEC = 437 --INTR_X86_AESNI_AESDECLAST = 438 --INTR_X86_AESNI_AESENC = 439 --INTR_X86_AESNI_AESENCLAST = 440 --INTR_X86_AESNI_AESIMC = 441 --INTR_X86_AESNI_AESKEYGENASSIST = 442 --INTR_X86_AVX_ADDSUB_PD_256 = 443 --INTR_X86_AVX_ADDSUB_PS_256 = 444 --INTR_X86_AVX_BLEND_PD_256 = 445 --INTR_X86_AVX_BLEND_PS_256 = 446 --INTR_X86_AVX_BLENDV_PD_256 = 447 --INTR_X86_AVX_BLENDV_PS_256 = 448 --INTR_X86_AVX_CMP_PD_256 = 449 --INTR_X86_AVX_CMP_PS_256 = 450 --INTR_X86_AVX_CVT_PD2_PS_256 = 451 --INTR_X86_AVX_CVT_PD2DQ_256 = 452 --INTR_X86_AVX_CVT_PS2_PD_256 = 453 --INTR_X86_AVX_CVT_PS2DQ_256 = 454 --INTR_X86_AVX_CVTDQ2_PD_256 = 455 --INTR_X86_AVX_CVTDQ2_PS_256 = 456 --INTR_X86_AVX_CVTT_PD2DQ_256 = 457 --INTR_X86_AVX_CVTT_PS2DQ_256 = 458 --INTR_X86_AVX_DP_PS_256 = 459 --INTR_X86_AVX_HADD_PD_256 = 460 --INTR_X86_AVX_HADD_PS_256 = 461 --INTR_X86_AVX_HSUB_PD_256 = 462 --INTR_X86_AVX_HSUB_PS_256 = 463 --INTR_X86_AVX_LDU_DQ_256 = 464 --INTR_X86_AVX_LOADU_DQ_256 = 465 --INTR_X86_AVX_LOADU_PD_256 = 466 --INTR_X86_AVX_LOADU_PS_256 = 467 --INTR_X86_AVX_MASKLOAD_PD = 468 --INTR_X86_AVX_MASKLOAD_PD_256 = 469 --INTR_X86_AVX_MASKLOAD_PS = 470 --INTR_X86_AVX_MASKLOAD_PS_256 = 471 --INTR_X86_AVX_MASKSTORE_PD = 472 --INTR_X86_AVX_MASKSTORE_PD_256 = 473 --INTR_X86_AVX_MASKSTORE_PS = 474 --INTR_X86_AVX_MASKSTORE_PS_256 = 475 --INTR_X86_AVX_MAX_PD_256 = 476 --INTR_X86_AVX_MAX_PS_256 = 477 --INTR_X86_AVX_MIN_PD_256 = 478 --INTR_X86_AVX_MIN_PS_256 = 479 --INTR_X86_AVX_MOVMSK_PD_256 = 480 --INTR_X86_AVX_MOVMSK_PS_256 = 481 --INTR_X86_AVX_MOVNT_DQ_256 = 482 --INTR_X86_AVX_MOVNT_PD_256 = 483 --INTR_X86_AVX_MOVNT_PS_256 = 484 --INTR_X86_AVX_PTESTC_256 = 485 --INTR_X86_AVX_PTESTNZC_256 = 486 --INTR_X86_AVX_PTESTZ_256 = 487 --INTR_X86_AVX_RCP_PS_256 = 488 --INTR_X86_AVX_ROUND_PD_256 = 489 --INTR_X86_AVX_ROUND_PS_256 = 490 --INTR_X86_AVX_RSQRT_PS_256 = 491 --INTR_X86_AVX_SQRT_PD_256 = 492 --INTR_X86_AVX_SQRT_PS_256 = 493 --INTR_X86_AVX_STOREU_DQ_256 = 494 --INTR_X86_AVX_STOREU_PD_256 = 495 --INTR_X86_AVX_STOREU_PS_256 = 496 --INTR_X86_AVX_VBROADCAST_SD_256 = 497 --INTR_X86_AVX_VBROADCASTF128_PD_256 = 498 --INTR_X86_AVX_VBROADCASTF128_PS_256 = 499 --INTR_X86_AVX_VBROADCASTSS = 500 --INTR_X86_AVX_VBROADCASTSS_256 = 501 --INTR_X86_AVX_VEXTRACTF128_PD_256 = 502 --INTR_X86_AVX_VEXTRACTF128_PS_256 = 503 --INTR_X86_AVX_VEXTRACTF128_SI_256 = 504 --INTR_X86_AVX_VINSERTF128_PD_256 = 505 --INTR_X86_AVX_VINSERTF128_PS_256 = 506 --INTR_X86_AVX_VINSERTF128_SI_256 = 507 --INTR_X86_AVX_VPERM2F128_PD_256 = 508 --INTR_X86_AVX_VPERM2F128_PS_256 = 509 --INTR_X86_AVX_VPERM2F128_SI_256 = 510 --INTR_X86_AVX_VPERMIL_PD = 511 --INTR_X86_AVX_VPERMIL_PD_256 = 512 --INTR_X86_AVX_VPERMIL_PS = 513 --INTR_X86_AVX_VPERMIL_PS_256 = 514 --INTR_X86_AVX_VPERMILVAR_PD = 515 --INTR_X86_AVX_VPERMILVAR_PD_256 = 516 --INTR_X86_AVX_VPERMILVAR_PS = 517 --INTR_X86_AVX_VPERMILVAR_PS_256 = 518 --INTR_X86_AVX_VTESTC_PD = 519 --INTR_X86_AVX_VTESTC_PD_256 = 520 --INTR_X86_AVX_VTESTC_PS = 521 --INTR_X86_AVX_VTESTC_PS_256 = 522 --INTR_X86_AVX_VTESTNZC_PD = 523 --INTR_X86_AVX_VTESTNZC_PD_256 = 524 --INTR_X86_AVX_VTESTNZC_PS = 525 --INTR_X86_AVX_VTESTNZC_PS_256 = 526 --INTR_X86_AVX_VTESTZ_PD = 527 --INTR_X86_AVX_VTESTZ_PD_256 = 528 --INTR_X86_AVX_VTESTZ_PS = 529 --INTR_X86_AVX_VTESTZ_PS_256 = 530 --INTR_X86_AVX_VZEROALL = 531 --INTR_X86_AVX_VZEROUPPER = 532 --INTR_X86_INT = 533 --INTR_X86_MMX_CVTSI32_SI64 = 534 --INTR_X86_MMX_CVTSI64_SI32 = 535 --INTR_X86_MMX_EMMS = 536 --INTR_X86_MMX_FEMMS = 537 --INTR_X86_MMX_MASKMOVQ = 538 --INTR_X86_MMX_MOVNT_DQ = 539 --INTR_X86_MMX_PACKSSDW = 540 --INTR_X86_MMX_PACKSSWB = 541 --INTR_X86_MMX_PACKUSWB = 542 --INTR_X86_MMX_PADD_B = 543 --INTR_X86_MMX_PADD_D = 544 --INTR_X86_MMX_PADD_Q = 545 --INTR_X86_MMX_PADD_W = 546 --INTR_X86_MMX_PADDS_B = 547 --INTR_X86_MMX_PADDS_W = 548 --INTR_X86_MMX_PADDUS_B = 549 --INTR_X86_MMX_PADDUS_W = 550 --INTR_X86_MMX_PAND = 551 --INTR_X86_MMX_PANDN = 552 --INTR_X86_MMX_PAVG_B = 553 --INTR_X86_MMX_PAVG_W = 554 --INTR_X86_MMX_PCMPEQ_B = 555 --INTR_X86_MMX_PCMPEQ_D = 556 --INTR_X86_MMX_PCMPEQ_W = 557 --INTR_X86_MMX_PCMPGT_B = 558 --INTR_X86_MMX_PCMPGT_D = 559 --INTR_X86_MMX_PCMPGT_W = 560 --INTR_X86_MMX_PEXTR_W = 561 --INTR_X86_MMX_PINSR_W = 562 --INTR_X86_MMX_PMADD_WD = 563 --INTR_X86_MMX_PMAXS_W = 564 --INTR_X86_MMX_PMAXU_B = 565 --INTR_X86_MMX_PMINS_W = 566 --INTR_X86_MMX_PMINU_B = 567 --INTR_X86_MMX_PMOVMSKB = 568 --INTR_X86_MMX_PMULH_W = 569 --INTR_X86_MMX_PMULHU_W = 570 --INTR_X86_MMX_PMULL_W = 571 --INTR_X86_MMX_PMULU_DQ = 572 --INTR_X86_MMX_POR = 573 --INTR_X86_MMX_PSAD_BW = 574 --INTR_X86_MMX_PSLL_D = 575 --INTR_X86_MMX_PSLL_Q = 576 --INTR_X86_MMX_PSLL_W = 577 --INTR_X86_MMX_PSLLI_D = 578 --INTR_X86_MMX_PSLLI_Q = 579 --INTR_X86_MMX_PSLLI_W = 580 --INTR_X86_MMX_PSRA_D = 581 --INTR_X86_MMX_PSRA_W = 582 --INTR_X86_MMX_PSRAI_D = 583 --INTR_X86_MMX_PSRAI_W = 584 --INTR_X86_MMX_PSRL_D = 585 --INTR_X86_MMX_PSRL_Q = 586 --INTR_X86_MMX_PSRL_W = 587 --INTR_X86_MMX_PSRLI_D = 588 --INTR_X86_MMX_PSRLI_Q = 589 --INTR_X86_MMX_PSRLI_W = 590 --INTR_X86_MMX_PSUB_B = 591 --INTR_X86_MMX_PSUB_D = 592 --INTR_X86_MMX_PSUB_Q = 593 --INTR_X86_MMX_PSUB_W = 594 --INTR_X86_MMX_PSUBS_B = 595 --INTR_X86_MMX_PSUBS_W = 596 --INTR_X86_MMX_PSUBUS_B = 597 --INTR_X86_MMX_PSUBUS_W = 598 --INTR_X86_MMX_PUNPCKHBW = 599 --INTR_X86_MMX_PUNPCKHDQ = 600 --INTR_X86_MMX_PUNPCKHWD = 601 --INTR_X86_MMX_PUNPCKLBW = 602 --INTR_X86_MMX_PUNPCKLDQ = 603 --INTR_X86_MMX_PUNPCKLWD = 604 --INTR_X86_MMX_PXOR = 605 --INTR_X86_MMX_VEC_EXT_D = 606 --INTR_X86_MMX_VEC_INIT_B = 607 --INTR_X86_MMX_VEC_INIT_D = 608 --INTR_X86_MMX_VEC_INIT_W = 609 --INTR_X86_SSE2_ADD_SD = 610 --INTR_X86_SSE2_CLFLUSH = 611 --INTR_X86_SSE2_CMP_PD = 612 --INTR_X86_SSE2_CMP_SD = 613 --INTR_X86_SSE2_COMIEQ_SD = 614 --INTR_X86_SSE2_COMIGE_SD = 615 --INTR_X86_SSE2_COMIGT_SD = 616 --INTR_X86_SSE2_COMILE_SD = 617 --INTR_X86_SSE2_COMILT_SD = 618 --INTR_X86_SSE2_COMINEQ_SD = 619 --INTR_X86_SSE2_CVTDQ2PD = 620 --INTR_X86_SSE2_CVTDQ2PS = 621 --INTR_X86_SSE2_CVTPD2DQ = 622 --INTR_X86_SSE2_CVTPD2PS = 623 --INTR_X86_SSE2_CVTPS2DQ = 624 --INTR_X86_SSE2_CVTPS2PD = 625 --INTR_X86_SSE2_CVTSD2SI = 626 --INTR_X86_SSE2_CVTSD2SI64 = 627 --INTR_X86_SSE2_CVTSD2SS = 628 --INTR_X86_SSE2_CVTSI2SD = 629 --INTR_X86_SSE2_CVTSI642SD = 630 --INTR_X86_SSE2_CVTSS2SD = 631 --INTR_X86_SSE2_CVTTPD2DQ = 632 --INTR_X86_SSE2_CVTTPS2DQ = 633 --INTR_X86_SSE2_CVTTSD2SI = 634 --INTR_X86_SSE2_CVTTSD2SI64 = 635 --INTR_X86_SSE2_DIV_SD = 636 --INTR_X86_SSE2_LFENCE = 637 --INTR_X86_SSE2_LOADU_DQ = 638 --INTR_X86_SSE2_LOADU_PD = 639 --INTR_X86_SSE2_MASKMOV_DQU = 640 --INTR_X86_SSE2_MAX_PD = 641 --INTR_X86_SSE2_MAX_SD = 642 --INTR_X86_SSE2_MFENCE = 643 --INTR_X86_SSE2_MIN_PD = 644 --INTR_X86_SSE2_MIN_SD = 645 --INTR_X86_SSE2_MOVMSK_PD = 646 --INTR_X86_SSE2_MOVNT_DQ = 647 --INTR_X86_SSE2_MOVNT_I = 648 --INTR_X86_SSE2_MOVNT_PD = 649 --INTR_X86_SSE2_MUL_SD = 650 --INTR_X86_SSE2_PACKSSDW_128 = 651 --INTR_X86_SSE2_PACKSSWB_128 = 652 --INTR_X86_SSE2_PACKUSWB_128 = 653 --INTR_X86_SSE2_PADDS_B = 654 --INTR_X86_SSE2_PADDS_W = 655 --INTR_X86_SSE2_PADDUS_B = 656 --INTR_X86_SSE2_PADDUS_W = 657 --INTR_X86_SSE2_PAVG_B = 658 --INTR_X86_SSE2_PAVG_W = 659 --INTR_X86_SSE2_PCMPEQ_B = 660 --INTR_X86_SSE2_PCMPEQ_D = 661 --INTR_X86_SSE2_PCMPEQ_W = 662 --INTR_X86_SSE2_PCMPGT_B = 663 --INTR_X86_SSE2_PCMPGT_D = 664 --INTR_X86_SSE2_PCMPGT_W = 665 --INTR_X86_SSE2_PMADD_WD = 666 --INTR_X86_SSE2_PMAXS_W = 667 --INTR_X86_SSE2_PMAXU_B = 668 --INTR_X86_SSE2_PMINS_W = 669 --INTR_X86_SSE2_PMINU_B = 670 --INTR_X86_SSE2_PMOVMSKB_128 = 671 --INTR_X86_SSE2_PMULH_W = 672 --INTR_X86_SSE2_PMULHU_W = 673 --INTR_X86_SSE2_PMULU_DQ = 674 --INTR_X86_SSE2_PSAD_BW = 675 --INTR_X86_SSE2_PSLL_D = 676 --INTR_X86_SSE2_PSLL_DQ = 677 --INTR_X86_SSE2_PSLL_DQ_BS = 678 --INTR_X86_SSE2_PSLL_Q = 679 --INTR_X86_SSE2_PSLL_W = 680 --INTR_X86_SSE2_PSLLI_D = 681 --INTR_X86_SSE2_PSLLI_Q = 682 --INTR_X86_SSE2_PSLLI_W = 683 --INTR_X86_SSE2_PSRA_D = 684 --INTR_X86_SSE2_PSRA_W = 685 --INTR_X86_SSE2_PSRAI_D = 686 --INTR_X86_SSE2_PSRAI_W = 687 --INTR_X86_SSE2_PSRL_D = 688 --INTR_X86_SSE2_PSRL_DQ = 689 --INTR_X86_SSE2_PSRL_DQ_BS = 690 --INTR_X86_SSE2_PSRL_Q = 691 --INTR_X86_SSE2_PSRL_W = 692 --INTR_X86_SSE2_PSRLI_D = 693 --INTR_X86_SSE2_PSRLI_Q = 694 --INTR_X86_SSE2_PSRLI_W = 695 --INTR_X86_SSE2_PSUBS_B = 696 --INTR_X86_SSE2_PSUBS_W = 697 --INTR_X86_SSE2_PSUBUS_B = 698 --INTR_X86_SSE2_PSUBUS_W = 699 --INTR_X86_SSE2_SQRT_PD = 700 --INTR_X86_SSE2_SQRT_SD = 701 --INTR_X86_SSE2_STOREL_DQ = 702 --INTR_X86_SSE2_STOREU_DQ = 703 --INTR_X86_SSE2_STOREU_PD = 704 --INTR_X86_SSE2_SUB_SD = 705 --INTR_X86_SSE2_UCOMIEQ_SD = 706 --INTR_X86_SSE2_UCOMIGE_SD = 707 --INTR_X86_SSE2_UCOMIGT_SD = 708 --INTR_X86_SSE2_UCOMILE_SD = 709 --INTR_X86_SSE2_UCOMILT_SD = 710 --INTR_X86_SSE2_UCOMINEQ_SD = 711 --INTR_X86_SSE3_ADDSUB_PD = 712 --INTR_X86_SSE3_ADDSUB_PS = 713 --INTR_X86_SSE3_HADD_PD = 714 --INTR_X86_SSE3_HADD_PS = 715 --INTR_X86_SSE3_HSUB_PD = 716 --INTR_X86_SSE3_HSUB_PS = 717 --INTR_X86_SSE3_LDU_DQ = 718 --INTR_X86_SSE3_MONITOR = 719 --INTR_X86_SSE3_MWAIT = 720 --INTR_X86_SSE41_BLENDPD = 721 --INTR_X86_SSE41_BLENDPS = 722 --INTR_X86_SSE41_BLENDVPD = 723 --INTR_X86_SSE41_BLENDVPS = 724 --INTR_X86_SSE41_DPPD = 725 --INTR_X86_SSE41_DPPS = 726 --INTR_X86_SSE41_EXTRACTPS = 727 --INTR_X86_SSE41_INSERTPS = 728 --INTR_X86_SSE41_MOVNTDQA = 729 --INTR_X86_SSE41_MPSADBW = 730 --INTR_X86_SSE41_PACKUSDW = 731 --INTR_X86_SSE41_PBLENDVB = 732 --INTR_X86_SSE41_PBLENDW = 733 --INTR_X86_SSE41_PCMPEQQ = 734 --INTR_X86_SSE41_PEXTRB = 735 --INTR_X86_SSE41_PEXTRD = 736 --INTR_X86_SSE41_PEXTRQ = 737 --INTR_X86_SSE41_PHMINPOSUW = 738 --INTR_X86_SSE41_PMAXSB = 739 --INTR_X86_SSE41_PMAXSD = 740 --INTR_X86_SSE41_PMAXUD = 741 --INTR_X86_SSE41_PMAXUW = 742 --INTR_X86_SSE41_PMINSB = 743 --INTR_X86_SSE41_PMINSD = 744 --INTR_X86_SSE41_PMINUD = 745 --INTR_X86_SSE41_PMINUW = 746 --INTR_X86_SSE41_PMOVSXBD = 747 --INTR_X86_SSE41_PMOVSXBQ = 748 --INTR_X86_SSE41_PMOVSXBW = 749 --INTR_X86_SSE41_PMOVSXDQ = 750 --INTR_X86_SSE41_PMOVSXWD = 751 --INTR_X86_SSE41_PMOVSXWQ = 752 --INTR_X86_SSE41_PMOVZXBD = 753 --INTR_X86_SSE41_PMOVZXBQ = 754 --INTR_X86_SSE41_PMOVZXBW = 755 --INTR_X86_SSE41_PMOVZXDQ = 756 --INTR_X86_SSE41_PMOVZXWD = 757 --INTR_X86_SSE41_PMOVZXWQ = 758 --INTR_X86_SSE41_PMULDQ = 759 --INTR_X86_SSE41_PTESTC = 760 --INTR_X86_SSE41_PTESTNZC = 761 --INTR_X86_SSE41_PTESTZ = 762 --INTR_X86_SSE41_ROUND_PD = 763 --INTR_X86_SSE41_ROUND_PS = 764 --INTR_X86_SSE41_ROUND_SD = 765 --INTR_X86_SSE41_ROUND_SS = 766 --INTR_X86_SSE42_CRC32_16 = 767 --INTR_X86_SSE42_CRC32_32 = 768 --INTR_X86_SSE42_CRC32_8 = 769 --INTR_X86_SSE42_CRC64_64 = 770 --INTR_X86_SSE42_CRC64_8 = 771 --INTR_X86_SSE42_PCMPESTRI128 = 772 --INTR_X86_SSE42_PCMPESTRIA128 = 773 --INTR_X86_SSE42_PCMPESTRIC128 = 774 --INTR_X86_SSE42_PCMPESTRIO128 = 775 --INTR_X86_SSE42_PCMPESTRIS128 = 776 --INTR_X86_SSE42_PCMPESTRIZ128 = 777 --INTR_X86_SSE42_PCMPESTRM128 = 778 --INTR_X86_SSE42_PCMPGTQ = 779 --INTR_X86_SSE42_PCMPISTRI128 = 780 --INTR_X86_SSE42_PCMPISTRIA128 = 781 --INTR_X86_SSE42_PCMPISTRIC128 = 782 --INTR_X86_SSE42_PCMPISTRIO128 = 783 --INTR_X86_SSE42_PCMPISTRIS128 = 784 --INTR_X86_SSE42_PCMPISTRIZ128 = 785 --INTR_X86_SSE42_PCMPISTRM128 = 786 --INTR_X86_SSE_ADD_SS = 787 --INTR_X86_SSE_CMP_PS = 788 --INTR_X86_SSE_CMP_SS = 789 --INTR_X86_SSE_COMIEQ_SS = 790 --INTR_X86_SSE_COMIGE_SS = 791 --INTR_X86_SSE_COMIGT_SS = 792 --INTR_X86_SSE_COMILE_SS = 793 --INTR_X86_SSE_COMILT_SS = 794 --INTR_X86_SSE_COMINEQ_SS = 795 --INTR_X86_SSE_CVTPD2PI = 796 --INTR_X86_SSE_CVTPI2PD = 797 --INTR_X86_SSE_CVTPI2PS = 798 --INTR_X86_SSE_CVTPS2PI = 799 --INTR_X86_SSE_CVTSI2SS = 800 --INTR_X86_SSE_CVTSI642SS = 801 --INTR_X86_SSE_CVTSS2SI = 802 --INTR_X86_SSE_CVTSS2SI64 = 803 --INTR_X86_SSE_CVTTPD2PI = 804 --INTR_X86_SSE_CVTTPS2PI = 805 --INTR_X86_SSE_CVTTSS2SI = 806 --INTR_X86_SSE_CVTTSS2SI64 = 807 --INTR_X86_SSE_DIV_SS = 808 --INTR_X86_SSE_LDMXCSR = 809 --INTR_X86_SSE_LOADU_PS = 810 --INTR_X86_SSE_MAX_PS = 811 --INTR_X86_SSE_MAX_SS = 812 --INTR_X86_SSE_MIN_PS = 813 --INTR_X86_SSE_MIN_SS = 814 --INTR_X86_SSE_MOVMSK_PS = 815 --INTR_X86_SSE_MOVNT_PS = 816 --INTR_X86_SSE_MUL_SS = 817 --INTR_X86_SSE_RCP_PS = 818 --INTR_X86_SSE_RCP_SS = 819 --INTR_X86_SSE_RSQRT_PS = 820 --INTR_X86_SSE_RSQRT_SS = 821 --INTR_X86_SSE_SFENCE = 822 --INTR_X86_SSE_SQRT_PS = 823 --INTR_X86_SSE_SQRT_SS = 824 --INTR_X86_SSE_STMXCSR = 825 --INTR_X86_SSE_STOREU_PS = 826 --INTR_X86_SSE_SUB_SS = 827 --INTR_X86_SSE_UCOMIEQ_SS = 828 --INTR_X86_SSE_UCOMIGE_SS = 829 --INTR_X86_SSE_UCOMIGT_SS = 830 --INTR_X86_SSE_UCOMILE_SS = 831 --INTR_X86_SSE_UCOMILT_SS = 832 --INTR_X86_SSE_UCOMINEQ_SS = 833 --INTR_X86_SSSE3_PABS_B = 834 --INTR_X86_SSSE3_PABS_B_128 = 835 --INTR_X86_SSSE3_PABS_D = 836 --INTR_X86_SSSE3_PABS_D_128 = 837 --INTR_X86_SSSE3_PABS_W = 838 --INTR_X86_SSSE3_PABS_W_128 = 839 --INTR_X86_SSSE3_PHADD_D = 840 --INTR_X86_SSSE3_PHADD_D_128 = 841 --INTR_X86_SSSE3_PHADD_SW = 842 --INTR_X86_SSSE3_PHADD_SW_128 = 843 --INTR_X86_SSSE3_PHADD_W = 844 --INTR_X86_SSSE3_PHADD_W_128 = 845 --INTR_X86_SSSE3_PHSUB_D = 846 --INTR_X86_SSSE3_PHSUB_D_128 = 847 --INTR_X86_SSSE3_PHSUB_SW = 848 --INTR_X86_SSSE3_PHSUB_SW_128 = 849 --INTR_X86_SSSE3_PHSUB_W = 850 --INTR_X86_SSSE3_PHSUB_W_128 = 851 --INTR_X86_SSSE3_PMADD_UB_SW = 852 --INTR_X86_SSSE3_PMADD_UB_SW_128 = 853 --INTR_X86_SSSE3_PMUL_HR_SW = 854 --INTR_X86_SSSE3_PMUL_HR_SW_128 = 855 --INTR_X86_SSSE3_PSHUF_B = 856 --INTR_X86_SSSE3_PSHUF_B_128 = 857 --INTR_X86_SSSE3_PSHUF_W = 858 --INTR_X86_SSSE3_PSIGN_B = 859 --INTR_X86_SSSE3_PSIGN_B_128 = 860 --INTR_X86_SSSE3_PSIGN_D = 861 --INTR_X86_SSSE3_PSIGN_D_128 = 862 --INTR_X86_SSSE3_PSIGN_W = 863 --INTR_X86_SSSE3_PSIGN_W_128 = 864 --INTR_XCORE_BITREV = 865 --INTR_XCORE_GETID = 866 -- -+INTR_ARM_NEON_VCVTFP2HF = 17 -+INTR_ARM_NEON_VCVTFXS2FP = 18 -+INTR_ARM_NEON_VCVTFXU2FP = 19 -+INTR_ARM_NEON_VCVTHF2FP = 20 -+INTR_ARM_NEON_VHADDS = 21 -+INTR_ARM_NEON_VHADDU = 22 -+INTR_ARM_NEON_VHSUBS = 23 -+INTR_ARM_NEON_VHSUBU = 24 -+INTR_ARM_NEON_VLD1 = 25 -+INTR_ARM_NEON_VLD2 = 26 -+INTR_ARM_NEON_VLD2LANE = 27 -+INTR_ARM_NEON_VLD3 = 28 -+INTR_ARM_NEON_VLD3LANE = 29 -+INTR_ARM_NEON_VLD4 = 30 -+INTR_ARM_NEON_VLD4LANE = 31 -+INTR_ARM_NEON_VMAXS = 32 -+INTR_ARM_NEON_VMAXU = 33 -+INTR_ARM_NEON_VMINS = 34 -+INTR_ARM_NEON_VMINU = 35 -+INTR_ARM_NEON_VMULLP = 36 -+INTR_ARM_NEON_VMULP = 37 -+INTR_ARM_NEON_VPADALS = 38 -+INTR_ARM_NEON_VPADALU = 39 -+INTR_ARM_NEON_VPADD = 40 -+INTR_ARM_NEON_VPADDLS = 41 -+INTR_ARM_NEON_VPADDLU = 42 -+INTR_ARM_NEON_VPMAXS = 43 -+INTR_ARM_NEON_VPMAXU = 44 -+INTR_ARM_NEON_VPMINS = 45 -+INTR_ARM_NEON_VPMINU = 46 -+INTR_ARM_NEON_VQABS = 47 -+INTR_ARM_NEON_VQADDS = 48 -+INTR_ARM_NEON_VQADDU = 49 -+INTR_ARM_NEON_VQDMLAL = 50 -+INTR_ARM_NEON_VQDMLSL = 51 -+INTR_ARM_NEON_VQDMULH = 52 -+INTR_ARM_NEON_VQDMULL = 53 -+INTR_ARM_NEON_VQMOVNS = 54 -+INTR_ARM_NEON_VQMOVNSU = 55 -+INTR_ARM_NEON_VQMOVNU = 56 -+INTR_ARM_NEON_VQNEG = 57 -+INTR_ARM_NEON_VQRDMULH = 58 -+INTR_ARM_NEON_VQRSHIFTNS = 59 -+INTR_ARM_NEON_VQRSHIFTNSU = 60 -+INTR_ARM_NEON_VQRSHIFTNU = 61 -+INTR_ARM_NEON_VQRSHIFTS = 62 -+INTR_ARM_NEON_VQRSHIFTU = 63 -+INTR_ARM_NEON_VQSHIFTNS = 64 -+INTR_ARM_NEON_VQSHIFTNSU = 65 -+INTR_ARM_NEON_VQSHIFTNU = 66 -+INTR_ARM_NEON_VQSHIFTS = 67 -+INTR_ARM_NEON_VQSHIFTSU = 68 -+INTR_ARM_NEON_VQSHIFTU = 69 -+INTR_ARM_NEON_VQSUBS = 70 -+INTR_ARM_NEON_VQSUBU = 71 -+INTR_ARM_NEON_VRADDHN = 72 -+INTR_ARM_NEON_VRECPE = 73 -+INTR_ARM_NEON_VRECPS = 74 -+INTR_ARM_NEON_VRHADDS = 75 -+INTR_ARM_NEON_VRHADDU = 76 -+INTR_ARM_NEON_VRSHIFTN = 77 -+INTR_ARM_NEON_VRSHIFTS = 78 -+INTR_ARM_NEON_VRSHIFTU = 79 -+INTR_ARM_NEON_VRSQRTE = 80 -+INTR_ARM_NEON_VRSQRTS = 81 -+INTR_ARM_NEON_VRSUBHN = 82 -+INTR_ARM_NEON_VSHIFTINS = 83 -+INTR_ARM_NEON_VSHIFTLS = 84 -+INTR_ARM_NEON_VSHIFTLU = 85 -+INTR_ARM_NEON_VSHIFTN = 86 -+INTR_ARM_NEON_VSHIFTS = 87 -+INTR_ARM_NEON_VSHIFTU = 88 -+INTR_ARM_NEON_VST1 = 89 -+INTR_ARM_NEON_VST2 = 90 -+INTR_ARM_NEON_VST2LANE = 91 -+INTR_ARM_NEON_VST3 = 92 -+INTR_ARM_NEON_VST3LANE = 93 -+INTR_ARM_NEON_VST4 = 94 -+INTR_ARM_NEON_VST4LANE = 95 -+INTR_ARM_NEON_VSUBHN = 96 -+INTR_ARM_NEON_VTBL1 = 97 -+INTR_ARM_NEON_VTBL2 = 98 -+INTR_ARM_NEON_VTBL3 = 99 -+INTR_ARM_NEON_VTBL4 = 100 -+INTR_ARM_NEON_VTBX1 = 101 -+INTR_ARM_NEON_VTBX2 = 102 -+INTR_ARM_NEON_VTBX3 = 103 -+INTR_ARM_NEON_VTBX4 = 104 -+INTR_ARM_QADD = 105 -+INTR_ARM_QSUB = 106 -+INTR_ARM_SET_FPSCR = 107 -+INTR_ARM_SSAT = 108 -+INTR_ARM_THREAD_POINTER = 109 -+INTR_ARM_USAT = 110 -+INTR_ARM_VCVTR = 111 -+INTR_ARM_VCVTRU = 112 -+INTR_ATOMIC_CMP_SWAP = 113 -+INTR_ATOMIC_LOAD_ADD = 114 -+INTR_ATOMIC_LOAD_AND = 115 -+INTR_ATOMIC_LOAD_MAX = 116 -+INTR_ATOMIC_LOAD_MIN = 117 -+INTR_ATOMIC_LOAD_NAND = 118 -+INTR_ATOMIC_LOAD_OR = 119 -+INTR_ATOMIC_LOAD_SUB = 120 -+INTR_ATOMIC_LOAD_UMAX = 121 -+INTR_ATOMIC_LOAD_UMIN = 122 -+INTR_ATOMIC_LOAD_XOR = 123 -+INTR_ATOMIC_SWAP = 124 -+INTR_BSWAP = 125 -+INTR_CONVERT_FROM_FP16 = 126 -+INTR_CONVERT_TO_FP16 = 127 -+INTR_CONVERTFF = 128 -+INTR_CONVERTFSI = 129 -+INTR_CONVERTFUI = 130 -+INTR_CONVERTSIF = 131 -+INTR_CONVERTSS = 132 -+INTR_CONVERTSU = 133 -+INTR_CONVERTUIF = 134 -+INTR_CONVERTUS = 135 -+INTR_CONVERTUU = 136 -+INTR_COS = 137 -+INTR_CTLZ = 138 -+INTR_CTPOP = 139 -+INTR_CTTZ = 140 -+INTR_DBG_DECLARE = 141 -+INTR_DBG_VALUE = 142 -+INTR_EH_DWARF_CFA = 143 -+INTR_EH_EXCEPTION = 144 -+INTR_EH_RETURN_I32 = 145 -+INTR_EH_RETURN_I64 = 146 -+INTR_EH_SELECTOR = 147 -+INTR_EH_SJLJ_CALLSITE = 148 -+INTR_EH_SJLJ_DISPATCH_SETUP = 149 -+INTR_EH_SJLJ_LONGJMP = 150 -+INTR_EH_SJLJ_LSDA = 151 -+INTR_EH_SJLJ_SETJMP = 152 -+INTR_EH_TYPEID_FOR = 153 -+INTR_EH_UNWIND_INIT = 154 -+INTR_EXP = 155 -+INTR_EXP2 = 156 -+INTR_FLT_ROUNDS = 157 -+INTR_FRAMEADDRESS = 158 -+INTR_GCREAD = 159 -+INTR_GCROOT = 160 -+INTR_GCWRITE = 161 -+INTR_INIT_TRAMPOLINE = 162 -+INTR_INVARIANT_END = 163 -+INTR_INVARIANT_START = 164 -+INTR_LIFETIME_END = 165 -+INTR_LIFETIME_START = 166 -+INTR_LOG = 167 -+INTR_LOG10 = 168 -+INTR_LOG2 = 169 -+INTR_LONGJMP = 170 -+INTR_MEMCPY = 171 -+INTR_MEMMOVE = 172 -+INTR_MEMORY_BARRIER = 173 -+INTR_MEMSET = 174 -+INTR_OBJECTSIZE = 175 -+INTR_PCMARKER = 176 -+INTR_POW = 177 -+INTR_POWI = 178 -+INTR_PPC_ALTIVEC_DSS = 179 -+INTR_PPC_ALTIVEC_DSSALL = 180 -+INTR_PPC_ALTIVEC_DST = 181 -+INTR_PPC_ALTIVEC_DSTST = 182 -+INTR_PPC_ALTIVEC_DSTSTT = 183 -+INTR_PPC_ALTIVEC_DSTT = 184 -+INTR_PPC_ALTIVEC_LVEBX = 185 -+INTR_PPC_ALTIVEC_LVEHX = 186 -+INTR_PPC_ALTIVEC_LVEWX = 187 -+INTR_PPC_ALTIVEC_LVSL = 188 -+INTR_PPC_ALTIVEC_LVSR = 189 -+INTR_PPC_ALTIVEC_LVX = 190 -+INTR_PPC_ALTIVEC_LVXL = 191 -+INTR_PPC_ALTIVEC_MFVSCR = 192 -+INTR_PPC_ALTIVEC_MTVSCR = 193 -+INTR_PPC_ALTIVEC_STVEBX = 194 -+INTR_PPC_ALTIVEC_STVEHX = 195 -+INTR_PPC_ALTIVEC_STVEWX = 196 -+INTR_PPC_ALTIVEC_STVX = 197 -+INTR_PPC_ALTIVEC_STVXL = 198 -+INTR_PPC_ALTIVEC_VADDCUW = 199 -+INTR_PPC_ALTIVEC_VADDSBS = 200 -+INTR_PPC_ALTIVEC_VADDSHS = 201 -+INTR_PPC_ALTIVEC_VADDSWS = 202 -+INTR_PPC_ALTIVEC_VADDUBS = 203 -+INTR_PPC_ALTIVEC_VADDUHS = 204 -+INTR_PPC_ALTIVEC_VADDUWS = 205 -+INTR_PPC_ALTIVEC_VAVGSB = 206 -+INTR_PPC_ALTIVEC_VAVGSH = 207 -+INTR_PPC_ALTIVEC_VAVGSW = 208 -+INTR_PPC_ALTIVEC_VAVGUB = 209 -+INTR_PPC_ALTIVEC_VAVGUH = 210 -+INTR_PPC_ALTIVEC_VAVGUW = 211 -+INTR_PPC_ALTIVEC_VCFSX = 212 -+INTR_PPC_ALTIVEC_VCFUX = 213 -+INTR_PPC_ALTIVEC_VCMPBFP = 214 -+INTR_PPC_ALTIVEC_VCMPBFP_P = 215 -+INTR_PPC_ALTIVEC_VCMPEQFP = 216 -+INTR_PPC_ALTIVEC_VCMPEQFP_P = 217 -+INTR_PPC_ALTIVEC_VCMPEQUB = 218 -+INTR_PPC_ALTIVEC_VCMPEQUB_P = 219 -+INTR_PPC_ALTIVEC_VCMPEQUH = 220 -+INTR_PPC_ALTIVEC_VCMPEQUH_P = 221 -+INTR_PPC_ALTIVEC_VCMPEQUW = 222 -+INTR_PPC_ALTIVEC_VCMPEQUW_P = 223 -+INTR_PPC_ALTIVEC_VCMPGEFP = 224 -+INTR_PPC_ALTIVEC_VCMPGEFP_P = 225 -+INTR_PPC_ALTIVEC_VCMPGTFP = 226 -+INTR_PPC_ALTIVEC_VCMPGTFP_P = 227 -+INTR_PPC_ALTIVEC_VCMPGTSB = 228 -+INTR_PPC_ALTIVEC_VCMPGTSB_P = 229 -+INTR_PPC_ALTIVEC_VCMPGTSH = 230 -+INTR_PPC_ALTIVEC_VCMPGTSH_P = 231 -+INTR_PPC_ALTIVEC_VCMPGTSW = 232 -+INTR_PPC_ALTIVEC_VCMPGTSW_P = 233 -+INTR_PPC_ALTIVEC_VCMPGTUB = 234 -+INTR_PPC_ALTIVEC_VCMPGTUB_P = 235 -+INTR_PPC_ALTIVEC_VCMPGTUH = 236 -+INTR_PPC_ALTIVEC_VCMPGTUH_P = 237 -+INTR_PPC_ALTIVEC_VCMPGTUW = 238 -+INTR_PPC_ALTIVEC_VCMPGTUW_P = 239 -+INTR_PPC_ALTIVEC_VCTSXS = 240 -+INTR_PPC_ALTIVEC_VCTUXS = 241 -+INTR_PPC_ALTIVEC_VEXPTEFP = 242 -+INTR_PPC_ALTIVEC_VLOGEFP = 243 -+INTR_PPC_ALTIVEC_VMADDFP = 244 -+INTR_PPC_ALTIVEC_VMAXFP = 245 -+INTR_PPC_ALTIVEC_VMAXSB = 246 -+INTR_PPC_ALTIVEC_VMAXSH = 247 -+INTR_PPC_ALTIVEC_VMAXSW = 248 -+INTR_PPC_ALTIVEC_VMAXUB = 249 -+INTR_PPC_ALTIVEC_VMAXUH = 250 -+INTR_PPC_ALTIVEC_VMAXUW = 251 -+INTR_PPC_ALTIVEC_VMHADDSHS = 252 -+INTR_PPC_ALTIVEC_VMHRADDSHS = 253 -+INTR_PPC_ALTIVEC_VMINFP = 254 -+INTR_PPC_ALTIVEC_VMINSB = 255 -+INTR_PPC_ALTIVEC_VMINSH = 256 -+INTR_PPC_ALTIVEC_VMINSW = 257 -+INTR_PPC_ALTIVEC_VMINUB = 258 -+INTR_PPC_ALTIVEC_VMINUH = 259 -+INTR_PPC_ALTIVEC_VMINUW = 260 -+INTR_PPC_ALTIVEC_VMLADDUHM = 261 -+INTR_PPC_ALTIVEC_VMSUMMBM = 262 -+INTR_PPC_ALTIVEC_VMSUMSHM = 263 -+INTR_PPC_ALTIVEC_VMSUMSHS = 264 -+INTR_PPC_ALTIVEC_VMSUMUBM = 265 -+INTR_PPC_ALTIVEC_VMSUMUHM = 266 -+INTR_PPC_ALTIVEC_VMSUMUHS = 267 -+INTR_PPC_ALTIVEC_VMULESB = 268 -+INTR_PPC_ALTIVEC_VMULESH = 269 -+INTR_PPC_ALTIVEC_VMULEUB = 270 -+INTR_PPC_ALTIVEC_VMULEUH = 271 -+INTR_PPC_ALTIVEC_VMULOSB = 272 -+INTR_PPC_ALTIVEC_VMULOSH = 273 -+INTR_PPC_ALTIVEC_VMULOUB = 274 -+INTR_PPC_ALTIVEC_VMULOUH = 275 -+INTR_PPC_ALTIVEC_VNMSUBFP = 276 -+INTR_PPC_ALTIVEC_VPERM = 277 -+INTR_PPC_ALTIVEC_VPKPX = 278 -+INTR_PPC_ALTIVEC_VPKSHSS = 279 -+INTR_PPC_ALTIVEC_VPKSHUS = 280 -+INTR_PPC_ALTIVEC_VPKSWSS = 281 -+INTR_PPC_ALTIVEC_VPKSWUS = 282 -+INTR_PPC_ALTIVEC_VPKUHUS = 283 -+INTR_PPC_ALTIVEC_VPKUWUS = 284 -+INTR_PPC_ALTIVEC_VREFP = 285 -+INTR_PPC_ALTIVEC_VRFIM = 286 -+INTR_PPC_ALTIVEC_VRFIN = 287 -+INTR_PPC_ALTIVEC_VRFIP = 288 -+INTR_PPC_ALTIVEC_VRFIZ = 289 -+INTR_PPC_ALTIVEC_VRLB = 290 -+INTR_PPC_ALTIVEC_VRLH = 291 -+INTR_PPC_ALTIVEC_VRLW = 292 -+INTR_PPC_ALTIVEC_VRSQRTEFP = 293 -+INTR_PPC_ALTIVEC_VSEL = 294 -+INTR_PPC_ALTIVEC_VSL = 295 -+INTR_PPC_ALTIVEC_VSLB = 296 -+INTR_PPC_ALTIVEC_VSLH = 297 -+INTR_PPC_ALTIVEC_VSLO = 298 -+INTR_PPC_ALTIVEC_VSLW = 299 -+INTR_PPC_ALTIVEC_VSR = 300 -+INTR_PPC_ALTIVEC_VSRAB = 301 -+INTR_PPC_ALTIVEC_VSRAH = 302 -+INTR_PPC_ALTIVEC_VSRAW = 303 -+INTR_PPC_ALTIVEC_VSRB = 304 -+INTR_PPC_ALTIVEC_VSRH = 305 -+INTR_PPC_ALTIVEC_VSRO = 306 -+INTR_PPC_ALTIVEC_VSRW = 307 -+INTR_PPC_ALTIVEC_VSUBCUW = 308 -+INTR_PPC_ALTIVEC_VSUBSBS = 309 -+INTR_PPC_ALTIVEC_VSUBSHS = 310 -+INTR_PPC_ALTIVEC_VSUBSWS = 311 -+INTR_PPC_ALTIVEC_VSUBUBS = 312 -+INTR_PPC_ALTIVEC_VSUBUHS = 313 -+INTR_PPC_ALTIVEC_VSUBUWS = 314 -+INTR_PPC_ALTIVEC_VSUM2SWS = 315 -+INTR_PPC_ALTIVEC_VSUM4SBS = 316 -+INTR_PPC_ALTIVEC_VSUM4SHS = 317 -+INTR_PPC_ALTIVEC_VSUM4UBS = 318 -+INTR_PPC_ALTIVEC_VSUMSWS = 319 -+INTR_PPC_ALTIVEC_VUPKHPX = 320 -+INTR_PPC_ALTIVEC_VUPKHSB = 321 -+INTR_PPC_ALTIVEC_VUPKHSH = 322 -+INTR_PPC_ALTIVEC_VUPKLPX = 323 -+INTR_PPC_ALTIVEC_VUPKLSB = 324 -+INTR_PPC_ALTIVEC_VUPKLSH = 325 -+INTR_PPC_DCBA = 326 -+INTR_PPC_DCBF = 327 -+INTR_PPC_DCBI = 328 -+INTR_PPC_DCBST = 329 -+INTR_PPC_DCBT = 330 -+INTR_PPC_DCBTST = 331 -+INTR_PPC_DCBZ = 332 -+INTR_PPC_DCBZL = 333 -+INTR_PPC_SYNC = 334 -+INTR_PREFETCH = 335 -+INTR_PTR_ANNOTATION = 336 -+INTR_PTX_BAR_SYNC = 337 -+INTR_PTX_READ_TID_R64 = 338 -+INTR_PTX_READ_TID_V4I16 = 339 -+INTR_PTX_READ_TID_W = 340 -+INTR_PTX_READ_TID_X = 341 -+INTR_PTX_READ_TID_Y = 342 -+INTR_PTX_READ_TID_Z = 343 -+INTR_READCYCLECOUNTER = 344 -+INTR_RETURNADDRESS = 345 -+INTR_SADD_WITH_OVERFLOW = 346 -+INTR_SETJMP = 347 -+INTR_SIGLONGJMP = 348 -+INTR_SIGSETJMP = 349 -+INTR_SIN = 350 -+INTR_SMUL_WITH_OVERFLOW = 351 -+INTR_SPU_SI_A = 352 -+INTR_SPU_SI_ADDX = 353 -+INTR_SPU_SI_AH = 354 -+INTR_SPU_SI_AHI = 355 -+INTR_SPU_SI_AI = 356 -+INTR_SPU_SI_AND = 357 -+INTR_SPU_SI_ANDBI = 358 -+INTR_SPU_SI_ANDC = 359 -+INTR_SPU_SI_ANDHI = 360 -+INTR_SPU_SI_ANDI = 361 -+INTR_SPU_SI_BG = 362 -+INTR_SPU_SI_BGX = 363 -+INTR_SPU_SI_CEQ = 364 -+INTR_SPU_SI_CEQB = 365 -+INTR_SPU_SI_CEQBI = 366 -+INTR_SPU_SI_CEQH = 367 -+INTR_SPU_SI_CEQHI = 368 -+INTR_SPU_SI_CEQI = 369 -+INTR_SPU_SI_CG = 370 -+INTR_SPU_SI_CGT = 371 -+INTR_SPU_SI_CGTB = 372 -+INTR_SPU_SI_CGTBI = 373 -+INTR_SPU_SI_CGTH = 374 -+INTR_SPU_SI_CGTHI = 375 -+INTR_SPU_SI_CGTI = 376 -+INTR_SPU_SI_CGX = 377 -+INTR_SPU_SI_CLGT = 378 -+INTR_SPU_SI_CLGTB = 379 -+INTR_SPU_SI_CLGTBI = 380 -+INTR_SPU_SI_CLGTH = 381 -+INTR_SPU_SI_CLGTHI = 382 -+INTR_SPU_SI_CLGTI = 383 -+INTR_SPU_SI_DFA = 384 -+INTR_SPU_SI_DFM = 385 -+INTR_SPU_SI_DFMA = 386 -+INTR_SPU_SI_DFMS = 387 -+INTR_SPU_SI_DFNMA = 388 -+INTR_SPU_SI_DFNMS = 389 -+INTR_SPU_SI_DFS = 390 -+INTR_SPU_SI_FA = 391 -+INTR_SPU_SI_FCEQ = 392 -+INTR_SPU_SI_FCGT = 393 -+INTR_SPU_SI_FCMEQ = 394 -+INTR_SPU_SI_FCMGT = 395 -+INTR_SPU_SI_FM = 396 -+INTR_SPU_SI_FMA = 397 -+INTR_SPU_SI_FMS = 398 -+INTR_SPU_SI_FNMS = 399 -+INTR_SPU_SI_FS = 400 -+INTR_SPU_SI_FSMBI = 401 -+INTR_SPU_SI_MPY = 402 -+INTR_SPU_SI_MPYA = 403 -+INTR_SPU_SI_MPYH = 404 -+INTR_SPU_SI_MPYHH = 405 -+INTR_SPU_SI_MPYHHA = 406 -+INTR_SPU_SI_MPYHHAU = 407 -+INTR_SPU_SI_MPYHHU = 408 -+INTR_SPU_SI_MPYI = 409 -+INTR_SPU_SI_MPYS = 410 -+INTR_SPU_SI_MPYU = 411 -+INTR_SPU_SI_MPYUI = 412 -+INTR_SPU_SI_NAND = 413 -+INTR_SPU_SI_NOR = 414 -+INTR_SPU_SI_OR = 415 -+INTR_SPU_SI_ORBI = 416 -+INTR_SPU_SI_ORC = 417 -+INTR_SPU_SI_ORHI = 418 -+INTR_SPU_SI_ORI = 419 -+INTR_SPU_SI_SF = 420 -+INTR_SPU_SI_SFH = 421 -+INTR_SPU_SI_SFHI = 422 -+INTR_SPU_SI_SFI = 423 -+INTR_SPU_SI_SFX = 424 -+INTR_SPU_SI_SHLI = 425 -+INTR_SPU_SI_SHLQBI = 426 -+INTR_SPU_SI_SHLQBII = 427 -+INTR_SPU_SI_SHLQBY = 428 -+INTR_SPU_SI_SHLQBYI = 429 -+INTR_SPU_SI_XOR = 430 -+INTR_SPU_SI_XORBI = 431 -+INTR_SPU_SI_XORHI = 432 -+INTR_SPU_SI_XORI = 433 -+INTR_SQRT = 434 -+INTR_SSUB_WITH_OVERFLOW = 435 -+INTR_STACKPROTECTOR = 436 -+INTR_STACKRESTORE = 437 -+INTR_STACKSAVE = 438 -+INTR_TRAP = 439 -+INTR_UADD_WITH_OVERFLOW = 440 -+INTR_UMUL_WITH_OVERFLOW = 441 -+INTR_USUB_WITH_OVERFLOW = 442 -+INTR_VACOPY = 443 -+INTR_VAEND = 444 -+INTR_VAR_ANNOTATION = 445 -+INTR_VASTART = 446 -+INTR_X86_AESNI_AESDEC = 447 -+INTR_X86_AESNI_AESDECLAST = 448 -+INTR_X86_AESNI_AESENC = 449 -+INTR_X86_AESNI_AESENCLAST = 450 -+INTR_X86_AESNI_AESIMC = 451 -+INTR_X86_AESNI_AESKEYGENASSIST = 452 -+INTR_X86_AVX_ADDSUB_PD_256 = 453 -+INTR_X86_AVX_ADDSUB_PS_256 = 454 -+INTR_X86_AVX_BLEND_PD_256 = 455 -+INTR_X86_AVX_BLEND_PS_256 = 456 -+INTR_X86_AVX_BLENDV_PD_256 = 457 -+INTR_X86_AVX_BLENDV_PS_256 = 458 -+INTR_X86_AVX_CMP_PD_256 = 459 -+INTR_X86_AVX_CMP_PS_256 = 460 -+INTR_X86_AVX_CVT_PD2_PS_256 = 461 -+INTR_X86_AVX_CVT_PD2DQ_256 = 462 -+INTR_X86_AVX_CVT_PS2_PD_256 = 463 -+INTR_X86_AVX_CVT_PS2DQ_256 = 464 -+INTR_X86_AVX_CVTDQ2_PD_256 = 465 -+INTR_X86_AVX_CVTDQ2_PS_256 = 466 -+INTR_X86_AVX_CVTT_PD2DQ_256 = 467 -+INTR_X86_AVX_CVTT_PS2DQ_256 = 468 -+INTR_X86_AVX_DP_PS_256 = 469 -+INTR_X86_AVX_HADD_PD_256 = 470 -+INTR_X86_AVX_HADD_PS_256 = 471 -+INTR_X86_AVX_HSUB_PD_256 = 472 -+INTR_X86_AVX_HSUB_PS_256 = 473 -+INTR_X86_AVX_LDU_DQ_256 = 474 -+INTR_X86_AVX_LOADU_DQ_256 = 475 -+INTR_X86_AVX_LOADU_PD_256 = 476 -+INTR_X86_AVX_LOADU_PS_256 = 477 -+INTR_X86_AVX_MASKLOAD_PD = 478 -+INTR_X86_AVX_MASKLOAD_PD_256 = 479 -+INTR_X86_AVX_MASKLOAD_PS = 480 -+INTR_X86_AVX_MASKLOAD_PS_256 = 481 -+INTR_X86_AVX_MASKSTORE_PD = 482 -+INTR_X86_AVX_MASKSTORE_PD_256 = 483 -+INTR_X86_AVX_MASKSTORE_PS = 484 -+INTR_X86_AVX_MASKSTORE_PS_256 = 485 -+INTR_X86_AVX_MAX_PD_256 = 486 -+INTR_X86_AVX_MAX_PS_256 = 487 -+INTR_X86_AVX_MIN_PD_256 = 488 -+INTR_X86_AVX_MIN_PS_256 = 489 -+INTR_X86_AVX_MOVMSK_PD_256 = 490 -+INTR_X86_AVX_MOVMSK_PS_256 = 491 -+INTR_X86_AVX_MOVNT_DQ_256 = 492 -+INTR_X86_AVX_MOVNT_PD_256 = 493 -+INTR_X86_AVX_MOVNT_PS_256 = 494 -+INTR_X86_AVX_PTESTC_256 = 495 -+INTR_X86_AVX_PTESTNZC_256 = 496 -+INTR_X86_AVX_PTESTZ_256 = 497 -+INTR_X86_AVX_RCP_PS_256 = 498 -+INTR_X86_AVX_ROUND_PD_256 = 499 -+INTR_X86_AVX_ROUND_PS_256 = 500 -+INTR_X86_AVX_RSQRT_PS_256 = 501 -+INTR_X86_AVX_SQRT_PD_256 = 502 -+INTR_X86_AVX_SQRT_PS_256 = 503 -+INTR_X86_AVX_STOREU_DQ_256 = 504 -+INTR_X86_AVX_STOREU_PD_256 = 505 -+INTR_X86_AVX_STOREU_PS_256 = 506 -+INTR_X86_AVX_VBROADCAST_SD_256 = 507 -+INTR_X86_AVX_VBROADCASTF128_PD_256 = 508 -+INTR_X86_AVX_VBROADCASTF128_PS_256 = 509 -+INTR_X86_AVX_VBROADCASTSS = 510 -+INTR_X86_AVX_VBROADCASTSS_256 = 511 -+INTR_X86_AVX_VEXTRACTF128_PD_256 = 512 -+INTR_X86_AVX_VEXTRACTF128_PS_256 = 513 -+INTR_X86_AVX_VEXTRACTF128_SI_256 = 514 -+INTR_X86_AVX_VINSERTF128_PD_256 = 515 -+INTR_X86_AVX_VINSERTF128_PS_256 = 516 -+INTR_X86_AVX_VINSERTF128_SI_256 = 517 -+INTR_X86_AVX_VPERM2F128_PD_256 = 518 -+INTR_X86_AVX_VPERM2F128_PS_256 = 519 -+INTR_X86_AVX_VPERM2F128_SI_256 = 520 -+INTR_X86_AVX_VPERMIL_PD = 521 -+INTR_X86_AVX_VPERMIL_PD_256 = 522 -+INTR_X86_AVX_VPERMIL_PS = 523 -+INTR_X86_AVX_VPERMIL_PS_256 = 524 -+INTR_X86_AVX_VPERMILVAR_PD = 525 -+INTR_X86_AVX_VPERMILVAR_PD_256 = 526 -+INTR_X86_AVX_VPERMILVAR_PS = 527 -+INTR_X86_AVX_VPERMILVAR_PS_256 = 528 -+INTR_X86_AVX_VTESTC_PD = 529 -+INTR_X86_AVX_VTESTC_PD_256 = 530 -+INTR_X86_AVX_VTESTC_PS = 531 -+INTR_X86_AVX_VTESTC_PS_256 = 532 -+INTR_X86_AVX_VTESTNZC_PD = 533 -+INTR_X86_AVX_VTESTNZC_PD_256 = 534 -+INTR_X86_AVX_VTESTNZC_PS = 535 -+INTR_X86_AVX_VTESTNZC_PS_256 = 536 -+INTR_X86_AVX_VTESTZ_PD = 537 -+INTR_X86_AVX_VTESTZ_PD_256 = 538 -+INTR_X86_AVX_VTESTZ_PS = 539 -+INTR_X86_AVX_VTESTZ_PS_256 = 540 -+INTR_X86_AVX_VZEROALL = 541 -+INTR_X86_AVX_VZEROUPPER = 542 -+INTR_X86_INT = 543 -+INTR_X86_MMX_EMMS = 544 -+INTR_X86_MMX_FEMMS = 545 -+INTR_X86_MMX_MASKMOVQ = 546 -+INTR_X86_MMX_MOVNT_DQ = 547 -+INTR_X86_MMX_PACKSSDW = 548 -+INTR_X86_MMX_PACKSSWB = 549 -+INTR_X86_MMX_PACKUSWB = 550 -+INTR_X86_MMX_PADD_B = 551 -+INTR_X86_MMX_PADD_D = 552 -+INTR_X86_MMX_PADD_Q = 553 -+INTR_X86_MMX_PADD_W = 554 -+INTR_X86_MMX_PADDS_B = 555 -+INTR_X86_MMX_PADDS_W = 556 -+INTR_X86_MMX_PADDUS_B = 557 -+INTR_X86_MMX_PADDUS_W = 558 -+INTR_X86_MMX_PALIGNR_B = 559 -+INTR_X86_MMX_PAND = 560 -+INTR_X86_MMX_PANDN = 561 -+INTR_X86_MMX_PAVG_B = 562 -+INTR_X86_MMX_PAVG_W = 563 -+INTR_X86_MMX_PCMPEQ_B = 564 -+INTR_X86_MMX_PCMPEQ_D = 565 -+INTR_X86_MMX_PCMPEQ_W = 566 -+INTR_X86_MMX_PCMPGT_B = 567 -+INTR_X86_MMX_PCMPGT_D = 568 -+INTR_X86_MMX_PCMPGT_W = 569 -+INTR_X86_MMX_PEXTR_W = 570 -+INTR_X86_MMX_PINSR_W = 571 -+INTR_X86_MMX_PMADD_WD = 572 -+INTR_X86_MMX_PMAXS_W = 573 -+INTR_X86_MMX_PMAXU_B = 574 -+INTR_X86_MMX_PMINS_W = 575 -+INTR_X86_MMX_PMINU_B = 576 -+INTR_X86_MMX_PMOVMSKB = 577 -+INTR_X86_MMX_PMULH_W = 578 -+INTR_X86_MMX_PMULHU_W = 579 -+INTR_X86_MMX_PMULL_W = 580 -+INTR_X86_MMX_PMULU_DQ = 581 -+INTR_X86_MMX_POR = 582 -+INTR_X86_MMX_PSAD_BW = 583 -+INTR_X86_MMX_PSLL_D = 584 -+INTR_X86_MMX_PSLL_Q = 585 -+INTR_X86_MMX_PSLL_W = 586 -+INTR_X86_MMX_PSLLI_D = 587 -+INTR_X86_MMX_PSLLI_Q = 588 -+INTR_X86_MMX_PSLLI_W = 589 -+INTR_X86_MMX_PSRA_D = 590 -+INTR_X86_MMX_PSRA_W = 591 -+INTR_X86_MMX_PSRAI_D = 592 -+INTR_X86_MMX_PSRAI_W = 593 -+INTR_X86_MMX_PSRL_D = 594 -+INTR_X86_MMX_PSRL_Q = 595 -+INTR_X86_MMX_PSRL_W = 596 -+INTR_X86_MMX_PSRLI_D = 597 -+INTR_X86_MMX_PSRLI_Q = 598 -+INTR_X86_MMX_PSRLI_W = 599 -+INTR_X86_MMX_PSUB_B = 600 -+INTR_X86_MMX_PSUB_D = 601 -+INTR_X86_MMX_PSUB_Q = 602 -+INTR_X86_MMX_PSUB_W = 603 -+INTR_X86_MMX_PSUBS_B = 604 -+INTR_X86_MMX_PSUBS_W = 605 -+INTR_X86_MMX_PSUBUS_B = 606 -+INTR_X86_MMX_PSUBUS_W = 607 -+INTR_X86_MMX_PUNPCKHBW = 608 -+INTR_X86_MMX_PUNPCKHDQ = 609 -+INTR_X86_MMX_PUNPCKHWD = 610 -+INTR_X86_MMX_PUNPCKLBW = 611 -+INTR_X86_MMX_PUNPCKLDQ = 612 -+INTR_X86_MMX_PUNPCKLWD = 613 -+INTR_X86_MMX_PXOR = 614 -+INTR_X86_SSE2_ADD_SD = 615 -+INTR_X86_SSE2_CLFLUSH = 616 -+INTR_X86_SSE2_CMP_PD = 617 -+INTR_X86_SSE2_CMP_SD = 618 -+INTR_X86_SSE2_COMIEQ_SD = 619 -+INTR_X86_SSE2_COMIGE_SD = 620 -+INTR_X86_SSE2_COMIGT_SD = 621 -+INTR_X86_SSE2_COMILE_SD = 622 -+INTR_X86_SSE2_COMILT_SD = 623 -+INTR_X86_SSE2_COMINEQ_SD = 624 -+INTR_X86_SSE2_CVTDQ2PD = 625 -+INTR_X86_SSE2_CVTDQ2PS = 626 -+INTR_X86_SSE2_CVTPD2DQ = 627 -+INTR_X86_SSE2_CVTPD2PS = 628 -+INTR_X86_SSE2_CVTPS2DQ = 629 -+INTR_X86_SSE2_CVTPS2PD = 630 -+INTR_X86_SSE2_CVTSD2SI = 631 -+INTR_X86_SSE2_CVTSD2SI64 = 632 -+INTR_X86_SSE2_CVTSD2SS = 633 -+INTR_X86_SSE2_CVTSI2SD = 634 -+INTR_X86_SSE2_CVTSI642SD = 635 -+INTR_X86_SSE2_CVTSS2SD = 636 -+INTR_X86_SSE2_CVTTPD2DQ = 637 -+INTR_X86_SSE2_CVTTPS2DQ = 638 -+INTR_X86_SSE2_CVTTSD2SI = 639 -+INTR_X86_SSE2_CVTTSD2SI64 = 640 -+INTR_X86_SSE2_DIV_SD = 641 -+INTR_X86_SSE2_LFENCE = 642 -+INTR_X86_SSE2_LOADU_DQ = 643 -+INTR_X86_SSE2_LOADU_PD = 644 -+INTR_X86_SSE2_MASKMOV_DQU = 645 -+INTR_X86_SSE2_MAX_PD = 646 -+INTR_X86_SSE2_MAX_SD = 647 -+INTR_X86_SSE2_MFENCE = 648 -+INTR_X86_SSE2_MIN_PD = 649 -+INTR_X86_SSE2_MIN_SD = 650 -+INTR_X86_SSE2_MOVMSK_PD = 651 -+INTR_X86_SSE2_MOVNT_DQ = 652 -+INTR_X86_SSE2_MOVNT_I = 653 -+INTR_X86_SSE2_MOVNT_PD = 654 -+INTR_X86_SSE2_MUL_SD = 655 -+INTR_X86_SSE2_PACKSSDW_128 = 656 -+INTR_X86_SSE2_PACKSSWB_128 = 657 -+INTR_X86_SSE2_PACKUSWB_128 = 658 -+INTR_X86_SSE2_PADDS_B = 659 -+INTR_X86_SSE2_PADDS_W = 660 -+INTR_X86_SSE2_PADDUS_B = 661 -+INTR_X86_SSE2_PADDUS_W = 662 -+INTR_X86_SSE2_PAVG_B = 663 -+INTR_X86_SSE2_PAVG_W = 664 -+INTR_X86_SSE2_PCMPEQ_B = 665 -+INTR_X86_SSE2_PCMPEQ_D = 666 -+INTR_X86_SSE2_PCMPEQ_W = 667 -+INTR_X86_SSE2_PCMPGT_B = 668 -+INTR_X86_SSE2_PCMPGT_D = 669 -+INTR_X86_SSE2_PCMPGT_W = 670 -+INTR_X86_SSE2_PMADD_WD = 671 -+INTR_X86_SSE2_PMAXS_W = 672 -+INTR_X86_SSE2_PMAXU_B = 673 -+INTR_X86_SSE2_PMINS_W = 674 -+INTR_X86_SSE2_PMINU_B = 675 -+INTR_X86_SSE2_PMOVMSKB_128 = 676 -+INTR_X86_SSE2_PMULH_W = 677 -+INTR_X86_SSE2_PMULHU_W = 678 -+INTR_X86_SSE2_PMULU_DQ = 679 -+INTR_X86_SSE2_PSAD_BW = 680 -+INTR_X86_SSE2_PSLL_D = 681 -+INTR_X86_SSE2_PSLL_DQ = 682 -+INTR_X86_SSE2_PSLL_DQ_BS = 683 -+INTR_X86_SSE2_PSLL_Q = 684 -+INTR_X86_SSE2_PSLL_W = 685 -+INTR_X86_SSE2_PSLLI_D = 686 -+INTR_X86_SSE2_PSLLI_Q = 687 -+INTR_X86_SSE2_PSLLI_W = 688 -+INTR_X86_SSE2_PSRA_D = 689 -+INTR_X86_SSE2_PSRA_W = 690 -+INTR_X86_SSE2_PSRAI_D = 691 -+INTR_X86_SSE2_PSRAI_W = 692 -+INTR_X86_SSE2_PSRL_D = 693 -+INTR_X86_SSE2_PSRL_DQ = 694 -+INTR_X86_SSE2_PSRL_DQ_BS = 695 -+INTR_X86_SSE2_PSRL_Q = 696 -+INTR_X86_SSE2_PSRL_W = 697 -+INTR_X86_SSE2_PSRLI_D = 698 -+INTR_X86_SSE2_PSRLI_Q = 699 -+INTR_X86_SSE2_PSRLI_W = 700 -+INTR_X86_SSE2_PSUBS_B = 701 -+INTR_X86_SSE2_PSUBS_W = 702 -+INTR_X86_SSE2_PSUBUS_B = 703 -+INTR_X86_SSE2_PSUBUS_W = 704 -+INTR_X86_SSE2_SQRT_PD = 705 -+INTR_X86_SSE2_SQRT_SD = 706 -+INTR_X86_SSE2_STOREL_DQ = 707 -+INTR_X86_SSE2_STOREU_DQ = 708 -+INTR_X86_SSE2_STOREU_PD = 709 -+INTR_X86_SSE2_SUB_SD = 710 -+INTR_X86_SSE2_UCOMIEQ_SD = 711 -+INTR_X86_SSE2_UCOMIGE_SD = 712 -+INTR_X86_SSE2_UCOMIGT_SD = 713 -+INTR_X86_SSE2_UCOMILE_SD = 714 -+INTR_X86_SSE2_UCOMILT_SD = 715 -+INTR_X86_SSE2_UCOMINEQ_SD = 716 -+INTR_X86_SSE3_ADDSUB_PD = 717 -+INTR_X86_SSE3_ADDSUB_PS = 718 -+INTR_X86_SSE3_HADD_PD = 719 -+INTR_X86_SSE3_HADD_PS = 720 -+INTR_X86_SSE3_HSUB_PD = 721 -+INTR_X86_SSE3_HSUB_PS = 722 -+INTR_X86_SSE3_LDU_DQ = 723 -+INTR_X86_SSE3_MONITOR = 724 -+INTR_X86_SSE3_MWAIT = 725 -+INTR_X86_SSE41_BLENDPD = 726 -+INTR_X86_SSE41_BLENDPS = 727 -+INTR_X86_SSE41_BLENDVPD = 728 -+INTR_X86_SSE41_BLENDVPS = 729 -+INTR_X86_SSE41_DPPD = 730 -+INTR_X86_SSE41_DPPS = 731 -+INTR_X86_SSE41_EXTRACTPS = 732 -+INTR_X86_SSE41_INSERTPS = 733 -+INTR_X86_SSE41_MOVNTDQA = 734 -+INTR_X86_SSE41_MPSADBW = 735 -+INTR_X86_SSE41_PACKUSDW = 736 -+INTR_X86_SSE41_PBLENDVB = 737 -+INTR_X86_SSE41_PBLENDW = 738 -+INTR_X86_SSE41_PCMPEQQ = 739 -+INTR_X86_SSE41_PEXTRB = 740 -+INTR_X86_SSE41_PEXTRD = 741 -+INTR_X86_SSE41_PEXTRQ = 742 -+INTR_X86_SSE41_PHMINPOSUW = 743 -+INTR_X86_SSE41_PMAXSB = 744 -+INTR_X86_SSE41_PMAXSD = 745 -+INTR_X86_SSE41_PMAXUD = 746 -+INTR_X86_SSE41_PMAXUW = 747 -+INTR_X86_SSE41_PMINSB = 748 -+INTR_X86_SSE41_PMINSD = 749 -+INTR_X86_SSE41_PMINUD = 750 -+INTR_X86_SSE41_PMINUW = 751 -+INTR_X86_SSE41_PMOVSXBD = 752 -+INTR_X86_SSE41_PMOVSXBQ = 753 -+INTR_X86_SSE41_PMOVSXBW = 754 -+INTR_X86_SSE41_PMOVSXDQ = 755 -+INTR_X86_SSE41_PMOVSXWD = 756 -+INTR_X86_SSE41_PMOVSXWQ = 757 -+INTR_X86_SSE41_PMOVZXBD = 758 -+INTR_X86_SSE41_PMOVZXBQ = 759 -+INTR_X86_SSE41_PMOVZXBW = 760 -+INTR_X86_SSE41_PMOVZXDQ = 761 -+INTR_X86_SSE41_PMOVZXWD = 762 -+INTR_X86_SSE41_PMOVZXWQ = 763 -+INTR_X86_SSE41_PMULDQ = 764 -+INTR_X86_SSE41_PTESTC = 765 -+INTR_X86_SSE41_PTESTNZC = 766 -+INTR_X86_SSE41_PTESTZ = 767 -+INTR_X86_SSE41_ROUND_PD = 768 -+INTR_X86_SSE41_ROUND_PS = 769 -+INTR_X86_SSE41_ROUND_SD = 770 -+INTR_X86_SSE41_ROUND_SS = 771 -+INTR_X86_SSE42_CRC32_16 = 772 -+INTR_X86_SSE42_CRC32_32 = 773 -+INTR_X86_SSE42_CRC32_8 = 774 -+INTR_X86_SSE42_CRC64_64 = 775 -+INTR_X86_SSE42_CRC64_8 = 776 -+INTR_X86_SSE42_PCMPESTRI128 = 777 -+INTR_X86_SSE42_PCMPESTRIA128 = 778 -+INTR_X86_SSE42_PCMPESTRIC128 = 779 -+INTR_X86_SSE42_PCMPESTRIO128 = 780 -+INTR_X86_SSE42_PCMPESTRIS128 = 781 -+INTR_X86_SSE42_PCMPESTRIZ128 = 782 -+INTR_X86_SSE42_PCMPESTRM128 = 783 -+INTR_X86_SSE42_PCMPGTQ = 784 -+INTR_X86_SSE42_PCMPISTRI128 = 785 -+INTR_X86_SSE42_PCMPISTRIA128 = 786 -+INTR_X86_SSE42_PCMPISTRIC128 = 787 -+INTR_X86_SSE42_PCMPISTRIO128 = 788 -+INTR_X86_SSE42_PCMPISTRIS128 = 789 -+INTR_X86_SSE42_PCMPISTRIZ128 = 790 -+INTR_X86_SSE42_PCMPISTRM128 = 791 -+INTR_X86_SSE_ADD_SS = 792 -+INTR_X86_SSE_CMP_PS = 793 -+INTR_X86_SSE_CMP_SS = 794 -+INTR_X86_SSE_COMIEQ_SS = 795 -+INTR_X86_SSE_COMIGE_SS = 796 -+INTR_X86_SSE_COMIGT_SS = 797 -+INTR_X86_SSE_COMILE_SS = 798 -+INTR_X86_SSE_COMILT_SS = 799 -+INTR_X86_SSE_COMINEQ_SS = 800 -+INTR_X86_SSE_CVTPD2PI = 801 -+INTR_X86_SSE_CVTPI2PD = 802 -+INTR_X86_SSE_CVTPI2PS = 803 -+INTR_X86_SSE_CVTPS2PI = 804 -+INTR_X86_SSE_CVTSI2SS = 805 -+INTR_X86_SSE_CVTSI642SS = 806 -+INTR_X86_SSE_CVTSS2SI = 807 -+INTR_X86_SSE_CVTSS2SI64 = 808 -+INTR_X86_SSE_CVTTPD2PI = 809 -+INTR_X86_SSE_CVTTPS2PI = 810 -+INTR_X86_SSE_CVTTSS2SI = 811 -+INTR_X86_SSE_CVTTSS2SI64 = 812 -+INTR_X86_SSE_DIV_SS = 813 -+INTR_X86_SSE_LDMXCSR = 814 -+INTR_X86_SSE_LOADU_PS = 815 -+INTR_X86_SSE_MAX_PS = 816 -+INTR_X86_SSE_MAX_SS = 817 -+INTR_X86_SSE_MIN_PS = 818 -+INTR_X86_SSE_MIN_SS = 819 -+INTR_X86_SSE_MOVMSK_PS = 820 -+INTR_X86_SSE_MOVNT_PS = 821 -+INTR_X86_SSE_MUL_SS = 822 -+INTR_X86_SSE_PSHUF_W = 823 -+INTR_X86_SSE_RCP_PS = 824 -+INTR_X86_SSE_RCP_SS = 825 -+INTR_X86_SSE_RSQRT_PS = 826 -+INTR_X86_SSE_RSQRT_SS = 827 -+INTR_X86_SSE_SFENCE = 828 -+INTR_X86_SSE_SQRT_PS = 829 -+INTR_X86_SSE_SQRT_SS = 830 -+INTR_X86_SSE_STMXCSR = 831 -+INTR_X86_SSE_STOREU_PS = 832 -+INTR_X86_SSE_SUB_SS = 833 -+INTR_X86_SSE_UCOMIEQ_SS = 834 -+INTR_X86_SSE_UCOMIGE_SS = 835 -+INTR_X86_SSE_UCOMIGT_SS = 836 -+INTR_X86_SSE_UCOMILE_SS = 837 -+INTR_X86_SSE_UCOMILT_SS = 838 -+INTR_X86_SSE_UCOMINEQ_SS = 839 -+INTR_X86_SSSE3_PABS_B = 840 -+INTR_X86_SSSE3_PABS_B_128 = 841 -+INTR_X86_SSSE3_PABS_D = 842 -+INTR_X86_SSSE3_PABS_D_128 = 843 -+INTR_X86_SSSE3_PABS_W = 844 -+INTR_X86_SSSE3_PABS_W_128 = 845 -+INTR_X86_SSSE3_PHADD_D = 846 -+INTR_X86_SSSE3_PHADD_D_128 = 847 -+INTR_X86_SSSE3_PHADD_SW = 848 -+INTR_X86_SSSE3_PHADD_SW_128 = 849 -+INTR_X86_SSSE3_PHADD_W = 850 -+INTR_X86_SSSE3_PHADD_W_128 = 851 -+INTR_X86_SSSE3_PHSUB_D = 852 -+INTR_X86_SSSE3_PHSUB_D_128 = 853 -+INTR_X86_SSSE3_PHSUB_SW = 854 -+INTR_X86_SSSE3_PHSUB_SW_128 = 855 -+INTR_X86_SSSE3_PHSUB_W = 856 -+INTR_X86_SSSE3_PHSUB_W_128 = 857 -+INTR_X86_SSSE3_PMADD_UB_SW = 858 -+INTR_X86_SSSE3_PMADD_UB_SW_128 = 859 -+INTR_X86_SSSE3_PMUL_HR_SW = 860 -+INTR_X86_SSSE3_PMUL_HR_SW_128 = 861 -+INTR_X86_SSSE3_PSHUF_B = 862 -+INTR_X86_SSSE3_PSHUF_B_128 = 863 -+INTR_X86_SSSE3_PSIGN_B = 864 -+INTR_X86_SSSE3_PSIGN_B_128 = 865 -+INTR_X86_SSSE3_PSIGN_D = 866 -+INTR_X86_SSSE3_PSIGN_D_128 = 867 -+INTR_X86_SSSE3_PSIGN_W = 868 -+INTR_X86_SSSE3_PSIGN_W_128 = 869 -+INTR_XCORE_BITREV = 870 -+INTR_XCORE_CHKCT = 871 -+INTR_XCORE_CLRE = 872 -+INTR_XCORE_EEU = 873 -+INTR_XCORE_FREER = 874 -+INTR_XCORE_GETID = 875 -+INTR_XCORE_GETR = 876 -+INTR_XCORE_GETTS = 877 -+INTR_XCORE_IN = 878 -+INTR_XCORE_INCT = 879 -+INTR_XCORE_INSHR = 880 -+INTR_XCORE_INT = 881 -+INTR_XCORE_OUT = 882 -+INTR_XCORE_OUTCT = 883 -+INTR_XCORE_OUTSHR = 884 -+INTR_XCORE_OUTT = 885 -+INTR_XCORE_SETC = 886 -+INTR_XCORE_SETD = 887 -+INTR_XCORE_SETPT = 888 -+INTR_XCORE_SETTW = 889 -+INTR_XCORE_SETV = 890 -+INTR_XCORE_SYNCR = 891 -+INTR_XCORE_WAITEVENT = 892 -Index: _core.c -=================================================================== ---- _core.c (revision 105) -+++ _core.c (working copy) -@@ -807,7 +807,7 @@ - _wrap_pass( EdgeProfiler ) - _wrap_pass( FunctionAttrs ) - _wrap_pass( FunctionInlining ) --_wrap_pass( GEPSplitter ) -+//_wrap_pass( GEPSplitter ) - _wrap_pass( GlobalDCE ) - _wrap_pass( GlobalOptimizer ) - _wrap_pass( GlobalsModRef ) -@@ -822,11 +822,11 @@ - _wrap_pass( LazyValueInfo ) - _wrap_pass( LCSSA ) - _wrap_pass( LICM ) --_wrap_pass( LiveValues ) -+//_wrap_pass( LiveValues ) - _wrap_pass( LoopDeletion ) - _wrap_pass( LoopDependenceAnalysis ) - _wrap_pass( LoopExtractor ) --_wrap_pass( LoopIndexSplit ) -+//_wrap_pass( LoopIndexSplit ) - _wrap_pass( LoopRotate ) - _wrap_pass( LoopSimplify ) - _wrap_pass( LoopStrengthReduce ) -@@ -841,7 +841,7 @@ - _wrap_pass( NoProfileInfo ) - _wrap_pass( OptimalEdgeProfiler ) - _wrap_pass( PartialInlining ) --_wrap_pass( PartialSpecialization ) -+//_wrap_pass( PartialSpecialization ) - _wrap_pass( PostDomOnlyPrinter ) - _wrap_pass( PostDomOnlyViewer ) - _wrap_pass( PostDomPrinter ) -@@ -855,7 +855,7 @@ - _wrap_pass( ScalarEvolutionAliasAnalysis ) - _wrap_pass( ScalarReplAggregates ) - _wrap_pass( SCCP ) --_wrap_pass( SimplifyHalfPowrLibCalls ) -+//_wrap_pass( SimplifyHalfPowrLibCalls ) - _wrap_pass( SimplifyLibCalls ) - _wrap_pass( SingleLoopExtractor ) - _wrap_pass( StripDeadPrototypes ) -@@ -1162,7 +1162,7 @@ - Py_RETURN_NONE; - } - --_wrap_obj2obj(LLVMInlineFunction, LLVMValueRef, int) -+//_wrap_obj2obj(LLVMInlineFunction, LLVMValueRef, int) - - /* Expose the void* inside a PyCObject as a PyLong. This allows us to - * use it as a unique ID. */ -@@ -1569,7 +1569,7 @@ - _pass( EdgeProfiler ) - _pass( FunctionAttrs ) - _pass( FunctionInlining ) -- _pass( GEPSplitter ) -+ //_pass( GEPSplitter ) - _pass( GlobalDCE ) - _pass( GlobalOptimizer ) - _pass( GlobalsModRef ) -@@ -1584,11 +1584,11 @@ - _pass( LazyValueInfo ) - _pass( LCSSA ) - _pass( LICM ) -- _pass( LiveValues ) -+ //_pass( LiveValues ) - _pass( LoopDeletion ) - _pass( LoopDependenceAnalysis ) - _pass( LoopExtractor ) -- _pass( LoopIndexSplit ) -+ //_pass( LoopIndexSplit ) - _pass( LoopRotate ) - _pass( LoopSimplify ) - _pass( LoopStrengthReduce ) -@@ -1603,7 +1603,7 @@ - _pass( NoProfileInfo ) - _pass( OptimalEdgeProfiler ) - _pass( PartialInlining ) -- _pass( PartialSpecialization ) -+ //_pass( PartialSpecialization ) - _pass( PostDomOnlyPrinter ) - _pass( PostDomOnlyViewer ) - _pass( PostDomPrinter ) -@@ -1617,7 +1617,7 @@ - _pass( ScalarEvolutionAliasAnalysis ) - _pass( ScalarReplAggregates ) - _pass( SCCP ) -- _pass( SimplifyHalfPowrLibCalls ) -+ //_pass( SimplifyHalfPowrLibCalls ) - _pass( SimplifyLibCalls ) - _pass( SingleLoopExtractor ) - _pass( StripDeadPrototypes ) -@@ -1672,7 +1672,7 @@ - /* Misc */ - _method( LLVMGetIntrinsic ) - _method( LLVMLoadLibraryPermanently ) -- _method( LLVMInlineFunction ) -+ //_method( LLVMInlineFunction ) - _method( PyCObjectVoidPtrToPyLong ) - - { NULL } -Index: extra.h -=================================================================== ---- extra.h (revision 105) -+++ extra.h (working copy) -@@ -181,7 +181,7 @@ - /* Wraps llvm::InlineFunction(). Inlines a function. C is the call - * instruction, created by LLVMBuildCall. Even if it fails, the Function - * containing the call is still in a proper state (not changed). */ --int LLVMInlineFunction(LLVMValueRef call); -+//int LLVMInlineFunction(LLVMValueRef call); - - /* Wraps llvm::getAlignmentFromAttrs from Attributes.h. Compliments the - * already available LLVMSetParamAlignment(). */ -@@ -209,13 +209,13 @@ - declare_pass( DomPrinter ) - declare_pass( DomViewer ) - declare_pass( EdgeProfiler ) --declare_pass( GEPSplitter ) -+//declare_pass( GEPSplitter ) - declare_pass( GlobalsModRef ) - declare_pass( InstCount ) - declare_pass( InstructionNamer ) - declare_pass( LazyValueInfo ) - declare_pass( LCSSA ) --declare_pass( LiveValues ) -+//declare_pass( LiveValues ) - declare_pass( LoopDependenceAnalysis ) - declare_pass( LoopExtractor ) - declare_pass( LoopSimplify ) -@@ -227,7 +227,7 @@ - declare_pass( NoProfileInfo ) - declare_pass( OptimalEdgeProfiler ) - declare_pass( PartialInlining ) --declare_pass( PartialSpecialization ) -+//declare_pass( PartialSpecialization ) - declare_pass( PostDomOnlyPrinter ) - declare_pass( PostDomOnlyViewer ) - declare_pass( PostDomPrinter ) diff --git a/llvm/__init__.py b/llvm/__init__.py index 8f61f35..e3e785f 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -1,154 +1,42 @@ -""" -Common classes related to LLVM. -""" - from ._version import get_versions __version__ = get_versions()['version'] del get_versions -from weakref import WeakValueDictionary -from . import _core +from llvmpy import extra +version = extra.get_llvm_version() +del extra -#===----------------------------------------------------------------------=== -# LLVM Version -#===----------------------------------------------------------------------=== +class Wrapper(object): + def __init__(self, ptr): + assert ptr + self.__ptr = ptr -version = _core.LLVMGetVersion() + @property + def _ptr(self): + try: + return self.__ptr + except AttributeError: + raise AttributeError("_ptr resource has been removed") -def require_version_at_least(major, minor): - '''Sentry to guard version requirement - ''' - if version < (major, minor): - raise Exception(major, minor) + @_ptr.deleter + def _ptr(self): + del self.__ptr -#===----------------------------------------------------------------------=== -# Exceptions -#===----------------------------------------------------------------------=== + +def _extract_ptrs(objs): + return [(x._ptr if x is not None else None) + for x in objs] class LLVMException(Exception): - """Generic LLVM exception.""" - - def __init__(self, msg=""): - Exception.__init__(self, msg) - - -#===----------------------------------------------------------------------=== -# Ownables -#===----------------------------------------------------------------------=== - -class Ownable(object): - """Objects that can be owned. - - Modules and Module Providers can be owned, i.e., the responsibility of - destruction of ownable objects can be handed over to other objects. The - llvm.Ownable class represents objects that can be so owned. This class - is NOT intended for public use. - """ - - def __init__(self, ptr, del_fn): - self.ptr = ptr - self.owner = None - self.del_fn = del_fn - - def _own(self, owner): - if self.owner: - raise LLVMException("object already owned") - self.owner = owner - - def _disown(self): - if not self.owner: - raise LLVMException("not owned") - self.owner = None - - def __del__(self): - if not self.owner: - self.del_fn(self.ptr) - - -#===----------------------------------------------------------------------=== -# Dummy owner, will not delete ownee. Be careful. -#===----------------------------------------------------------------------=== - -class DummyOwner(object): pass - -#===----------------------------------------------------------------------=== -# A metaclass to prevent aliasing. It stores a (weak) reference to objects -# constructed based on a PyCObject. If an object is constructed based on a -# PyCObject with the same underlying pointer as a previous object, a reference -# to the previous object is returned rather than a new one. -#===----------------------------------------------------------------------=== - -class _ObjectCache(type): - """A metaclass to prevent aliasing. - - Classes using 'ObjectCache' as a metaclass must have constructors - that take a PyCObject as their first argument. When the class is - called (to create a new instance of the class), the value of the - pointer wrapped by the PyCObj is checked: - - If no previous object has been created based on the same - underlying pointer (note that different PyCObject objects can - wrap the same pointer), the object will be initialized as - usual and returned. - - If a previous has been created based on the same pointer, - then a reference to that object will be returned, and no - object initialization is performed. - """ - - __instances = WeakValueDictionary() - - def __call__(cls, ptr, *args, **kwargs): - objid = _core.PyCObjectVoidPtrToPyLong(ptr) - key = "%s:%d" % (cls.__name__, objid) - obj = _ObjectCache.__instances.get(key) - if obj is None: - obj = super(_ObjectCache, cls).__call__(ptr, *args, **kwargs) - _ObjectCache.__instances[key] = obj - return obj - - @staticmethod - def forget(obj): - objid = _core.PyCObjectVoidPtrToPyLong(obj.ptr) - key = "%s:%d" % (type(obj).__name__, objid) - if key in _ObjectCache.__instances: - del _ObjectCache.__instances[key] - - -#===----------------------------------------------------------------------=== -# Cacheables -#===----------------------------------------------------------------------=== - -# version 2/3 compatibility help -# version 2 metaclass -# class Cacheable(object): -# __metaclass__ = _ObjectCache # Doing nothing for version 3 -# -# version 3 metaclass -# class Cacheable(metaclass=_ObjectCache): -# -# Reference: http://mikewatkins.ca/2008/11/29/python-2-and-3-metaclasses/#using-the-metaclass-in-python-3-x -ObjectCache = _ObjectCache('ObjectCache', (object, ), {}) - -class Cacheable(ObjectCache): - """Objects that can be cached. - - Objects that wrap a PyCObject are cached to avoid "aliasing", i.e., - two Python objects each containing a PyCObject which internally points - to the same C pointer.""" - - def forget(self): - ObjectCache.forget(self) - - def test(verbosity=1): """test(verbosity=1) -> TextTestResult - Run self-test, and return unittest.runner.TextTestResult object. - """ + Run self-test, and return unittest.runner.TextTestResult object. + """ from llvm.test_llvmpy import run return run(verbosity=verbosity) + diff --git a/llvm/_core.cpp b/llvm/_core.cpp deleted file mode 100644 index db5287e..0000000 --- a/llvm/_core.cpp +++ /dev/null @@ -1,2212 +0,0 @@ -/* - * Copyright (c) 2008-10, Mahadevan R All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of this software, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* our includes */ -#include "wrap.h" -#include "extra.h" - - - -// Python include -#include "Python.h" - -/* LLVM includes */ -#include "llvm-c/Analysis.h" -#include "llvm-c/Transforms/Scalar.h" -#include "llvm-c/ExecutionEngine.h" -#include "llvm-c/Target.h" -#include "llvm-c/Transforms/IPO.h" - -#include "llvm/Support/CommandLine.h" -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 - #include "llvm-c/Linker.h" -#else - typedef unsigned int LLVMLinkerMode; -#endif - -/* Compatibility with Python 2.4: Py_ssize_t is not available. */ -#ifndef PY_SSIZE_T_MAX -typedef int Py_ssize_t; -#endif - - -// explicit specializations -template <> PyObject* pycap_new(int i) -{ - return PyLong_FromLong(static_cast(i)); -} - -template <> PyObject* pycap_new(unsigned long i) -{ - return PyLong_FromLong(static_cast(i)); -} - -template <> PyObject* pycap_new(LLVMTypeKind i) -{ - return PyLong_FromLong(static_cast(i)); -} - -template <> PyObject* pycap_new(LLVMLinkage i) -{ - return PyLong_FromLong(static_cast(i)); -} - -template <> PyObject* pycap_new(LLVMVisibility i) -{ - return PyLong_FromLong(static_cast(i)); -} - -template <> PyObject* pycap_new(LLVMByteOrdering i) -{ - return PyLong_FromLong(static_cast(i)); -} - -template <> PyObject* pycap_new(unsigned PY_LONG_LONG ull) -{ - return PyLong_FromUnsignedLongLong(ull); -} - -template <> PyObject* pycap_new(PY_LONG_LONG ll) -{ - return PyLong_FromLongLong(ll); -} - -/*===----------------------------------------------------------------------===*/ -/* Modules */ -/*===----------------------------------------------------------------------===*/ - -static PyObject * -_wLLVMModuleCreateWithName(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const char *s; - - if (!PyArg_ParseTuple(args, "s:LLVMModuleCreateWithName", &s)) { - return NULL; - } - - const LLVMModuleRef module = LLVMModuleCreateWithName(s); - return pycap_new(module); - LLVMPY_CATCH_ALL -} - -_wrap_obj2str(LLVMGetDataLayout, LLVMModuleRef) -_wrap_objstr2none(LLVMSetDataLayout, LLVMModuleRef) -_wrap_obj2str(LLVMGetModuleIdentifier, LLVMModuleRef) -_wrap_objstr2none(LLVMSetModuleIdentifier, LLVMModuleRef) -_wrap_obj2str(LLVMGetTarget, LLVMModuleRef) -_wrap_objstr2none(LLVMSetTarget, LLVMModuleRef) -_wrap_objstr2none(LLVMModuleAddLibrary, LLVMModuleRef) -_wrap_objstr2obj(LLVMGetTypeByName, LLVMModuleRef, LLVMTypeRef) -_wrap_obj2none(LLVMDumpModule, LLVMModuleRef) -_wrap_obj2none(LLVMDisposeModule, LLVMModuleRef) -_wrap_dumper(LLVMDumpModuleToString, LLVMModuleRef) - _wrap_obj2obj( LLVMModuleGetPointerSize, LLVMModuleRef, int) -_wrap_objstrobj2obj(LLVMModuleGetOrInsertFunction, LLVMModuleRef, - LLVMTypeRef, LLVMValueRef) - -static PyObject * -_wLLVMVerifyModule(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const LLVMModuleRef m = get_object_arg(args) ; - if (!m) return NULL; - - char *outmsg = 0; - (void) LLVMVerifyModule(m, LLVMReturnStatusAction, &outmsg); - - PyObject *ret; - if (outmsg) { - ret = PyUnicode_FromString(outmsg); - LLVMDisposeMessage(outmsg); - } else { - ret = PyUnicode_FromString(""); - } - - return ret; - LLVMPY_CATCH_ALL -} - -///// unused -// typedef LLVMModuleRef (*asm_or_bc_fn_t)(const char *A, unsigned Len, char **OutMessage); - - -static PyObject* -_wLLVMGetModuleFromAssembly(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const char * str; -#if (PY_MAJOR_VERSION >= 3) - if ( !PyArg_ParseTuple(args, "y", &str) ){ -#else - if ( !PyArg_ParseTuple(args, "s", &str) ){ -#endif - return NULL; - } - - char * outmsg = 0; - const LLVMModuleRef mod = LLVMGetModuleFromAssembly(str, &outmsg); - - if ( !mod ){ - if ( outmsg ){ - PyObject * ret = PyUnicode_FromString(outmsg); - LLVMDisposeMessage(outmsg); - return ret; - } else { - Py_RETURN_NONE; - } - } - - return pycap_new(mod); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMGetModuleFromBitcode(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj ; - - if (!PyArg_ParseTuple(args, "S", &obj)) - return NULL; - - const char *start = PyBytes_AsString(obj); - const Py_ssize_t len = PyBytes_Size(obj); - - char *outmsg = 0; - LLVMModuleRef m = LLVMGetModuleFromBitcode(start, len, &outmsg); - - PyObject *ret; - if (!m) { - if (outmsg) { - ret = PyUnicode_FromString(outmsg); - LLVMDisposeMessage(outmsg); - return ret; - } else { - Py_RETURN_NONE; - } - } - - return pycap_new(m); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMGetBitcodeFromModule(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const LLVMModuleRef m = get_object_arg(args) ; - if (!m ) return NULL; - - size_t len; - const unsigned char *ubytes = LLVMGetBitcodeFromModule(m, &len) ; - if ( !ubytes ) Py_RETURN_NONE; - - const char *chars = reinterpret_cast(ubytes) ; - PyObject *ret = PyBytes_FromStringAndSize(chars, len); - delete [] ubytes; - return ret; - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMGetNativeCodeFromModule(PyObject * self, PyObject * args) -{ - LLVMPY_TRY - PyObject * arg_m; - int arg_use_asm; - - if (!PyArg_ParseTuple(args, "Oi", &arg_m, &arg_use_asm)) - return NULL; - - const LLVMModuleRef m = pycap_get( arg_m ) ; - - std::string error; - size_t len; - unsigned const char * ubytes - = LLVMGetNativeCodeFromModule(m, arg_use_asm, &len, error); - if ( !error.empty() ){ - PyErr_SetString(PyExc_RuntimeError, error.c_str()); - } - - const char *chars = reinterpret_cast(ubytes) ; - PyObject * ret = PyBytes_FromStringAndSize(chars, len); - - delete [] ubytes; - - return ret; - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMLinkModules(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - size_t mode = 0; - - PyObject *dest_obj, *src_obj ; - if (!PyArg_ParseTuple(args, "OO|I", &dest_obj, &src_obj, &mode)) - return NULL; - - const LLVMModuleRef dest = pycap_get(dest_obj ) ; - const LLVMModuleRef src = pycap_get(src_obj) ; - - PyObject *ret = NULL; - char *errmsg = NULL; - if (LLVMLinkModules(dest, src, (LLVMLinkerMode)mode, &errmsg)) { - if (errmsg) { - ret = PyUnicode_FromString(errmsg); - LLVMDisposeMessage(errmsg); - } else { - ret = PyUnicode_FromString("Link error"); - } - return ret; - } - - /* note: success => None, failure => string with error message */ - Py_RETURN_NONE; - LLVMPY_CATCH_ALL -} - -_wrap_objstr2obj(LLVMModuleGetOrInsertNamedMetaData, LLVMModuleRef, LLVMNamedMDRef) -_wrap_objstr2obj(LLVMModuleGetNamedMetaData, LLVMModuleRef, LLVMNamedMDRef) -_wrap_obj2obj(LLVMCloneModule, LLVMModuleRef, LLVMModuleRef) - -/*===----------------------------------------------------------------------===*/ -/* Types */ -/*===----------------------------------------------------------------------===*/ - -/*===-- General ----------------------------------------------------------===*/ - -_wrap_obj2obj(LLVMGetTypeKind, LLVMTypeRef, int) -_wrap_dumper(LLVMDumpTypeToString, LLVMTypeRef) - -/*===-- Integer types ----------------------------------------------------===*/ - -_wrap_none2obj(LLVMInt1Type, LLVMTypeRef) -_wrap_none2obj(LLVMInt8Type, LLVMTypeRef) -_wrap_none2obj(LLVMInt16Type, LLVMTypeRef) -_wrap_none2obj(LLVMInt32Type, LLVMTypeRef) -_wrap_none2obj(LLVMInt64Type, LLVMTypeRef) -_wrap_int2obj(LLVMIntType, LLVMTypeRef) -_wrap_obj2obj(LLVMGetIntTypeWidth, LLVMTypeRef, int) - -/*===-- Floating-point types ---------------------------------------------===*/ - -_wrap_none2obj(LLVMFloatType, LLVMTypeRef) -_wrap_none2obj(LLVMDoubleType, LLVMTypeRef) -_wrap_none2obj(LLVMX86FP80Type, LLVMTypeRef) -_wrap_none2obj(LLVMFP128Type, LLVMTypeRef) -_wrap_none2obj(LLVMPPCFP128Type, LLVMTypeRef) - -/*===-- Function types ---------------------------------------------------===*/ - -_wrap_objlistint2obj(LLVMFunctionType, LLVMTypeRef, LLVMTypeRef, LLVMTypeRef) -_wrap_obj2obj(LLVMIsFunctionVarArg, LLVMTypeRef, int) -_wrap_obj2obj(LLVMGetReturnType, LLVMTypeRef, LLVMTypeRef) -_wrap_obj2obj(LLVMCountParamTypes, LLVMTypeRef, int) - -/* The LLVMGetParamTypes and LLVMGetStructElementTypes functions both - * have the same signatures. The following implementation takes advantage - * of this. - */ - -typedef void (*obj2arr_fn_t)(LLVMTypeRef ty, LLVMTypeRef *outv); -typedef unsigned (*arrcnt_fn_t)(LLVMTypeRef ty); - -static PyObject * -obj2arr(PyObject *self, PyObject *args, arrcnt_fn_t cntfunc, obj2arr_fn_t arrfunc) -{ - size_t param_count; - - /* get the function object ptr */ - const LLVMTypeRef type = get_object_arg(args) ; - - /* get param count */ - param_count = cntfunc(type); - - /* alloc enough space for all of them */ - LLVMTypeRef* param_types = new LLVMTypeRef[param_count] ; - - /* call LLVM func */ - arrfunc(type, param_types); - - /* create a list from the array */ - PyObject *list = make_list(param_types, param_count); - - /* free temp storage */ - delete [] param_types ; - - return list; -} - -static PyObject * -_wLLVMGetFunctionTypeParams(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - return obj2arr(self, args, LLVMCountParamTypes, LLVMGetParamTypes); - LLVMPY_CATCH_ALL -} - -/*===-- Struct types -----------------------------------------------------===*/ - -_wrap_listint2obj(LLVMStructType, LLVMTypeRef, LLVMTypeRef) -_wrap_str2obj(LLVMStructTypeIdentified, LLVMTypeRef) -_wrap_objlistint2none(LLVMSetStructBody, LLVMTypeRef, LLVMTypeRef) -_wrap_obj2obj(LLVMCountStructElementTypes, LLVMTypeRef, int) -_wrap_obj2str(LLVMGetStructName, LLVMTypeRef) -_wrap_objstr2none(LLVMSetStructName, LLVMTypeRef) - - -static PyObject * -_wLLVMGetStructElementTypes(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - return obj2arr(self, args, LLVMCountStructElementTypes, - LLVMGetStructElementTypes); - LLVMPY_CATCH_ALL -} - - -_wrap_obj2obj(LLVMIsPackedStruct, LLVMTypeRef, int) -_wrap_obj2obj(LLVMIsOpaqueStruct, LLVMTypeRef, int) -_wrap_obj2obj(LLVMIsLiteralStruct, LLVMTypeRef, int) - -/*===-- Array types ------------------------------------------------------===*/ - -_wrap_objint2obj(LLVMArrayType, LLVMTypeRef, LLVMTypeRef) -_wrap_obj2obj(LLVMGetElementType, LLVMTypeRef, LLVMTypeRef) -_wrap_obj2obj(LLVMGetArrayLength, LLVMTypeRef, int) - -/*===-- Pointer types ----------------------------------------------------===*/ - -_wrap_objint2obj(LLVMPointerType, LLVMTypeRef, LLVMTypeRef) -_wrap_obj2obj(LLVMGetPointerAddressSpace, LLVMTypeRef, int) - -/*===-- Vector type ------------------------------------------------------===*/ - -_wrap_objint2obj(LLVMVectorType, LLVMTypeRef, LLVMTypeRef) -_wrap_obj2obj(LLVMGetVectorSize, LLVMTypeRef, int) - -/*===-- Other types ------------------------------------------------------===*/ - -_wrap_none2obj(LLVMVoidType, LLVMTypeRef) -_wrap_none2obj(LLVMLabelType, LLVMTypeRef) - -/*===-- Type handles -----------------------------------------------------===*/ - -/* -_wrap_obj2obj(LLVMCreateTypeHandle, LLVMTypeRef, LLVMTypeHandleRef) -_wrap_obj2obj(LLVMResolveTypeHandle, LLVMTypeHandleRef, LLVMTypeRef) -_wrap_obj2none(LLVMDisposeTypeHandle, LLVMTypeHandleRef) -*/ - - -/*===----------------------------------------------------------------------===*/ -/* Values */ -/*===----------------------------------------------------------------------===*/ - -/* Operations on all values */ - -_wrap_obj2obj(LLVMTypeOf, LLVMValueRef, LLVMTypeRef) -_wrap_obj2str(LLVMGetValueName, LLVMValueRef) -_wrap_objstr2none(LLVMSetValueName, LLVMValueRef) -_wrap_obj2none(LLVMDumpValue, LLVMValueRef) -_wrap_dumper(LLVMDumpValueToString, LLVMValueRef) -_wrap_obj2obj(LLVMValueGetID, LLVMValueRef, int) -_wrap_obj2obj(LLVMValueGetNumUses, LLVMValueRef, int) - -static PyObject * -_wLLVMValueGetUses(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const LLVMValueRef value = get_object_arg(args) ; - - LLVMValueRef *uses = 0; - size_t n = LLVMValueGetUses(value, &uses); - - PyObject *list = make_list(uses, n); - if (n > 0) - LLVMDisposeValueRefArray(uses); - - return list; - LLVMPY_CATCH_ALL -} - -/*===-- Users ------------------------------------------------------------===*/ - -_wrap_obj2obj(LLVMUserGetNumOperands, LLVMValueRef, int) -_wrap_objint2obj(LLVMUserGetOperand, LLVMValueRef, LLVMValueRef) - -/*===-- Constant Values --------------------------------------------------===*/ - -/* Operations on constants of any type */ - -_wrap_obj2obj(LLVMConstNull, LLVMTypeRef, LLVMValueRef) -_wrap_obj2obj(LLVMConstAllOnes, LLVMTypeRef, LLVMValueRef) -_wrap_obj2obj(LLVMGetUndef, LLVMTypeRef, LLVMValueRef) -_wrap_obj2obj(LLVMIsConstant, LLVMValueRef, int) -_wrap_obj2obj(LLVMIsNull, LLVMValueRef, int) -_wrap_obj2obj(LLVMIsUndef, LLVMValueRef, int) - -/* Operations on scalar constants */ - -static PyObject * -_wLLVMConstInt(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj; - unsigned PY_LONG_LONG n; - int sign_extend; - - if (!PyArg_ParseTuple(args, "OKi", &obj, &n, &sign_extend)) - return NULL; - - const LLVMTypeRef ty = pycap_get( obj ) ; - - const LLVMValueRef val = LLVMConstInt(ty, n, sign_extend); - - return pycap_new(val); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMConstReal(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj; - double d; - - if (!PyArg_ParseTuple(args, "Od", &obj, &d)) - return NULL; - - const LLVMTypeRef ty = pycap_get( obj ) ; - - const LLVMValueRef val = LLVMConstReal(ty, d); - return pycap_new(val); - LLVMPY_CATCH_ALL -} - -_wrap_objstr2obj(LLVMConstRealOfString, LLVMTypeRef, LLVMValueRef) -_wrap_obj2obj(LLVMConstIntGetZExtValue, LLVMValueRef, llvmwrap_ull) -_wrap_obj2obj(LLVMConstIntGetSExtValue, LLVMValueRef, llvmwrap_ll) - -/* Operations on composite constants */ - -static PyObject * -_wLLVMConstString(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const char *s; - int dont_null_terminate; - - if (!PyArg_ParseTuple(args, "si:LLVMConstString", &s, &dont_null_terminate)) { - return NULL; - } - - LLVMValueRef val = LLVMConstString(s, strlen(s), dont_null_terminate); - return pycap_new(val); - LLVMPY_CATCH_ALL -} - -_wrap_objlist2obj(LLVMConstArray, LLVMTypeRef, LLVMValueRef, LLVMValueRef) -_wrap_listint2obj(LLVMConstStruct, LLVMValueRef, LLVMValueRef) -_wrap_list2obj(LLVMConstVector, LLVMValueRef, LLVMValueRef) - -/* Constant expressions */ - -_wrap_obj2obj(LLVMGetConstExprOpcode, LLVMValueRef, int) -_wrap_obj2str(LLVMGetConstExprOpcodeName, LLVMValueRef) -_wrap_obj2obj(LLVMSizeOf, LLVMTypeRef, LLVMValueRef) -_wrap_obj2obj(LLVMConstNeg, LLVMValueRef, LLVMValueRef) -_wrap_obj2obj(LLVMConstNot, LLVMValueRef, LLVMValueRef) - -_wrap_objobj2obj(LLVMConstAdd, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFAdd, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstSub, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFSub, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstMul, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFMul, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstUDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstSDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstURem, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstSRem, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFRem, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstAnd, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstOr, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstXor, LLVMValueRef, LLVMValueRef, LLVMValueRef) - -_wrap_enumobjobj2obj(LLVMConstICmp, LLVMIntPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_enumobjobj2obj(LLVMConstFCmp, LLVMRealPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef) - -_wrap_objobj2obj(LLVMConstShl, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstLShr, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstAShr, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objlist2obj(LLVMConstGEP, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstTrunc, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstSExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstZExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFPTrunc, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFPExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstUIToFP, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstSIToFP, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFPToUI, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstFPToSI, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstPtrToInt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstIntToPtr, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstBitCast, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobj2obj(LLVMConstSelect, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMConstExtractElement, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobj2obj(LLVMConstInsertElement, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobj2obj(LLVMConstShuffleVector, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) - - -/*===----------------------------------------------------------------------===*/ -/* Globals */ -/*===----------------------------------------------------------------------===*/ - -/*===-- Globals ----------------------------------------------------------===*/ - -_wrap_obj2obj(LLVMGetGlobalParent, LLVMValueRef, LLVMModuleRef) -_wrap_obj2obj(LLVMIsDeclaration, LLVMValueRef, int) -_wrap_obj2obj(LLVMGetLinkage, LLVMValueRef, int) -_wrap_objenum2none(LLVMSetLinkage, LLVMValueRef, LLVMLinkage) -_wrap_obj2str(LLVMGetSection, LLVMValueRef) -_wrap_objstr2none(LLVMSetSection, LLVMValueRef) -_wrap_obj2obj(LLVMGetVisibility, LLVMValueRef, int) -_wrap_objenum2none(LLVMSetVisibility, LLVMValueRef, LLVMVisibility) -_wrap_obj2obj(LLVMGetAlignment, LLVMValueRef, int) -_wrap_objint2none(LLVMSetAlignment, LLVMValueRef) - -/*===-- Global Variables -------------------------------------------------===*/ - -_wrap_objobjstr2obj(LLVMAddGlobal, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjstrint2obj(LLVMAddGlobalInAddressSpace, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) -_wrap_objstr2obj(LLVMGetNamedGlobal, LLVMModuleRef, LLVMValueRef) -_wrap_obj2obj(LLVMGetFirstGlobal, LLVMModuleRef, LLVMValueRef) -_wrap_obj2obj(LLVMGetNextGlobal, LLVMValueRef, LLVMValueRef) -_wrap_obj2none(LLVMDeleteGlobal, LLVMValueRef) -_wrap_obj2obj(LLVMHasInitializer, LLVMValueRef, int) -_wrap_obj2obj(LLVMGetInitializer, LLVMValueRef, LLVMValueRef) -_wrap_objobj2none(LLVMSetInitializer, LLVMValueRef, LLVMValueRef) -_wrap_objint2none(LLVMSetGlobalConstant, LLVMValueRef) -_wrap_obj2obj(LLVMIsGlobalConstant, LLVMValueRef, int) -_wrap_objint2none(LLVMSetThreadLocal, LLVMValueRef) -_wrap_obj2obj(LLVMIsThreadLocal, LLVMValueRef, int) - - -/*===-- Functions --------------------------------------------------------===*/ - -_wrap_objstrobj2obj(LLVMAddFunction, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) -_wrap_objstr2obj(LLVMGetNamedFunction, LLVMModuleRef, LLVMValueRef) -_wrap_obj2obj(LLVMGetFirstFunction, LLVMModuleRef, LLVMValueRef) -_wrap_obj2obj(LLVMGetNextFunction, LLVMValueRef, LLVMValueRef) -_wrap_obj2none(LLVMDeleteFunction, LLVMValueRef) -_wrap_obj2obj(LLVMGetIntrinsicID, LLVMValueRef, int) -_wrap_obj2obj(LLVMGetFunctionCallConv, LLVMValueRef, int) -_wrap_objint2none(LLVMSetFunctionCallConv, LLVMValueRef) -_wrap_obj2str(LLVMGetGC, LLVMValueRef) -_wrap_objstr2none(LLVMSetGC, LLVMValueRef) -_wrap_obj2obj(LLVMGetDoesNotThrow, LLVMValueRef, int) -_wrap_objint2none(LLVMSetDoesNotThrow, LLVMValueRef) -_wrap_obj2none(LLVMViewFunctionCFG, LLVMValueRef) -_wrap_obj2none(LLVMViewFunctionCFGOnly, LLVMValueRef) -_wrap_objenum2none(LLVMAddFunctionAttr, LLVMValueRef, LLVMAttribute) -_wrap_objenum2none(LLVMRemoveFunctionAttr, LLVMValueRef, LLVMAttribute) - -static PyObject * -_wLLVMVerifyFunction(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const LLVMValueRef fn = get_object_arg(args); - if (!fn) return NULL; - - return pycap_new(LLVMVerifyFunction(fn, LLVMReturnStatusAction)); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMGetFunctionFromInlineAsm(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *pycapFuncType; - const char *inlineAsm = NULL; - const char *constrains = NULL; - int hasSideEffect; - int isAlignStack; - int asmDialect; - - if (!PyArg_ParseTuple(args, "Ossiii", &pycapFuncType, &inlineAsm, - &constrains, &hasSideEffect, - &isAlignStack, &asmDialect)) - return NULL; - - - LLVMTypeRef funcType = pycap_get(pycapFuncType); - LLVMValueRef inlineAsmRef; - inlineAsmRef = LLVMGetFunctionFromInlineAsm(funcType, inlineAsm, constrains, - hasSideEffect, isAlignStack, - asmDialect); - - return pycap_new(inlineAsmRef); - LLVMPY_CATCH_ALL -} - - -/*===-- Arguments --------------------------------------------------------===*/ - -_wrap_obj2obj(LLVMCountParams, LLVMValueRef, int) -_wrap_obj2obj(LLVMGetFirstParam, LLVMValueRef, LLVMValueRef) -_wrap_obj2obj(LLVMGetNextParam, LLVMValueRef, LLVMValueRef) -_wrap_obj2obj(LLVMGetParamParent, LLVMValueRef, LLVMValueRef) -_wrap_objenum2none(LLVMAddAttribute, LLVMValueRef, LLVMAttribute) -_wrap_objenum2none(LLVMRemoveAttribute, LLVMValueRef, LLVMAttribute) -_wrap_objenum2none(LLVMSetParamAlignment, LLVMValueRef, LLVMAttribute) -_wrap_obj2obj(LLVMGetParamAlignment, LLVMValueRef, int) - -/*===-- Basic Blocks -----------------------------------------------------===*/ - -_wrap_obj2obj(LLVMGetBasicBlockParent, LLVMBasicBlockRef, LLVMValueRef) -_wrap_obj2obj(LLVMCountBasicBlocks, LLVMValueRef, int) -_wrap_obj2obj(LLVMGetFirstBasicBlock, LLVMValueRef, LLVMBasicBlockRef) -_wrap_obj2obj(LLVMGetNextBasicBlock, LLVMBasicBlockRef, LLVMBasicBlockRef) -_wrap_obj2obj(LLVMGetEntryBasicBlock, LLVMValueRef, LLVMBasicBlockRef) -_wrap_objstr2obj(LLVMAppendBasicBlock, LLVMValueRef, LLVMBasicBlockRef) -_wrap_objstr2obj(LLVMInsertBasicBlock, LLVMBasicBlockRef, LLVMBasicBlockRef) -_wrap_obj2none(LLVMDeleteBasicBlock, LLVMBasicBlockRef) - - -/*===-- MetaData -----------------------------------------------------===*/ - -_wrap_objlist2obj(LLVMMetaDataGet, LLVMModuleRef, LLVMValueRef, LLVMValueRef) -_wrap_objstrobj2none(LLVMAddNamedMetadataOperand, LLVMModuleRef, LLVMValueRef) -_wrap_objint2obj(LLVMMetaDataGetOperand, LLVMValueRef, LLVMValueRef) -_wrap_obj2obj(LLVMMetaDataGetNumOperands, LLVMValueRef, int) -_wrap_objstr2obj(LLVMMetaDataStringGet, LLVMModuleRef, LLVMValueRef) - -static PyObject * -_wLLVMGetNamedMetadataOperands(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj_module; - const char *name; - - if (!PyArg_ParseTuple(args, "Os", &obj_module, &name)) - return NULL; - - LLVMModuleRef module = pycap_get(obj_module); - unsigned num_operands = LLVMGetNamedMetadataNumOperands(module, name); - LLVMValueRef *operands = new LLVMValueRef[num_operands]; - LLVMGetNamedMetadataOperands(module, name, operands); - - PyObject *list = make_list(operands, num_operands); - delete [] operands; - - return list; - LLVMPY_CATCH_ALL -} - - -/*===-- NamedMetaData -----------------------------------------------------===*/ - -_wrap_obj2str( LLVMNamedMetaDataGetName, LLVMNamedMDRef ) -_wrap_objobj2none( LLVMNamedMetaDataAddOperand, LLVMNamedMDRef, LLVMValueRef ) -_wrap_obj2none( LLVMEraseNamedMetaData, LLVMNamedMDRef ) -_wrap_dumper(LLVMDumpNamedMDToString, LLVMNamedMDRef) - -/*===-- Instructions -----------------------------------------------------===*/ - -_wrap_obj2obj(LLVMGetInstructionParent, LLVMValueRef, LLVMBasicBlockRef) -_wrap_obj2obj(LLVMGetFirstInstruction, LLVMBasicBlockRef, LLVMValueRef) -_wrap_obj2obj(LLVMGetNextInstruction, LLVMValueRef, LLVMValueRef) -_wrap_obj2obj(LLVMInstIsTerminator, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstIsBinaryOp, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstIsShift, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstIsCast, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstIsLogicalShift, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstIsArithmeticShift, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstIsAssociative, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstIsCommutative, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstIsVolatile, LLVMValueRef, int) -_wrap_objint2none(LLVMSetVolatile, LLVMValueRef) -_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int) -_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef) - -_wrap_objstrobj2none(LLVMInstSetMetaData, LLVMValueRef, LLVMValueRef) -_wrap_obj2none(LLVMInstructionEraseFromParent, LLVMValueRef) - -/*===-- Call Sites (Call or Invoke) --------------------------------------===*/ - -_wrap_objint2none(LLVMSetInstructionCallConv, LLVMValueRef) -_wrap_obj2obj(LLVMGetInstructionCallConv, LLVMValueRef, int) -_wrap_objintenum2none(LLVMAddInstrAttribute, LLVMValueRef, LLVMAttribute) -_wrap_objintenum2none(LLVMRemoveInstrAttribute, LLVMValueRef, LLVMAttribute) -_wrap_objintint2none(LLVMSetInstrParamAlignment, LLVMValueRef) -_wrap_obj2obj(LLVMIsTailCall, LLVMValueRef, int) -_wrap_objint2none(LLVMSetTailCall, LLVMValueRef) -_wrap_obj2obj(LLVMInstGetCalledFunction, LLVMValueRef, LLVMValueRef) -_wrap_objobj2none(LLVMInstSetCalledFunction, LLVMValueRef, LLVMValueRef) - -/*===-- PHI Nodes --------------------------------------------------------===*/ - -static void LLVMAddIncoming1(LLVMValueRef PhiNode, LLVMValueRef IncomingValue, LLVMBasicBlockRef IncomingBlock) -{ - LLVMAddIncoming(PhiNode, &IncomingValue, &IncomingBlock, 1); -} - -_wrap_objobjobj2none(LLVMAddIncoming1, LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef) -_wrap_obj2obj(LLVMCountIncoming, LLVMValueRef, int) -_wrap_objint2obj(LLVMGetIncomingValue, LLVMValueRef, LLVMValueRef) -_wrap_objint2obj(LLVMGetIncomingBlock, LLVMValueRef, LLVMBasicBlockRef) - -/*===-- Compare Instructions ---------------------------------------------===*/ - -_wrap_obj2obj(LLVMCmpInstGetPredicate, LLVMValueRef, int) - -/*===-- Instruction builders ----------------------------------------------===*/ - -_wrap_none2obj(LLVMCreateBuilder, LLVMBuilderRef) -_wrap_objobj2none(LLVMPositionBuilderBefore, LLVMBuilderRef, LLVMValueRef) -_wrap_objobj2none(LLVMPositionBuilderAtEnd, LLVMBuilderRef, LLVMBasicBlockRef) -_wrap_obj2obj(LLVMGetInsertBlock, LLVMBuilderRef, LLVMBasicBlockRef) -_wrap_obj2none(LLVMDisposeBuilder, LLVMBuilderRef) - -/* Terminators */ - -_wrap_obj2obj(LLVMBuildRetVoid, LLVMBuilderRef, LLVMValueRef) -_wrap_objobj2obj(LLVMBuildRet, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) -_wrap_objlist2obj(LLVMBuildRetMultiple, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMBuildBr, LLVMBuilderRef, LLVMBasicBlockRef, LLVMValueRef) -_wrap_objobjobjobj2obj(LLVMBuildCondBr, LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMBasicBlockRef, LLVMValueRef) -_wrap_objobjobjint2obj(LLVMBuildSwitch, LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMValueRef) - -static PyObject * -_wLLVMBuildInvoke(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj1, *obj2, *obj3, *obj4, *obj5; - const char *name; - - if (!PyArg_ParseTuple(args, "OOOOOs:LLVMBuildInvoke", &obj1, &obj2, &obj3, &obj4, &obj5, &name)) { - return NULL; - } - - const LLVMBuilderRef builder = pycap_get( obj1); - const LLVMValueRef func = pycap_get( obj2 ) ; - - size_t fnarg_count = PyList_Size(obj3); - LLVMValueRef *fnargs - = make_array_from_list(obj3, fnarg_count); - - const LLVMBasicBlockRef then_blk = pycap_get ( obj4 ) ; - const LLVMBasicBlockRef catch_blk = pycap_get ( obj5 ) ; - - const LLVMValueRef inst - = LLVMBuildInvoke(builder, func, fnargs, fnarg_count, then_blk, - catch_blk, name); - - delete [] fnargs; - - return pycap_new(inst); - LLVMPY_CATCH_ALL -} - -_wrap_obj2obj(LLVMBuildUnreachable, LLVMBuilderRef, LLVMValueRef) - -/* Add a case to the switch instruction */ - -_wrap_objobjobj2none(LLVMAddCase, LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef) - -/* Arithmetic */ - -_wrap_objobjobjstr2obj(LLVMBuildAdd, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFAdd, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildSub, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFSub, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildMul, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFMul, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildUDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildSDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildURem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildSRem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFRem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildShl, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildLShr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildAShr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildAnd, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildOr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildXor, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjstr2obj(LLVMBuildNeg, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjstr2obj(LLVMBuildNot, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) - -/* Memory */ - -_wrap_objobjstr2obj(LLVMBuildMalloc, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildArrayMalloc, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjstr2obj(LLVMBuildAlloca, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildArrayAlloca, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, LLVMValueRef) -_wrap_objobj2obj(LLVMBuildFree, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjstr2obj(LLVMBuildLoad, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobj2obj(LLVMBuildStore, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjliststr2obj(LLVMBuildGEP, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjliststr2obj(LLVMBuildInBoundsGEP, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) - - - -_wrap_objint2none(LLVMLdSetAlignment, LLVMValueRef) -_wrap_objint2none(LLVMStSetAlignment, LLVMValueRef) - -/* Casts */ - -_wrap_objobjobjstr2obj(LLVMBuildTrunc, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildZExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildSExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFPToUI, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFPToSI, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildUIToFP, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildSIToFP, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFPTrunc, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildFPExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildPtrToInt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildIntToPtr, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildBitCast, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) - -/* Comparisons */ - -_wrap_objenumobjobjstr2obj(LLVMBuildICmp, LLVMBuilderRef, LLVMIntPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objenumobjobjstr2obj(LLVMBuildFCmp, LLVMBuilderRef, LLVMRealPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef) - - -/* Atomics */ -_wrap_objobjobjobjstrint2obj(LLVMBuildAtomicCmpXchg, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objstrobjobjstrint2obj(LLVMBuildAtomicRMW, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjintstrint2obj(LLVMBuildAtomicLoad, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjintstrint2obj(LLVMBuildAtomicStore, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objstrint2obj(LLVMBuildFence, LLVMBuilderRef, LLVMValueRef) - -/* Miscellaneous instructions */ - -_wrap_objobjintstr2obj(LLVMBuildGetResult, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjintstr2obj(LLVMBuildInsertValue, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjstr2obj(LLVMBuildPhi, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjliststr2obj(LLVMBuildCall, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjobjstr2obj(LLVMBuildSelect, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildVAArg, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) -_wrap_objobjobjstr2obj(LLVMBuildExtractElement, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjobjstr2obj(LLVMBuildInsertElement, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) -_wrap_objobjobjobjstr2obj(LLVMBuildShuffleVector, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) - - -/*===----------------------------------------------------------------------===*/ -/* Memory Buffer */ -/*===----------------------------------------------------------------------===*/ - -static PyObject * -_wLLVMCreateMemoryBufferWithContentsOfFile(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const char *path; - LLVMMemoryBufferRef ref; - PyObject *ret; - - if (!PyArg_ParseTuple(args, "s:LLVMCreateMemoryBufferWithContentsOfFile", &path)) { - return NULL; - } - - char *outmsg; - if (!LLVMCreateMemoryBufferWithContentsOfFile(path, &ref, &outmsg)) { - ret = pycap_new(ref); - } else { - ret = PyUnicode_FromString(outmsg); - LLVMDisposeMessage(outmsg); - } - - return ret; - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMCreateMemoryBufferWithSTDIN(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *ret; - LLVMMemoryBufferRef ref; - char *outmsg; - if (!LLVMCreateMemoryBufferWithSTDIN(&ref, &outmsg)) { - ret = pycap_new(ref); - } else { - ret = PyUnicode_FromString(outmsg); - LLVMDisposeMessage(outmsg); - } - - return ret; - LLVMPY_CATCH_ALL -} - -_wrap_obj2none(LLVMDisposeMemoryBuffer, LLVMMemoryBufferRef) - - -/*===----------------------------------------------------------------------===*/ -/* Pass Manager Builder */ -/*===----------------------------------------------------------------------===*/ - -_wrap_none2obj(LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderRef) -_wrap_obj2none(LLVMPassManagerBuilderDispose, LLVMPassManagerBuilderRef) - -_wrap_objint2none(LLVMPassManagerBuilderSetOptLevel, LLVMPassManagerBuilderRef) -_wrap_obj2obj(LLVMPassManagerBuilderGetOptLevel, LLVMPassManagerBuilderRef, int) - -_wrap_objint2none(LLVMPassManagerBuilderSetSizeLevel, LLVMPassManagerBuilderRef) -_wrap_obj2obj(LLVMPassManagerBuilderGetSizeLevel, LLVMPassManagerBuilderRef, int) - -_wrap_objint2none(LLVMPassManagerBuilderSetVectorize, LLVMPassManagerBuilderRef) -_wrap_obj2obj(LLVMPassManagerBuilderGetVectorize, LLVMPassManagerBuilderRef, int) - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 -_wrap_objint2none(LLVMPassManagerBuilderSetLoopVectorize, LLVMPassManagerBuilderRef) -_wrap_obj2obj(LLVMPassManagerBuilderGetLoopVectorize, LLVMPassManagerBuilderRef, int) -#endif //llvm-3.2 - -_wrap_objint2none(LLVMPassManagerBuilderSetDisableUnitAtATime, - LLVMPassManagerBuilderRef) -_wrap_obj2obj(LLVMPassManagerBuilderGetDisableUnitAtATime, - LLVMPassManagerBuilderRef, int) - -_wrap_objint2none(LLVMPassManagerBuilderSetDisableUnrollLoops, - LLVMPassManagerBuilderRef) -_wrap_obj2obj(LLVMPassManagerBuilderGetDisableUnrollLoops, - LLVMPassManagerBuilderRef, int) - -_wrap_objint2none(LLVMPassManagerBuilderSetDisableSimplifyLibCalls, - LLVMPassManagerBuilderRef) -_wrap_obj2obj(LLVMPassManagerBuilderGetDisableSimplifyLibCalls, - LLVMPassManagerBuilderRef, int) - -_wrap_objint2none(LLVMPassManagerBuilderUseInlinerWithThreshold, - LLVMPassManagerBuilderRef) - - -_wrap_objobj2none(LLVMPassManagerBuilderPopulateFunctionPassManager, - LLVMPassManagerBuilderRef, - LLVMPassManagerRef) - -_wrap_objobj2none(LLVMPassManagerBuilderPopulateModulePassManager, - LLVMPassManagerBuilderRef, - LLVMPassManagerRef) - - -/*===----------------------------------------------------------------------===*/ -/* Pass Manager */ -/*===----------------------------------------------------------------------===*/ - -_wrap_none2obj(LLVMCreatePassManager, LLVMPassManagerRef) -_wrap_obj2obj(LLVMCreateFunctionPassManagerForModule, LLVMModuleRef, LLVMPassManagerRef) -_wrap_objobj2obj(LLVMRunPassManager, LLVMPassManagerRef, LLVMModuleRef, int) -_wrap_obj2obj(LLVMInitializeFunctionPassManager, LLVMPassManagerRef, int) -_wrap_objobj2obj(LLVMRunFunctionPassManager, LLVMPassManagerRef, LLVMValueRef, int) -_wrap_obj2obj(LLVMFinalizeFunctionPassManager, LLVMPassManagerRef, int) -_wrap_obj2none(LLVMDisposePassManager, LLVMPassManagerRef) -_wrap_none2str(LLVMDumpPasses) -_wrap_objstr2obj(LLVMAddPassByName, LLVMPassManagerRef, int) - - -_wrap_objobj2none(LLVMAddPass, LLVMPassManagerRef, LLVMPassRef) -_wrap_none2none(LLVMInitializePasses) - -_wrap_none2obj(LLVMInitializeNativeTarget, int) -_wrap_none2obj(LLVMInitializeNativeTargetAsmPrinter, int) -#if !defined(LLVM_DISABLE_PTX) -# if LLVM_HAS_NVPTX -_wrap_none2none(LLVMInitializeNVPTXTarget) -_wrap_none2none(LLVMInitializeNVPTXTargetInfo) -_wrap_none2none( LLVMInitializeNVPTXTargetMC ) -_wrap_none2none(LLVMInitializeNVPTXAsmPrinter) -# else -_wrap_none2none(LLVMInitializePTXTarget) -_wrap_none2none(LLVMInitializePTXTargetInfo) -_wrap_none2none( LLVMInitializePTXTargetMC ) -_wrap_none2none(LLVMInitializePTXAsmPrinter) -# endif -#endif - -/*===----------------------------------------------------------------------===*/ -/* Passes */ -/*===----------------------------------------------------------------------===*/ - -_wrap_str2obj(LLVMCreatePassByName, LLVMPassRef) -_wrap_obj2none(LLVMDisposePass, LLVMPassRef) -_wrap_obj2str(LLVMGetPassName, LLVMPassRef) -_wrap_obj2none(LLVMPassDump, LLVMPassRef) - -_wrap_str2obj(LLVMCreateTargetLibraryInfo, LLVMPassRef) - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 -_wrap_obj2obj(LLVMCreateTargetTransformInfo, LLVMTargetMachineRef, LLVMPassRef) -#endif - - -/*===----------------------------------------------------------------------===*/ -/* Target Machine */ -/*===----------------------------------------------------------------------===*/ - -_wrap_none2str(LLVMGetHostCPUName); - -_wrap_obj2obj(LLVMTargetMachineFromEngineBuilder, LLVMEngineBuilderRef, - LLVMTargetMachineRef) -_wrap_obj2none(LLVMDisposeTargetMachine, LLVMTargetMachineRef) - -static PyObject * -_wLLVMTargetMachineLookup(PyObject * self, PyObject * args) -{ - LLVMPY_TRY - const char *triple; - const char *cpu; - const char *features; - int opt, codemodel; - - if (!PyArg_ParseTuple(args, "sssii", &triple, &cpu, &features, - &opt, &codemodel)) - return NULL; - - std::string error; - LLVMTargetMachineRef tm = LLVMTargetMachineLookup(triple, cpu, features, - opt, codemodel, error); - if(!error.empty()){ - PyErr_SetString(PyExc_RuntimeError, error.c_str()); - return NULL; - } - return pycap_new(tm); - LLVMPY_CATCH_ALL -} - - -static PyObject * -_wLLVMCreateTargetMachine(PyObject * self, PyObject * args) -{ - LLVMPY_TRY - const char *triple; - const char *cpu; - const char *features; - int opt, codemodel; - - if (!PyArg_ParseTuple(args, "sssii", &triple, &cpu, &features, - &opt, &codemodel)) - return NULL; - - std::string error; - LLVMTargetMachineRef tm = LLVMCreateTargetMachine(triple, cpu, features, - opt, codemodel, error); - if(!error.empty()){ - PyErr_SetString(PyExc_RuntimeError, error.c_str()); - return NULL; - } - return pycap_new(tm); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMTargetMachineEmitFile(PyObject * self, PyObject * args) -{ - LLVMPY_TRY - PyObject *arg_tm, *arg_m; - int arg_use_asm; - - if (!PyArg_ParseTuple(args, "OOi", &arg_tm, &arg_m, &arg_use_asm)) - return NULL; - - const LLVMTargetMachineRef tm - = pycap_get( arg_tm ) ; - const LLVMModuleRef m = pycap_get( arg_m ) ; - - std::string error; - size_t len; - unsigned const char * ubytes - = LLVMTargetMachineEmitFile(tm, m, arg_use_asm, &len, error); - if ( !error.empty() ){ - PyErr_SetString(PyExc_RuntimeError, error.c_str()); - return NULL; - } - - const char *chars = reinterpret_cast(ubytes) ; - PyObject * ret = PyBytes_FromStringAndSize(chars, len); - delete [] ubytes; - return ret; - LLVMPY_CATCH_ALL -} - -_wrap_obj2obj(LLVMTargetMachineGetTargetData, LLVMTargetMachineRef, - LLVMTargetDataRef) -_wrap_obj2str(LLVMTargetMachineGetTargetName, LLVMTargetMachineRef) -_wrap_obj2str(LLVMTargetMachineGetTargetShortDescription, LLVMTargetMachineRef) -_wrap_obj2str(LLVMTargetMachineGetTriple, LLVMTargetMachineRef) -_wrap_obj2str(LLVMTargetMachineGetCPU, LLVMTargetMachineRef) -_wrap_obj2str(LLVMTargetMachineGetFS, LLVMTargetMachineRef) -_wrap_none2none(LLVMPrintRegisteredTargetsForVersion) - - -/*===----------------------------------------------------------------------===*/ -/* Target Data */ -/*===----------------------------------------------------------------------===*/ - -_wrap_str2obj(LLVMCreateTargetData, LLVMTargetDataRef) -_wrap_obj2none(LLVMDisposeTargetData, LLVMTargetDataRef) - -static PyObject * -_wLLVMTargetDataAsString(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const LLVMTargetDataRef td = get_object_arg(args); - - char *tdrep = LLVMCopyStringRepOfTargetData(td); - PyObject *ret = PyUnicode_FromString(tdrep); - LLVMDisposeMessage(tdrep); - return ret; - LLVMPY_CATCH_ALL -} - -_wrap_objobj2none(LLVMAddTargetData, LLVMTargetDataRef, LLVMPassManagerRef) -_wrap_obj2obj(LLVMByteOrder, LLVMTargetDataRef, int) -_wrap_obj2obj(LLVMPointerSize, LLVMTargetDataRef, int) -_wrap_obj2obj(LLVMIntPtrType, LLVMTargetDataRef, LLVMTypeRef) -_wrap_objobj2obj(LLVMSizeOfTypeInBits, LLVMTargetDataRef, LLVMTypeRef, - llvmwrap_ull) -_wrap_objobj2obj(LLVMStoreSizeOfType, LLVMTargetDataRef, LLVMTypeRef, - llvmwrap_ull) -_wrap_objobj2obj(LLVMABISizeOfType, LLVMTargetDataRef, LLVMTypeRef, - llvmwrap_ull) -_wrap_objobj2obj(LLVMABIAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, - int) -_wrap_objobj2obj(LLVMCallFrameAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, - int) -_wrap_objobj2obj(LLVMPreferredAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, - int) -_wrap_objobj2obj(LLVMPreferredAlignmentOfGlobal, LLVMTargetDataRef, - LLVMValueRef, int) -_wrap_objobjull2obj(LLVMElementAtOffset, LLVMTargetDataRef, LLVMTypeRef, int) -_wrap_objobjint2obj(LLVMOffsetOfElement, LLVMTargetDataRef, LLVMTypeRef, - llvmwrap_ull) - - -/*===----------------------------------------------------------------------===*/ -/* Engine Builder */ -/*===----------------------------------------------------------------------===*/ - -_wrap_obj2obj(LLVMCreateEngineBuilder, LLVMModuleRef, LLVMEngineBuilderRef) -_wrap_obj2none(LLVMDisposeEngineBuilder, LLVMEngineBuilderRef) -_wrap_obj2none(LLVMEngineBuilderForceJIT, LLVMEngineBuilderRef) -_wrap_obj2none(LLVMEngineBuilderForceInterpreter, LLVMEngineBuilderRef) -_wrap_objint2none(LLVMEngineBuilderSetOptLevel, LLVMEngineBuilderRef) -_wrap_objstr2none(LLVMEngineBuilderSetMCPU, LLVMEngineBuilderRef) -_wrap_objstr2none(LLVMEngineBuilderSetMAttrs, LLVMEngineBuilderRef) - -static PyObject * -_wLLVMEngineBuilderCreate(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const LLVMEngineBuilderRef obj - = get_object_arg(args) ; - - std::string outmsg; - const LLVMExecutionEngineRef ee = LLVMEngineBuilderCreate(obj, outmsg); - - PyObject * ret; - if( !ee ){ // check if error message is set. - ret = PyUnicode_FromString(outmsg.c_str()); - }else{ - ret = pycap_new(ee); - } - - return ret; - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMEngineBuilderCreateTM(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj, *tm; - if (!PyArg_ParseTuple(args, "OO", &obj, &tm)) - return NULL; - - const LLVMEngineBuilderRef objref = pycap_get( obj ); - const LLVMTargetMachineRef tmref = pycap_get( tm ); - std::string outmsg; - - const LLVMExecutionEngineRef ee = LLVMEngineBuilderCreateTM(objref, tmref, - outmsg); - - PyObject * ret; - if( !ee ){ // check if error message is set. - ret = PyUnicode_FromString(outmsg.c_str()); - }else{ - ret = pycap_new(ee); - } - - return ret; - LLVMPY_CATCH_ALL -} - -/*===----------------------------------------------------------------------===*/ -/* Execution Engine */ -/*===----------------------------------------------------------------------===*/ - -// Use EngineBuilder -//static PyObject * -//_wLLVMCreateExecutionEngine(PyObject *self, PyObject *args) -//{ -// LLVMPY_TRY -// PyObject *obj; -// int force_interpreter; -// char *outmsg = 0; -// int error; -// -// if (!PyArg_ParseTuple(args, "Oi", &obj, &force_interpreter)) -// return NULL; -// -// const LLVMModuleRef mod = pycap_get( obj ) ; -// -// LLVMExecutionEngineRef ee; -// if (force_interpreter) -// error = LLVMCreateInterpreterForModule(&ee, mod, &outmsg); -// else -// error = LLVMCreateJITCompilerForModule(&ee, mod, 1 /*fast*/, &outmsg); -// -// PyObject *ret; -// if (error) { -// ret = PyUnicode_FromString(outmsg); -// LLVMDisposeMessage(outmsg); -// } else { -// ret = pycap_new(ee); -// } -// -// return ret; -// LLVMPY_CATCH_ALL -//} - -static PyObject * -_wLLVMGetPointerToFunction(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj_ee; - PyObject *obj_fn; - - if (!PyArg_ParseTuple(args, "OO", &obj_ee, &obj_fn)) - return NULL; - - const LLVMExecutionEngineRef ee = pycap_get(obj_ee ) ; - const LLVMValueRef fn = pycap_get( obj_fn ) ; - - return PyLong_FromVoidPtr(LLVMGetPointerToFunction(ee,fn)); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMGetPointerToGlobal(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj_ee; - PyObject *obj_val; - - if (!PyArg_ParseTuple(args, "OO", &obj_ee, &obj_val)) - return NULL; - - const LLVMExecutionEngineRef ee = pycap_get( obj_ee ) ; - const LLVMValueRef val = pycap_get( obj_val ) ; - - return PyLong_FromVoidPtr(LLVMGetPointerToGlobal(ee, val)); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMAddGlobalMapping(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj_ee; - PyObject *obj_val; - PyObject *obj_long; - void* address; - - if (!PyArg_ParseTuple(args, "OOO", &obj_ee, &obj_val, &obj_long)) - return NULL; - - address = PyLong_AsVoidPtr(obj_long); - if (PyErr_Occurred()) return NULL; - - const LLVMExecutionEngineRef ee = pycap_get( obj_ee ); - const LLVMValueRef val = pycap_get( obj_val ); - - LLVMAddGlobalMapping(ee, val, address); - - Py_RETURN_NONE; - - LLVMPY_CATCH_ALL -} - -/* the args should have been ptr, num */ -LLVMGenericValueRef LLVMRunFunction2(LLVMExecutionEngineRef EE, - LLVMValueRef F, LLVMGenericValueRef *Args, unsigned NumArgs) -{ - return LLVMRunFunction(EE, F, NumArgs, Args); -} - -static PyObject * -_wLLVMRemoveModule2(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj_ee; - PyObject *obj_mod; - if (!PyArg_ParseTuple(args, "OO", &obj_ee, &obj_mod)) - return NULL; - - const LLVMExecutionEngineRef ee = pycap_get( obj_ee ) ; - const LLVMModuleRef mod = pycap_get(obj_mod) ; - - char *outmsg = 0; - LLVMModuleRef mod_new = 0; - LLVMRemoveModule(ee, mod, &mod_new, &outmsg); - PyObject *ret; - if (mod_new) { - ret = pycap_new(mod_new); - } else { - if (outmsg) { - ret = PyUnicode_FromString(outmsg); - LLVMDisposeMessage(outmsg); - } else { - ret = PyUnicode_FromString("error"); - } - } - - return ret; - LLVMPY_CATCH_ALL -} - -_wrap_obj2none(LLVMDisposeExecutionEngine, LLVMExecutionEngineRef) -_wrap_objint2none(LLVMExecutionEngineDisableLazyCompilation, - LLVMExecutionEngineRef) -_wrap_objobjlist2obj(LLVMRunFunction2, LLVMExecutionEngineRef, - LLVMValueRef, LLVMGenericValueRef, LLVMGenericValueRef) -_wrap_obj2obj(LLVMGetExecutionEngineTargetData, LLVMExecutionEngineRef, - LLVMTargetDataRef) -_wrap_obj2none(LLVMRunStaticConstructors, LLVMExecutionEngineRef) -_wrap_obj2none(LLVMRunStaticDestructors, LLVMExecutionEngineRef) -_wrap_objobj2none(LLVMFreeMachineCodeForFunction, LLVMExecutionEngineRef, - LLVMValueRef) -_wrap_objobj2none(LLVMAddModule, LLVMExecutionEngineRef, - LLVMModuleRef) - - -/*===----------------------------------------------------------------------===*/ -/* Generic Value */ -/*===----------------------------------------------------------------------===*/ - -static PyObject * -_wLLVMCreateGenericValueOfInt(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj1; - unsigned PY_LONG_LONG n; - int is_signed; - LLVMGenericValueRef gv; - - if (!PyArg_ParseTuple(args, "OKi", &obj1, &n, &is_signed)) - return NULL; - - const LLVMTypeRef ty = pycap_get( obj1 ) ; - - gv = LLVMCreateGenericValueOfInt(ty, n, is_signed); - return pycap_new(gv); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMCreateGenericValueOfFloat(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj1; - double d; - LLVMGenericValueRef gv; - - if (!PyArg_ParseTuple(args, "Od", &obj1, &d)) - return NULL; - - const LLVMTypeRef ty = pycap_get( obj1 ) ; - - gv = LLVMCreateGenericValueOfFloat(ty, d); - return pycap_new(gv); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMCreateGenericValueOfPointer(PyObject *self, PyObject *args) -{ - LLVMPY_TRY -// PyObject *obj1; -// LLVMTypeRef ty; //unused? - unsigned PY_LONG_LONG n_; - size_t n; - - if (!PyArg_ParseTuple(args, "K", &n_)) - return NULL; - - n=n_; - - const LLVMGenericValueRef gv = LLVMCreateGenericValueOfPointer((void*)n); - return pycap_new(gv); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMGenericValueToInt(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj1; - int is_signed; - unsigned PY_LONG_LONG val; - - if (!PyArg_ParseTuple(args, "Oi", &obj1, &is_signed)) - return NULL; - - LLVMGenericValueRef gv = pycap_get(obj1); - - val = LLVMGenericValueToInt(gv, is_signed); - return is_signed ? - PyLong_FromLongLong((PY_LONG_LONG)val) : - PyLong_FromUnsignedLongLong(val); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMGenericValueToFloat(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj1, *obj2; - - if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) - return NULL; - - const LLVMTypeRef ty = pycap_get( obj1 ) ; - const LLVMGenericValueRef gv = pycap_get( obj2 ) ; - - double val = LLVMGenericValueToFloat(ty, gv); - return PyFloat_FromDouble(val); - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMGenericValueToPointer(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - PyObject *obj1; - - if (!PyArg_ParseTuple(args, "O", &obj1)) - return NULL; - - const LLVMGenericValueRef gv = pycap_get( obj1 ) ; - - void * val = LLVMGenericValueToPointer(gv); - return PyLong_FromVoidPtr(val); - LLVMPY_CATCH_ALL -} - -_wrap_obj2none(LLVMDisposeGenericValue, LLVMGenericValueRef) - - -/*===----------------------------------------------------------------------===*/ -/* Misc */ -/*===----------------------------------------------------------------------===*/ - -static PyObject * -_wLLVMGetVersion(PyObject *self, PyObject *args) -{ - int major = LLVM_VERSION_MAJOR; - int minor = LLVM_VERSION_MINOR; - return Py_BuildValue("(i,i)", major, minor); -} - -_wrap_objintlist2obj(LLVMGetIntrinsic, LLVMModuleRef, LLVMTypeRef, - LLVMValueRef) - -static PyObject * -_wLLVMLoadLibraryPermanently(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const char *filename; - PyObject *ret; - - if (!PyArg_ParseTuple(args, "s:LLVMLoadLibraryPermanently", &filename)) { - return NULL; - } - - char *outmsg = 0; - if (!LLVMLoadLibraryPermanently(filename, &outmsg)) { - if (outmsg) { - ret = PyUnicode_FromString(outmsg); - LLVMDisposeMessage(outmsg); - return ret; - } - } - - /* note: success => None, failure => string with error message */ - Py_RETURN_NONE; - LLVMPY_CATCH_ALL -} - -static PyObject * -_wLLVMParseEnvOpts(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - const char * progname; - const char * envname; - if(!PyArg_ParseTuple(args, "ss", &progname, &envname)) { - return NULL; - } - - llvm::cl::ParseEnvironmentOptions(progname, envname); - - Py_RETURN_NONE; - LLVMPY_CATCH_ALL -} - -_wrap_obj2obj(LLVMInlineFunction, LLVMValueRef, int) - -_wrap_none2str(LLVMDefaultTargetTriple) - - -/* Expose the void* inside a PyCObject as a PyLong. This allows us to - * use it as a unique ID. */ -static PyObject * -_wPyCObjectVoidPtrToPyLong(PyObject *self, PyObject *args) -{ - LLVMPY_TRY - void *p = get_object_arg(args); - return PyLong_FromVoidPtr(p); - LLVMPY_CATCH_ALL -} - - -/*===----------------------------------------------------------------------===*/ -/* Python member method table */ -/*===----------------------------------------------------------------------===*/ - -#define _method( func ) { # func , ( PyCFunction )_w ## func , METH_VARARGS , NULL }, -#define _pass( P ) _method( LLVMAdd ## P ## Pass ) - -static PyMethodDef core_methods[] = { - - /* Modules */ - _method( LLVMModuleCreateWithName ) - _method( LLVMGetDataLayout ) - _method( LLVMSetDataLayout ) - _method( LLVMGetModuleIdentifier ) - _method( LLVMSetModuleIdentifier ) - _method( LLVMGetTarget ) - _method( LLVMSetTarget ) - _method( LLVMModuleAddLibrary ) - _method( LLVMGetTypeByName ) - _method( LLVMDumpModule ) - _method( LLVMDisposeModule ) - _method( LLVMDumpModuleToString ) - _method( LLVMVerifyModule ) - _method( LLVMGetModuleFromAssembly ) - _method( LLVMGetModuleFromBitcode ) - _method( LLVMGetBitcodeFromModule ) - _method( LLVMGetNativeCodeFromModule ) - _method( LLVMModuleGetPointerSize ) - _method( LLVMModuleGetOrInsertFunction ) - _method( LLVMLinkModules ) - _method( LLVMModuleGetOrInsertNamedMetaData ) - _method( LLVMModuleGetNamedMetaData ) - _method( LLVMCloneModule ) - - /* Types */ - - /* General */ - _method( LLVMGetTypeKind ) - _method( LLVMDumpTypeToString ) - - /* Integer types */ - _method( LLVMInt1Type ) - _method( LLVMInt8Type ) - _method( LLVMInt16Type ) - _method( LLVMInt32Type ) - _method( LLVMInt64Type ) - _method( LLVMIntType ) - _method( LLVMGetIntTypeWidth ) - - /* Floating-point types */ - _method( LLVMFloatType ) - _method( LLVMDoubleType ) - _method( LLVMX86FP80Type ) - _method( LLVMFP128Type ) - _method( LLVMPPCFP128Type ) - - /* Function types */ - _method( LLVMFunctionType ) - _method( LLVMIsFunctionVarArg ) - _method( LLVMGetReturnType ) - _method( LLVMCountParamTypes ) - _method( LLVMGetFunctionTypeParams ) - - /* Struct types */ - _method( LLVMStructType ) - _method( LLVMStructTypeIdentified ) - _method( LLVMSetStructBody ) - _method( LLVMCountStructElementTypes ) - _method( LLVMGetStructElementTypes ) - _method( LLVMIsPackedStruct ) - _method( LLVMIsOpaqueStruct ) - _method( LLVMIsLiteralStruct ) - _method( LLVMGetStructName ) - _method( LLVMSetStructName ) - - /* Array types */ - _method( LLVMArrayType ) - _method( LLVMGetElementType ) - _method( LLVMGetArrayLength ) - - /* Pointer types */ - _method( LLVMPointerType ) - _method( LLVMGetPointerAddressSpace ) - - /* Vector type */ - _method( LLVMVectorType ) - _method( LLVMGetVectorSize ) - - /* Other types */ - _method( LLVMVoidType ) - _method( LLVMLabelType ) - - /* Type handles */ - /* - _method( LLVMResolveTypeHandle ) - _method( LLVMDisposeTypeHandle ) - */ - - /* Values */ - - /* Operations on all values */ - _method( LLVMTypeOf ) - _method( LLVMGetValueName ) - _method( LLVMSetValueName ) - _method( LLVMDumpValue ) - _method( LLVMDumpValueToString ) - _method( LLVMValueGetID ) - _method( LLVMValueGetNumUses ) - _method( LLVMValueGetUses ) - - /* Users */ - - _method( LLVMUserGetNumOperands ) - _method( LLVMUserGetOperand ) - - /* Constant Values */ - - /* Operations on constants of any type */ - _method( LLVMConstNull ) - _method( LLVMConstAllOnes ) - _method( LLVMGetUndef ) - _method( LLVMIsConstant ) - _method( LLVMIsNull ) - _method( LLVMIsUndef ) - - /* Operations on scalar constants */ - _method( LLVMConstInt ) - _method( LLVMConstReal ) - _method( LLVMConstRealOfString ) - _method( LLVMConstIntGetZExtValue ) - _method( LLVMConstIntGetSExtValue ) - - /* Operations on composite constants */ - _method( LLVMConstString ) - _method( LLVMConstArray ) - _method( LLVMConstStruct ) - _method( LLVMConstVector ) - - /* Constant expressions */ - _method( LLVMGetConstExprOpcode ) - _method( LLVMGetConstExprOpcodeName ) - _method( LLVMSizeOf ) - _method( LLVMConstNeg ) - _method( LLVMConstNot ) - _method( LLVMConstAdd ) - _method( LLVMConstFAdd ) - _method( LLVMConstSub ) - _method( LLVMConstFSub ) - _method( LLVMConstMul ) - _method( LLVMConstFMul ) - _method( LLVMConstUDiv ) - _method( LLVMConstSDiv ) - _method( LLVMConstFDiv ) - _method( LLVMConstURem ) - _method( LLVMConstSRem ) - _method( LLVMConstFRem ) - _method( LLVMConstAnd ) - _method( LLVMConstOr ) - _method( LLVMConstXor ) - _method( LLVMConstICmp ) - _method( LLVMConstFCmp ) - _method( LLVMConstShl ) - _method( LLVMConstLShr ) - _method( LLVMConstAShr ) - _method( LLVMConstGEP ) - _method( LLVMConstTrunc ) - _method( LLVMConstSExt ) - _method( LLVMConstZExt ) - _method( LLVMConstFPTrunc ) - _method( LLVMConstFPExt ) - _method( LLVMConstUIToFP ) - _method( LLVMConstSIToFP ) - _method( LLVMConstFPToUI ) - _method( LLVMConstFPToSI ) - _method( LLVMConstPtrToInt ) - _method( LLVMConstIntToPtr ) - _method( LLVMConstBitCast ) - _method( LLVMConstSelect ) - _method( LLVMConstExtractElement ) - _method( LLVMConstInsertElement ) - _method( LLVMConstShuffleVector ) - - /* Globals */ - - /* Globals (general) */ - _method( LLVMGetGlobalParent ) - _method( LLVMIsDeclaration ) - _method( LLVMGetLinkage ) - _method( LLVMSetLinkage ) - _method( LLVMGetSection ) - _method( LLVMSetSection ) - _method( LLVMGetVisibility ) - _method( LLVMSetVisibility ) - _method( LLVMGetAlignment ) - _method( LLVMSetAlignment ) - - /* Global Variables */ - _method( LLVMAddGlobal ) - _method( LLVMAddGlobalInAddressSpace ) - _method( LLVMGetNamedGlobal ) - _method( LLVMGetFirstGlobal ) - _method( LLVMGetNextGlobal ) - _method( LLVMDeleteGlobal ) - _method( LLVMHasInitializer ) - _method( LLVMGetInitializer ) - _method( LLVMSetInitializer ) - _method( LLVMSetThreadLocal ) - _method( LLVMIsThreadLocal ) - _method( LLVMSetGlobalConstant ) - _method( LLVMIsGlobalConstant ) - - /* Functions */ - _method( LLVMAddFunction ) - _method( LLVMGetNamedFunction ) - _method( LLVMGetFirstFunction ) - _method( LLVMGetNextFunction ) - _method( LLVMDeleteFunction ) - _method( LLVMGetIntrinsicID ) - _method( LLVMGetFunctionCallConv ) - _method( LLVMSetFunctionCallConv ) - _method( LLVMGetGC ) - _method( LLVMSetGC ) - _method( LLVMGetDoesNotThrow ) - _method( LLVMSetDoesNotThrow ) - _method( LLVMVerifyFunction ) - _method( LLVMViewFunctionCFG ) - _method( LLVMViewFunctionCFGOnly ) - _method( LLVMAddFunctionAttr ) - _method( LLVMRemoveFunctionAttr ) - _method( LLVMGetFunctionFromInlineAsm ) - - /* Arguments */ - _method( LLVMCountParams ) - _method( LLVMGetFirstParam ) - _method( LLVMGetNextParam ) - _method( LLVMGetParamParent ) - _method( LLVMAddAttribute ) - _method( LLVMRemoveAttribute ) - _method( LLVMSetParamAlignment ) - _method( LLVMGetParamAlignment ) - - /* Basic Blocks */ - _method( LLVMGetBasicBlockParent ) - _method( LLVMCountBasicBlocks ) - _method( LLVMGetFirstBasicBlock ) - _method( LLVMGetNextBasicBlock ) - _method( LLVMGetEntryBasicBlock ) - _method( LLVMAppendBasicBlock ) - _method( LLVMInsertBasicBlock ) - _method( LLVMDeleteBasicBlock ) - - /* MetaData */ - _method( LLVMMetaDataGet ) - _method( LLVMGetNamedMetadataOperands ) - _method( LLVMAddNamedMetadataOperand ) - _method( LLVMMetaDataGetOperand ) - _method( LLVMMetaDataGetNumOperands ) - _method( LLVMMetaDataStringGet ) - - /* NamedMetaData */ - _method( LLVMNamedMetaDataGetName ) - _method( LLVMNamedMetaDataAddOperand ) - _method( LLVMEraseNamedMetaData ) - _method( LLVMDumpNamedMDToString ) - - /* Instructions */ - _method( LLVMGetInstructionParent ) - _method( LLVMGetFirstInstruction ) - _method( LLVMGetNextInstruction ) - _method( LLVMInstIsTerminator ) - _method( LLVMInstIsBinaryOp ) - _method( LLVMInstIsShift ) - _method( LLVMInstIsCast ) - _method( LLVMInstIsLogicalShift ) - _method( LLVMInstIsArithmeticShift ) - _method( LLVMInstIsAssociative ) - _method( LLVMInstIsCommutative ) - _method( LLVMInstIsVolatile ) - _method( LLVMSetVolatile ) - _method( LLVMInstGetOpcode ) - _method( LLVMInstGetOpcodeName ) - - _method( LLVMInstSetMetaData ) - _method( LLVMInstructionEraseFromParent ) - - /* Call Sites (Call or Invoke) */ - _method( LLVMSetInstructionCallConv ) - _method( LLVMGetInstructionCallConv ) - _method( LLVMIsTailCall ) - _method( LLVMSetTailCall ) - _method( LLVMAddInstrAttribute ) - _method( LLVMRemoveInstrAttribute ) - _method( LLVMSetInstrParamAlignment ) - _method( LLVMInstGetCalledFunction ) - _method( LLVMInstSetCalledFunction ) - - /* PHI Nodes */ - _method( LLVMAddIncoming1 ) - _method( LLVMCountIncoming ) - _method( LLVMGetIncomingValue ) - _method( LLVMGetIncomingBlock ) - - /* Comparison Instructions */ - _method( LLVMCmpInstGetPredicate ) - - /* Instruction builders */ - _method( LLVMCreateBuilder ) - _method( LLVMPositionBuilderBefore ) - _method( LLVMPositionBuilderAtEnd ) - _method( LLVMGetInsertBlock ) - _method( LLVMDisposeBuilder ) - - /* Terminators */ - _method( LLVMBuildRetVoid ) - _method( LLVMBuildRet ) - _method( LLVMBuildRetMultiple ) - _method( LLVMBuildBr ) - _method( LLVMBuildCondBr ) - _method( LLVMBuildSwitch ) - _method( LLVMBuildInvoke ) - _method( LLVMBuildUnreachable ) - - /* Add a case to the switch instruction */ - _method( LLVMAddCase ) - - /* Arithmetic */ - _method( LLVMBuildAdd ) - _method( LLVMBuildFAdd) - _method( LLVMBuildSub ) - _method( LLVMBuildFSub) - _method( LLVMBuildMul ) - _method( LLVMBuildFMul) - _method( LLVMBuildUDiv ) - _method( LLVMBuildSDiv ) - _method( LLVMBuildFDiv ) - _method( LLVMBuildURem ) - _method( LLVMBuildSRem ) - _method( LLVMBuildFRem ) - _method( LLVMBuildShl ) - _method( LLVMBuildLShr ) - _method( LLVMBuildAShr ) - _method( LLVMBuildAnd ) - _method( LLVMBuildOr ) - _method( LLVMBuildXor ) - _method( LLVMBuildNeg ) - _method( LLVMBuildNot ) - - /* Memory */ - _method( LLVMBuildMalloc ) - _method( LLVMBuildArrayMalloc ) - _method( LLVMBuildAlloca ) - _method( LLVMBuildArrayAlloca ) - _method( LLVMBuildFree ) - _method( LLVMBuildLoad ) - _method( LLVMBuildStore ) - _method( LLVMBuildGEP ) - _method( LLVMBuildInBoundsGEP ) - - _method( LLVMLdSetAlignment ) - _method( LLVMStSetAlignment ) - - /* Casts */ - _method( LLVMBuildTrunc ) - _method( LLVMBuildZExt ) - _method( LLVMBuildSExt ) - _method( LLVMBuildFPToUI ) - _method( LLVMBuildFPToSI ) - _method( LLVMBuildUIToFP ) - _method( LLVMBuildSIToFP ) - _method( LLVMBuildFPTrunc ) - _method( LLVMBuildFPExt ) - _method( LLVMBuildPtrToInt ) - _method( LLVMBuildIntToPtr ) - _method( LLVMBuildBitCast ) - - /* Comparisons */ - _method( LLVMBuildICmp ) - _method( LLVMBuildFCmp ) - - /* Atomics */ - _method( LLVMBuildAtomicCmpXchg ) - _method( LLVMBuildAtomicRMW ) - _method( LLVMBuildAtomicLoad ) - _method( LLVMBuildAtomicStore ) - _method( LLVMBuildFence ) - - /* Miscellaneous instructions */ - _method( LLVMBuildGetResult ) - _method( LLVMBuildInsertValue ) - _method( LLVMBuildPhi ) - _method( LLVMBuildCall ) - _method( LLVMBuildSelect ) - _method( LLVMBuildVAArg ) - _method( LLVMBuildExtractElement ) - _method( LLVMBuildInsertElement ) - _method( LLVMBuildShuffleVector ) - - /* Memory Buffer */ - _method( LLVMCreateMemoryBufferWithContentsOfFile ) - _method( LLVMCreateMemoryBufferWithSTDIN ) - _method( LLVMDisposeMemoryBuffer ) - - /* Pass Manager Builder */ - - _method( LLVMPassManagerBuilderCreate ) - _method( LLVMPassManagerBuilderDispose ) - - _method( LLVMPassManagerBuilderSetOptLevel ) - _method( LLVMPassManagerBuilderGetOptLevel ) - - _method( LLVMPassManagerBuilderSetSizeLevel ) - _method( LLVMPassManagerBuilderGetSizeLevel ) - - _method( LLVMPassManagerBuilderSetVectorize ) - _method( LLVMPassManagerBuilderGetVectorize ) -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 - _method( LLVMPassManagerBuilderSetLoopVectorize ) - _method( LLVMPassManagerBuilderGetLoopVectorize ) -#endif // llvm-3.2 - - _method( LLVMPassManagerBuilderSetDisableUnitAtATime ) - _method( LLVMPassManagerBuilderGetDisableUnitAtATime ) - - _method( LLVMPassManagerBuilderSetDisableUnrollLoops ) - _method( LLVMPassManagerBuilderGetDisableUnrollLoops ) - - _method( LLVMPassManagerBuilderSetDisableSimplifyLibCalls ) - _method( LLVMPassManagerBuilderGetDisableSimplifyLibCalls ) - - _method( LLVMPassManagerBuilderUseInlinerWithThreshold ) - - _method( LLVMPassManagerBuilderPopulateFunctionPassManager ) - _method( LLVMPassManagerBuilderPopulateModulePassManager ) - - /* Pass Manager */ - _method( LLVMCreatePassManager ) - _method( LLVMCreateFunctionPassManagerForModule ) - _method( LLVMRunPassManager ) - _method( LLVMInitializeFunctionPassManager ) - _method( LLVMRunFunctionPassManager ) - _method( LLVMFinalizeFunctionPassManager ) - _method( LLVMDisposePassManager ) - _method( LLVMDumpPasses ) - _method( LLVMAddPassByName ) - _method( LLVMAddPass ) - _method( LLVMInitializePasses ) - - _method( LLVMInitializeNativeTarget ) - _method( LLVMInitializeNativeTargetAsmPrinter ) -#if !defined(LLVM_DISABLE_PTX) -# if LLVM_HAS_NVPTX - _method( LLVMInitializeNVPTXTarget ) - _method( LLVMInitializeNVPTXTargetInfo ) - _method( LLVMInitializeNVPTXTargetMC ) - _method( LLVMInitializeNVPTXAsmPrinter ) -# else - _method( LLVMInitializePTXTarget ) - _method( LLVMInitializePTXTargetInfo ) - _method( LLVMInitializePTXTargetMC ) - _method( LLVMInitializePTXAsmPrinter ) -# endif -#endif - - /* Target Machine */ - _method( LLVMTargetMachineFromEngineBuilder ) - _method( LLVMDisposeTargetMachine ) - _method( LLVMCreateTargetMachine ) - _method( LLVMTargetMachineLookup ) - _method( LLVMTargetMachineEmitFile ) - _method( LLVMTargetMachineGetTargetData ) - _method( LLVMTargetMachineGetTargetName ) - _method( LLVMTargetMachineGetTargetShortDescription ) - _method( LLVMTargetMachineGetTriple ) - _method( LLVMTargetMachineGetCPU ) - _method( LLVMTargetMachineGetFS ) - - _method( LLVMPrintRegisteredTargetsForVersion ) - _method( LLVMGetHostCPUName ) - - /* Target Data */ - _method( LLVMCreateTargetData ) - _method( LLVMDisposeTargetData ) - _method( LLVMTargetDataAsString ) - _method( LLVMAddTargetData ) - _method( LLVMByteOrder ) - _method( LLVMPointerSize ) - _method( LLVMIntPtrType ) - _method( LLVMSizeOfTypeInBits ) - _method( LLVMStoreSizeOfType ) - _method( LLVMABISizeOfType ) - _method( LLVMABIAlignmentOfType ) - _method( LLVMCallFrameAlignmentOfType ) - _method( LLVMPreferredAlignmentOfType ) - _method( LLVMPreferredAlignmentOfGlobal ) - _method( LLVMElementAtOffset ) - _method( LLVMOffsetOfElement ) - - /* Engine Builder */ - - _method( LLVMCreateEngineBuilder ) - _method( LLVMDisposeEngineBuilder ) - _method( LLVMEngineBuilderForceJIT ) - _method( LLVMEngineBuilderForceInterpreter ) - _method( LLVMEngineBuilderSetOptLevel ) - _method( LLVMEngineBuilderSetMCPU ) - _method( LLVMEngineBuilderSetMAttrs ) - _method( LLVMEngineBuilderCreate ) - _method( LLVMEngineBuilderCreateTM ) - - /* Execution Engine */ -// Use EngineBuilder instead -// _method( LLVMCreateExecutionEngine ) - _method( LLVMDisposeExecutionEngine ) - _method( LLVMExecutionEngineDisableLazyCompilation ) - _method( LLVMRunFunction2 ) - _method( LLVMGetPointerToFunction ) - _method( LLVMGetPointerToGlobal ) - _method( LLVMAddGlobalMapping ) - _method( LLVMGetExecutionEngineTargetData ) - _method( LLVMRunStaticConstructors ) - _method( LLVMRunStaticDestructors ) - _method( LLVMFreeMachineCodeForFunction ) - _method( LLVMAddModule ) - _method( LLVMRemoveModule2 ) - - /* Generic Value */ - _method( LLVMCreateGenericValueOfInt ) - _method( LLVMCreateGenericValueOfFloat ) - _method( LLVMCreateGenericValueOfPointer ) - _method( LLVMGenericValueToInt ) - _method( LLVMGenericValueToFloat ) - _method( LLVMGenericValueToPointer ) - _method( LLVMDisposeGenericValue ) - - /* Passes */ - _method( LLVMCreatePassByName ) - _method( LLVMDisposePass ) - _method( LLVMGetPassName ) - _method( LLVMPassDump ) - - _method( LLVMCreateTargetLibraryInfo ) - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 - _method( LLVMCreateTargetTransformInfo ) -#endif - - /* Misc */ - _method( LLVMGetVersion ) - _method( LLVMGetIntrinsic ) - _method( LLVMLoadLibraryPermanently ) - _method( LLVMParseEnvOpts ) - _method( LLVMDefaultTargetTriple ) - _method( LLVMInlineFunction ) - _method( PyCObjectVoidPtrToPyLong ) - { NULL } -}; - - - -// Module main function, hairy because of py3k port -extern "C" { - -#if (PY_MAJOR_VERSION >= 3) -struct PyModuleDef module_def = { - PyModuleDef_HEAD_INIT, - "_core", - NULL, - -1, - core_methods, - NULL, NULL, NULL, NULL -}; -#define INITERROR return NULL -PyObject * -PyInit__core(void) -#else -#define INITERROR return -PyMODINIT_FUNC -init_core(void) -#endif -{ - LLVMLinkInJIT(); - LLVMLinkInInterpreter(); - LLVMInitializeNativeTarget(); -#if PY_MAJOR_VERSION >= 3 - PyObject *module = PyModule_Create( &module_def ); -#else - PyObject *module = Py_InitModule("_core", core_methods); -#endif - if (module == NULL) - INITERROR; -#if PY_MAJOR_VERSION >= 3 - - return module; -#endif -} - -} // end extern C diff --git a/llvm/_dwarf.cpp b/llvm/_dwarf.cpp deleted file mode 100644 index 43f75aa..0000000 --- a/llvm/_dwarf.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include - -namespace llvmpy { -namespace dwarf { - -using namespace llvm::dwarf; - -const char *constant_names[] = { - "LLVMDebugVersion", - - #define define(x) #x, - #include "_dwarf.h" - #undef define -}; - -int constant_values[] = { - llvm::LLVMDebugVersion, - - #define define(x) x, - #include "_dwarf.h" - #undef define -}; - -enum enum_values { - __llvmpy_LLVMDebugVersion, - - #define define(x) __llvmpy_##x, - #include "_dwarf.h" - #undef define - - NVALUES /* Get the number of constants */ -}; - -} // End namespace dwarf - -int -set_dwarf_constants(PyObject *module) -{ - int i; - for (i = 0; i < dwarf::NVALUES; i++) { - if (PyModule_AddIntConstant(module, dwarf::constant_names[i], - dwarf::constant_values[i]) > 0) - return -1; - } - - return 0; -} - -} // End namespace llvmpy - -#if (PY_MAJOR_VERSION >= 3) - struct PyModuleDef module_def = { - PyModuleDef_HEAD_INIT, - "_dwarf", - NULL, - -1, - NULL, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ - }; - - #define INITERROR return NULL - PyObject *PyInit__dwarf(void) -#else - #define INITERROR return - PyMODINIT_FUNC init_dwarf(void) -#endif -{ -#if PY_MAJOR_VERSION >= 3 - PyObject *module = PyModule_Create( &module_def ); -#else - PyObject *module = Py_InitModule("_dwarf", NULL); -#endif - if (module == NULL) - INITERROR; - - if (llvmpy::set_dwarf_constants(module) < 0) - INITERROR; - -#if PY_MAJOR_VERSION >= 3 - return module; -#endif -} diff --git a/llvm/_dwarf.h b/llvm/_dwarf.h deleted file mode 100644 index 78eada0..0000000 --- a/llvm/_dwarf.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Dwarf constant wrapping. See include/llvm/Support/Dwarf.h */ - -define(DWARF_VERSION) - -/* Dwarf tags */ -define(DW_TAG_array_type) -define(DW_TAG_class_type) -define(DW_TAG_entry_point) -define(DW_TAG_enumeration_type) -define(DW_TAG_formal_parameter) -define(DW_TAG_imported_declaration) -define(DW_TAG_label) -define(DW_TAG_lexical_block) -define(DW_TAG_member) -define(DW_TAG_pointer_type) -define(DW_TAG_reference_type) -define(DW_TAG_compile_unit) -define(DW_TAG_string_type) -define(DW_TAG_structure_type) -define(DW_TAG_subroutine_type) -define(DW_TAG_typedef) -define(DW_TAG_union_type) -define(DW_TAG_unspecified_parameters) -define(DW_TAG_variant) -define(DW_TAG_common_block) -define(DW_TAG_common_inclusion) -define(DW_TAG_inheritance) -define(DW_TAG_inlined_subroutine) -define(DW_TAG_module) -define(DW_TAG_ptr_to_member_type) -define(DW_TAG_set_type) -define(DW_TAG_subrange_type) -define(DW_TAG_with_stmt) -define(DW_TAG_access_declaration) -define(DW_TAG_base_type) -define(DW_TAG_catch_block) -define(DW_TAG_const_type) -define(DW_TAG_constant) -define(DW_TAG_enumerator) -define(DW_TAG_file_type) -define(DW_TAG_friend) -define(DW_TAG_namelist) -define(DW_TAG_namelist_item) -define(DW_TAG_packed_type) -define(DW_TAG_subprogram) -define(DW_TAG_template_type_parameter) -define(DW_TAG_template_value_parameter) -define(DW_TAG_thrown_type) -define(DW_TAG_try_block) -define(DW_TAG_variant_part) -define(DW_TAG_variable) -define(DW_TAG_volatile_type) -define(DW_TAG_dwarf_procedure) -define(DW_TAG_restrict_type) -define(DW_TAG_interface_type) -define(DW_TAG_namespace) -define(DW_TAG_imported_module) -define(DW_TAG_unspecified_type) -define(DW_TAG_partial_unit) -define(DW_TAG_imported_unit) -define(DW_TAG_condition) -define(DW_TAG_shared_type) -define(DW_TAG_type_unit) -define(DW_TAG_rvalue_reference_type) -define(DW_TAG_template_alias) -define(DW_TAG_MIPS_loop) -define(DW_TAG_format_label) -define(DW_TAG_function_template) -define(DW_TAG_class_template) -define(DW_TAG_GNU_template_template_param) -define(DW_TAG_GNU_template_parameter_pack) -define(DW_TAG_GNU_formal_parameter_pack) -define(DW_TAG_lo_user) -define(DW_TAG_APPLE_property) -define(DW_TAG_hi_user) - -/* Dwarf language constants */ -define(DW_LANG_C89) -define(DW_LANG_C) -define(DW_LANG_Ada83) -define(DW_LANG_C_plus_plus) -define(DW_LANG_Cobol74) -define(DW_LANG_Cobol85) -define(DW_LANG_Fortran77) -define(DW_LANG_Fortran90) -define(DW_LANG_Pascal83) -define(DW_LANG_Modula2) -define(DW_LANG_Java) -define(DW_LANG_C99) -define(DW_LANG_Ada95) -define(DW_LANG_Fortran95) -define(DW_LANG_PLI) -define(DW_LANG_ObjC) -define(DW_LANG_ObjC_plus_plus) -define(DW_LANG_UPC) -define(DW_LANG_D) -define(DW_LANG_Python) -define(DW_LANG_lo_user) -define(DW_LANG_Mips_Assembler) -define(DW_LANG_hi_user) - diff --git a/llvm/_util.py b/llvm/_util.py deleted file mode 100644 index da003b0..0000000 --- a/llvm/_util.py +++ /dev/null @@ -1,108 +0,0 @@ -# -# Copyright (c) 2008-10, Mahadevan R All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of this software, nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -"""Utility functions and classes. - -Used only in other modules, not for public use.""" - -import llvm -import llvm._core as _core # for PyCObjectVoidPtrToPyLong - - -#===----------------------------------------------------------------------=== -# A set of helpers to check various things. Raises exceptions on -# failures. -#===----------------------------------------------------------------------=== - -def check_gen(obj, typ): - if not isinstance(obj, typ): - typ_str = typ.__name__ - msg = "argument not an instance of llvm.core.%s" % typ_str - raise TypeError(msg) - -def check_is_unowned(ownable): - if ownable.owner: - raise llvm.LLVMException("object is already owned") - - -#===----------------------------------------------------------------------=== -# A set of helpers to unpack a list of Python wrapper objects -# into a list of PyCObject wrapped objects, checking types along -# the way. -#===----------------------------------------------------------------------=== - -def unpack_gen(objlist, check_fn): - for obj in objlist: check_fn(obj) - return [ obj.ptr for obj in objlist ] - -def unpack_gen_allow_none(objlist, check_fn): - for obj in objlist: - if obj is not None: - check_fn(obj) - return [ (obj.ptr if obj is not None else None) for obj in objlist ] - -#===----------------------------------------------------------------------=== -# Helper to wrap over iterables (LLVMFirstXXX, LLVMNextXXX). This used -# to be a generator, but that loses subscriptability of the result, so -# we now return a list. -#===----------------------------------------------------------------------=== - -def wrapiter(first, next, container, wrapper): - ret = [] - ptr = first(container) - while ptr: - ret.append(wrapper(ptr)) - ptr = next(ptr) - return ret - - -#===----------------------------------------------------------------------=== -# Py2/3 compatibility string check -#===----------------------------------------------------------------------=== -def _isstring_py2(x): - return isinstance(x, basestring) - -def _isstring_py3(x): - return isinstance(x, str) - -def _isstring_choose(): - try: - basestring - return _isstring_py2 - except: - return _isstring_py3 - -isstring = _isstring_choose() - -try: - unicode_type = unicode -except NameError: # Py3 - unicode_type = str - diff --git a/llvm/capsulethunk.h b/llvm/capsulethunk.h deleted file mode 100644 index 6b20564..0000000 --- a/llvm/capsulethunk.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef __CAPSULETHUNK_H -#define __CAPSULETHUNK_H - -#if ( (PY_VERSION_HEX < 0x02070000) \ - || ((PY_VERSION_HEX >= 0x03000000) \ - && (PY_VERSION_HEX < 0x03010000)) ) - -#define __PyCapsule_GetField(capsule, field, default_value) \ - ( PyCapsule_CheckExact(capsule) \ - ? (((PyCObject *)capsule)->field) \ - : (default_value) \ - ) \ - -#define __PyCapsule_SetField(capsule, field, value) \ - ( PyCapsule_CheckExact(capsule) \ - ? (((PyCObject *)capsule)->field = value), 1 \ - : 0 \ - ) \ - - -#define PyCapsule_Type PyCObject_Type - -#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule)) -#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule)) - - -#define PyCapsule_New(pointer, name, destructor) \ - (PyCObject_FromVoidPtr(pointer, destructor)) - - -#define PyCapsule_GetPointer(capsule, name) \ - (PyCObject_AsVoidPtr(capsule)) - -/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */ -#define PyCapsule_SetPointer(capsule, pointer) \ - __PyCapsule_SetField(capsule, cobject, pointer) - - -#define PyCapsule_GetDestructor(capsule) \ - __PyCapsule_GetField(capsule, destructor) - -#define PyCapsule_SetDestructor(capsule, dtor) \ - __PyCapsule_SetField(capsule, destructor, dtor) - - -/* - * Sorry, there's simply no place - * to store a Capsule "name" in a CObject. - */ -#define PyCapsule_GetName(capsule) NULL - -static int -PyCapsule_SetName(PyObject *capsule, const char *unused) -{ - unused = unused; - PyErr_SetString(PyExc_NotImplementedError, - "can't use PyCapsule_SetName with CObjects"); - return 1; -} - - - -#define PyCapsule_GetContext(capsule) \ - __PyCapsule_GetField(capsule, descr) - -#define PyCapsule_SetContext(capsule, context) \ - __PyCapsule_SetField(capsule, descr, context) - - -static void * -PyCapsule_Import(const char *name, int no_block) -{ - PyObject *object = NULL; - void *return_value = NULL; - char *trace; - size_t name_length = (strlen(name) + 1) * sizeof(char); - char *name_dup = (char *)PyMem_MALLOC(name_length); - - if (!name_dup) { - return NULL; - } - - memcpy(name_dup, name, name_length); - - trace = name_dup; - while (trace) { - char *dot = strchr(trace, '.'); - if (dot) { - *dot++ = '\0'; - } - - if (object == NULL) { - if (no_block) { - object = PyImport_ImportModuleNoBlock(trace); - } else { - object = PyImport_ImportModule(trace); - if (!object) { - PyErr_Format(PyExc_ImportError, - "PyCapsule_Import could not " - "import module \"%s\"", trace); - } - } - } else { - PyObject *object2 = PyObject_GetAttrString(object, trace); - Py_DECREF(object); - object = object2; - } - if (!object) { - goto EXIT; - } - - trace = dot; - } - - if (PyCObject_Check(object)) { - PyCObject *cobject = (PyCObject *)object; - return_value = cobject->cobject; - } else { - PyErr_Format(PyExc_AttributeError, - "PyCapsule_Import \"%s\" is not valid", - name); - } - -EXIT: - Py_XDECREF(object); - if (name_dup) { - PyMem_FREE(name_dup); - } - return return_value; -} - -#endif /* #if PY_VERSION_HEX < 0x02070000 */ - -#endif /* __CAPSULETHUNK_H */ diff --git a/llvm/core.py b/llvm/core.py index fafaa22..bed5763 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -28,64 +28,71 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -"""Core classes of LLVM. +from io import BytesIO +try: + from StringIO import StringIO +except ImportError: + try: + from cStringIO import StringIO + except ImportError: + from io import StringIO -The llvm.core module contains classes and constants required to build the -in-memory intermediate representation (IR) data structures.""" +import contextlib, weakref +import llvm +from llvm._intrinsic_ids import * -import llvm # top-level, for common stuff -import llvm._core as _core # C wrappers -import llvm._util as _util # utility functions - +from llvmpy import api #===----------------------------------------------------------------------=== # Enumerations #===----------------------------------------------------------------------=== -# type kinds (LLVMTypeKind enum) -TYPE_VOID = 0 -TYPE_HALF = 1 -TYPE_FLOAT = 2 -TYPE_DOUBLE = 3 -TYPE_X86_FP80 = 4 -TYPE_FP128 = 5 -TYPE_PPC_FP128 = 6 -TYPE_LABEL = 7 -TYPE_INTEGER = 8 -TYPE_FUNCTION = 9 -TYPE_STRUCT = 10 -TYPE_ARRAY = 11 -TYPE_POINTER = 12 -TYPE_VECTOR = 13 -TYPE_METADATA = 14 -TYPE_X86_MMX = 15 +# type id (llvm::Type::TypeID) +TYPE_VOID = api.llvm.Type.TypeID.VoidTyID +TYPE_HALF = api.llvm.Type.TypeID.HalfTyID +TYPE_FLOAT = api.llvm.Type.TypeID.FloatTyID +TYPE_DOUBLE = api.llvm.Type.TypeID.DoubleTyID +TYPE_X86_FP80 = api.llvm.Type.TypeID.X86_FP80TyID +TYPE_FP128 = api.llvm.Type.TypeID.FP128TyID +TYPE_PPC_FP128 = api.llvm.Type.TypeID.PPC_FP128TyID +TYPE_LABEL = api.llvm.Type.TypeID.LabelTyID +TYPE_INTEGER = api.llvm.Type.TypeID.IntegerTyID +TYPE_FUNCTION = api.llvm.Type.TypeID.FunctionTyID +TYPE_STRUCT = api.llvm.Type.TypeID.StructTyID +TYPE_ARRAY = api.llvm.Type.TypeID.ArrayTyID +TYPE_POINTER = api.llvm.Type.TypeID.PointerTyID +TYPE_VECTOR = api.llvm.Type.TypeID.VectorTyID +TYPE_METADATA = api.llvm.Type.TypeID.MetadataTyID +TYPE_X86_MMX = api.llvm.Type.TypeID.X86_MMXTyID # value IDs (llvm::Value::ValueTy enum) -VALUE_ARGUMENT = 0 -VALUE_BASIC_BLOCK = 1 -VALUE_FUNCTION = 2 -VALUE_GLOBAL_ALIAS = 3 -VALUE_GLOBAL_VARIABLE = 4 -VALUE_UNDEF_VALUE = 5 -VALUE_BLOCK_ADDRESS = 6 -VALUE_CONSTANT_EXPR = 7 -VALUE_CONSTANT_AGGREGATE_ZERO = 8 -VALUE_CONSTANT_DATA_ARRAY = 9 -VALUE_CONSTANT_DATA_VECTOR = 10 -VALUE_CONSTANT_INT = 11 -VALUE_CONSTANT_FP = 12 -VALUE_CONSTANT_ARRAY = 13 -VALUE_CONSTANT_STRUCT = 14 -VALUE_CONSTANT_VECTOR = 15 -VALUE_CONSTANT_POINTER_NULL = 16 -VALUE_MD_NODE = 17 -VALUE_MD_STRING = 18 -VALUE_INLINE_ASM = 19 -VALUE_PSEUDO_SOURCE_VALUE = 20 -VALUE_FIXED_STACK_PSEUDO_SOURCE_VALUE = 21 -VALUE_INSTRUCTION = 22 +# According to the doxygen docs, it is not a good idea to use these enums. +# There are more values than those declared. +VALUE_ARGUMENT = api.llvm.Value.ValueTy.ArgumentVal +VALUE_BASIC_BLOCK = api.llvm.Value.ValueTy.BasicBlockVal +VALUE_FUNCTION = api.llvm.Value.ValueTy.FunctionVal +VALUE_GLOBAL_ALIAS = api.llvm.Value.ValueTy.GlobalAliasVal +VALUE_GLOBAL_VARIABLE = api.llvm.Value.ValueTy.GlobalVariableVal +VALUE_UNDEF_VALUE = api.llvm.Value.ValueTy.UndefValueVal +VALUE_BLOCK_ADDRESS = api.llvm.Value.ValueTy.BlockAddressVal +VALUE_CONSTANT_EXPR = api.llvm.Value.ValueTy.ConstantExprVal +VALUE_CONSTANT_AGGREGATE_ZERO = api.llvm.Value.ValueTy.ConstantAggregateZeroVal +VALUE_CONSTANT_DATA_ARRAY = api.llvm.Value.ValueTy.ConstantDataArrayVal +VALUE_CONSTANT_DATA_VECTOR = api.llvm.Value.ValueTy.ConstantDataVectorVal +VALUE_CONSTANT_INT = api.llvm.Value.ValueTy.ConstantIntVal +VALUE_CONSTANT_FP = api.llvm.Value.ValueTy.ConstantFPVal +VALUE_CONSTANT_ARRAY = api.llvm.Value.ValueTy.ConstantArrayVal +VALUE_CONSTANT_STRUCT = api.llvm.Value.ValueTy.ConstantStructVal +VALUE_CONSTANT_VECTOR = api.llvm.Value.ValueTy.ConstantVectorVal +VALUE_CONSTANT_POINTER_NULL = api.llvm.Value.ValueTy.ConstantPointerNullVal +VALUE_MD_NODE = api.llvm.Value.ValueTy.MDNodeVal +VALUE_MD_STRING = api.llvm.Value.ValueTy.MDStringVal +VALUE_INLINE_ASM = api.llvm.Value.ValueTy.InlineAsmVal +VALUE_PSEUDO_SOURCE_VALUE = api.llvm.Value.ValueTy.PseudoSourceValueVal +VALUE_FIXED_STACK_PSEUDO_SOURCE_VALUE = api.llvm.Value.ValueTy.FixedStackPseudoSourceValueVal +VALUE_INSTRUCTION = api.llvm.Value.ValueTy.InstructionVal # instruction opcodes (from include/llvm/Instruction.def) OPCODE_RET = 1 @@ -148,34 +155,34 @@ OPCODE_INSERTVALUE = 57 OPCODE_LANDINGPAD = 58 # calling conventions -CC_C = 0 -CC_FASTCALL = 8 -CC_COLDCALL = 9 -CC_GHC = 10 -CC_X86_STDCALL = 64 -CC_X86_FASTCALL = 65 -CC_ARM_APCS = 66 -CC_ARM_AAPCS = 67 -CC_ARM_AAPCS_VFP = 68 -CC_MSP430_INTR = 69 -CC_X86_THISCALL = 70 -CC_PTX_KERNEL = 71 -CC_PTX_DEVICE = 72 -CC_MBLAZE_INTR = 73 -CC_MBLAZE_SVOL = 74 +CC_C = api.llvm.CallingConv.ID.C +CC_FASTCALL = api.llvm.CallingConv.ID.Fast +CC_COLDCALL = api.llvm.CallingConv.ID.Cold +CC_GHC = api.llvm.CallingConv.ID.GHC +CC_X86_STDCALL = api.llvm.CallingConv.ID.X86_StdCall +CC_X86_FASTCALL = api.llvm.CallingConv.ID.X86_FastCall +CC_ARM_APCS = api.llvm.CallingConv.ID.ARM_APCS +CC_ARM_AAPCS = api.llvm.CallingConv.ID.ARM_AAPCS +CC_ARM_AAPCS_VFP = api.llvm.CallingConv.ID.ARM_AAPCS_VFP +CC_MSP430_INTR = api.llvm.CallingConv.ID.MSP430_INTR +CC_X86_THISCALL = api.llvm.CallingConv.ID.X86_ThisCall +CC_PTX_KERNEL = api.llvm.CallingConv.ID.PTX_Kernel +CC_PTX_DEVICE = api.llvm.CallingConv.ID.PTX_Device +CC_MBLAZE_INTR = api.llvm.CallingConv.ID.MBLAZE_INTR +CC_MBLAZE_SVOL = api.llvm.CallingConv.ID.MBLAZE_SVOL # int predicates -ICMP_EQ = 32 -ICMP_NE = 33 -ICMP_UGT = 34 -ICMP_UGE = 35 -ICMP_ULT = 36 -ICMP_ULE = 37 -ICMP_SGT = 38 -ICMP_SGE = 39 -ICMP_SLT = 40 -ICMP_SLE = 41 +ICMP_EQ = api.llvm.CmpInst.Predicate.ICMP_EQ +ICMP_NE = api.llvm.CmpInst.Predicate.ICMP_NE +ICMP_UGT = api.llvm.CmpInst.Predicate.ICMP_UGT +ICMP_UGE = api.llvm.CmpInst.Predicate.ICMP_UGE +ICMP_ULT = api.llvm.CmpInst.Predicate.ICMP_ULT +ICMP_ULE = api.llvm.CmpInst.Predicate.ICMP_ULE +ICMP_SGT = api.llvm.CmpInst.Predicate.ICMP_SGT +ICMP_SGE = api.llvm.CmpInst.Predicate.ICMP_SGE +ICMP_SLT = api.llvm.CmpInst.Predicate.ICMP_SLT +ICMP_SLE = api.llvm.CmpInst.Predicate.ICMP_SLE # same as ICMP_xx, for backward compatibility IPRED_EQ = ICMP_EQ @@ -190,22 +197,22 @@ IPRED_SLT = ICMP_SLT IPRED_SLE = ICMP_SLE # real predicates -FCMP_FALSE = 0 -FCMP_OEQ = 1 -FCMP_OGT = 2 -FCMP_OGE = 3 -FCMP_OLT = 4 -FCMP_OLE = 5 -FCMP_ONE = 6 -FCMP_ORD = 7 -FCMP_UNO = 8 -FCMP_UEQ = 9 -FCMP_UGT = 10 -FCMP_UGE = 11 -FCMP_ULT = 12 -FCMP_ULE = 13 -FCMP_UNE = 14 -FCMP_TRUE = 15 +FCMP_FALSE = api.llvm.CmpInst.Predicate.FCMP_FALSE +FCMP_OEQ = api.llvm.CmpInst.Predicate.FCMP_OEQ +FCMP_OGT = api.llvm.CmpInst.Predicate.FCMP_OGT +FCMP_OGE = api.llvm.CmpInst.Predicate.FCMP_OGE +FCMP_OLT = api.llvm.CmpInst.Predicate.FCMP_OLT +FCMP_OLE = api.llvm.CmpInst.Predicate.FCMP_OLE +FCMP_ONE = api.llvm.CmpInst.Predicate.FCMP_ONE +FCMP_ORD = api.llvm.CmpInst.Predicate.FCMP_ORD +FCMP_UNO = api.llvm.CmpInst.Predicate.FCMP_UNO +FCMP_UEQ = api.llvm.CmpInst.Predicate.FCMP_UEQ +FCMP_UGT = api.llvm.CmpInst.Predicate.FCMP_UGT +FCMP_UGE = api.llvm.CmpInst.Predicate.FCMP_UGE +FCMP_ULT = api.llvm.CmpInst.Predicate.FCMP_ULT +FCMP_ULE = api.llvm.CmpInst.Predicate.FCMP_ULE +FCMP_UNE = api.llvm.CmpInst.Predicate.FCMP_UNE +FCMP_TRUE = api.llvm.CmpInst.Predicate.FCMP_TRUE # real predicates RPRED_FALSE = FCMP_FALSE @@ -225,102 +232,71 @@ RPRED_ULE = FCMP_ULE RPRED_UNE = FCMP_UNE RPRED_TRUE = FCMP_TRUE -# linkages (see llvm-c/Core.h) -LINKAGE_EXTERNAL = 0 -LINKAGE_AVAILABLE_EXTERNALLY = 1 -LINKAGE_LINKONCE_ANY = 2 -LINKAGE_LINKONCE_ODR = 3 -LINKAGE_WEAK_ANY = 4 -LINKAGE_WEAK_ODR = 5 -LINKAGE_APPENDING = 6 -LINKAGE_INTERNAL = 7 -LINKAGE_PRIVATE = 8 -LINKAGE_DLLIMPORT = 9 -LINKAGE_DLLEXPORT = 10 -LINKAGE_EXTERNAL_WEAK = 11 -LINKAGE_GHOST = 12 -LINKAGE_COMMON = 13 -LINKAGE_LINKER_PRIVATE = 14 -LINKAGE_LINKER_PRIVATE_WEAK = 15 -LINKAGE_LINKER_PRIVATE_WEAK_DEF_AUTO = 16 +# linkages (see llvm::GlobalValue::LinkageTypes) +LINKAGE_EXTERNAL = \ + api.llvm.GlobalValue.LinkageTypes.ExternalLinkage +LINKAGE_AVAILABLE_EXTERNALLY = \ + api.llvm.GlobalValue.LinkageTypes.AvailableExternallyLinkage +LINKAGE_LINKONCE_ANY = \ + api.llvm.GlobalValue.LinkageTypes.LinkOnceAnyLinkage +LINKAGE_LINKONCE_ODR = \ + api.llvm.GlobalValue.LinkageTypes.LinkOnceODRLinkage +LINKAGE_WEAK_ANY = \ + api.llvm.GlobalValue.LinkageTypes.WeakAnyLinkage +LINKAGE_WEAK_ODR = \ + api.llvm.GlobalValue.LinkageTypes.WeakODRLinkage +LINKAGE_APPENDING = \ + api.llvm.GlobalValue.LinkageTypes.AppendingLinkage +LINKAGE_INTERNAL = \ + api.llvm.GlobalValue.LinkageTypes.InternalLinkage +LINKAGE_PRIVATE = \ + api.llvm.GlobalValue.LinkageTypes.PrivateLinkage +LINKAGE_DLLIMPORT = \ + api.llvm.GlobalValue.LinkageTypes.DLLImportLinkage +LINKAGE_DLLEXPORT = \ + api.llvm.GlobalValue.LinkageTypes.DLLExportLinkage +LINKAGE_EXTERNAL_WEAK = \ + api.llvm.GlobalValue.LinkageTypes.ExternalWeakLinkage +LINKAGE_COMMON = \ + api.llvm.GlobalValue.LinkageTypes.CommonLinkage +LINKAGE_LINKER_PRIVATE = \ + api.llvm.GlobalValue.LinkageTypes.LinkerPrivateLinkage +LINKAGE_LINKER_PRIVATE_WEAK = \ + api.llvm.GlobalValue.LinkageTypes.LinkerPrivateWeakLinkage # visibility (see llvm/GlobalValue.h) -VISIBILITY_DEFAULT = 0 -VISIBILITY_HIDDEN = 1 -VISIBILITY_PROTECTED = 2 +VISIBILITY_DEFAULT = api.llvm.GlobalValue.VisibilityTypes.DefaultVisibility +VISIBILITY_HIDDEN = api.llvm.GlobalValue.VisibilityTypes.HiddenVisibility +VISIBILITY_PROTECTED = api.llvm.GlobalValue.VisibilityTypes.ProtectedVisibility -# parameter attributes (see llvm/Attributes.h) -ATTR_NONE = 0 -ATTR_ZEXT = 1 -ATTR_SEXT = 2 -ATTR_NO_RETURN = 4 -ATTR_IN_REG = 8 -ATTR_STRUCT_RET = 16 -ATTR_NO_UNWIND = 32 -ATTR_NO_ALIAS = 64 -ATTR_BY_VAL = 128 -ATTR_NEST = 256 -ATTR_READ_NONE = 512 -ATTR_READONLY = 1024 -ATTR_NO_INLINE = 1<<11 -ATTR_ALWAYS_INLINE = 1<<12 -ATTR_OPTIMIZE_FOR_SIZE = 1<<13 -ATTR_STACK_PROTECT = 1<<14 -ATTR_STACK_PROTECT_REQ = 1<<15 -ATTR_ALIGNMENT = 1<<16 -ATTR_NO_CAPTURE = 1<<21 -ATTR_NO_REDZONE = 1<<22 -ATTR_NO_IMPLICIT_FLOAT = 1<<23 -ATTR_NAKED = 1<<24 -ATTR_INLINE_HINT = 1<<25 -ATTR_STACK_ALIGNMENT = 7<<26 -ATTR_HOTPATCH = 1<<29 - -# intrinsic IDs -from llvm._intrinsic_ids import * +# parameter attributes llvm::Attributes::AttrVal (see llvm/Attributes.h) +ATTR_NONE = api.llvm.Attributes.AttrVal.None_ +ATTR_ZEXT = api.llvm.Attributes.AttrVal.ZExt +ATTR_SEXT = api.llvm.Attributes.AttrVal.SExt +ATTR_NO_RETURN = api.llvm.Attributes.AttrVal.NoReturn +ATTR_IN_REG = api.llvm.Attributes.AttrVal.InReg +ATTR_STRUCT_RET = api.llvm.Attributes.AttrVal.StructRet +ATTR_NO_UNWIND = api.llvm.Attributes.AttrVal.NoUnwind +ATTR_NO_ALIAS = api.llvm.Attributes.AttrVal.NoAlias +ATTR_BY_VAL = api.llvm.Attributes.AttrVal.ByVal +ATTR_NEST = api.llvm.Attributes.AttrVal.Nest +ATTR_READ_NONE = api.llvm.Attributes.AttrVal.ReadNone +ATTR_READONLY = api.llvm.Attributes.AttrVal.ReadOnly +ATTR_NO_INLINE = api.llvm.Attributes.AttrVal.NoInline +ATTR_ALWAYS_INLINE = api.llvm.Attributes.AttrVal.AlwaysInline +ATTR_OPTIMIZE_FOR_SIZE = api.llvm.Attributes.AttrVal.OptimizeForSize +ATTR_STACK_PROTECT = api.llvm.Attributes.AttrVal.StackProtect +ATTR_STACK_PROTECT_REQ = api.llvm.Attributes.AttrVal.StackProtectReq +ATTR_ALIGNMENT = api.llvm.Attributes.AttrVal.Alignment +ATTR_NO_CAPTURE = api.llvm.Attributes.AttrVal.NoCapture +ATTR_NO_REDZONE = api.llvm.Attributes.AttrVal.NoRedZone +ATTR_NO_IMPLICIT_FLOAT = api.llvm.Attributes.AttrVal.NoImplicitFloat +ATTR_NAKED = api.llvm.Attributes.AttrVal.Naked +ATTR_INLINE_HINT = api.llvm.Attributes.AttrVal.InlineHint +ATTR_STACK_ALIGNMENT = api.llvm.Attributes.AttrVal.StackAlignment -#===----------------------------------------------------------------------=== -# Helpers (for internal use) -#===----------------------------------------------------------------------=== - -def check_is_type(obj): _util.check_gen(obj, Type) -def check_is_type_struct(obj): _util.check_gen(obj, StructType) -def check_is_value(obj): _util.check_gen(obj, Value) -def check_is_constant(obj): _util.check_gen(obj, Constant) -def check_is_function(obj): _util.check_gen(obj, Function) -def check_is_global_value(obj): _util.check_gen(obj, GlobalValue) -def check_is_basic_block(obj): _util.check_gen(obj, BasicBlock) -def check_is_module(obj): _util.check_gen(obj, Module) - -def unpack_types(objlst): return _util.unpack_gen(objlst, check_is_type) -def unpack_values(objlst): return _util.unpack_gen(objlst, check_is_value) -def unpack_constants(objlst): return _util.unpack_gen(objlst, check_is_constant) - -def unpack_values_or_none(objlst): - return _util.unpack_gen_allow_none(objlst, check_is_value) - -def check_is_callable(obj): - if isinstance(obj, Function): - return - typ = obj.type - if isinstance(typ, PointerType) and \ - isinstance(typ.pointee, FunctionType): - return - raise TypeError("argument is neither a function nor a function pointer") - -def _to_int(v): - if v: - return 1 - else: - return 0 - - -#===----------------------------------------------------------------------=== -# Module -#===----------------------------------------------------------------------=== - -class Module(llvm.Ownable, llvm.Cacheable): +class Module(llvm.Wrapper): """A Module instance stores all the information related to an LLVM module. Modules are the top level container of all other LLVM Intermediate @@ -334,6 +310,15 @@ class Module(llvm.Ownable, llvm.Cacheable): module_obj = Module.new('my_module') """ + __cache = weakref.WeakValueDictionary() + + def __new__(cls, ptr): + cached = cls.__cache.get(ptr) + if cached: + return cached + obj = object.__new__(cls) + cls.__cache[ptr] = obj + return obj @staticmethod def new(id): @@ -341,7 +326,9 @@ class Module(llvm.Ownable, llvm.Cacheable): Creates an instance of Module, having the id `id'. """ - return Module(_core.LLVMModuleCreateWithName(id)) + context = api.llvm.getGlobalContext() + m = api.llvm.Module.new(id, context) + return Module(m) @staticmethod def from_bitcode(fileobj_or_str): @@ -349,22 +336,20 @@ class Module(llvm.Ownable, llvm.Cacheable): file. fileobj_or_str -- takes a file-like object or string that contains - a module represented in bitcode. + a module represented in bitcode. """ + if isinstance(fileobj_or_str, str): + bc = fileobj_or_str + else: + bc = fileobj_or_str.read() + errbuf = BytesIO() + context = api.llvm.getGlobalContext() + m = api.llvm.ParseBitCodeFile(bc, context, errbuf) + if not m: + raise Exception(errbuf.getvalue()) + errbuf.close() + return Module(m) - if isinstance(fileobj_or_str, _util.unicode_type): - data = fileobj_or_str.encode('utf-8') - elif isinstance(fileobj_or_str, bytes): - data = fileobj_or_str - else: - data = fileobj_or_str.read() - ret = _core.LLVMGetModuleFromBitcode(data) - if not ret: - raise llvm.LLVMException("Unable to create module from bitcode") - elif _util.isstring(ret): - raise llvm.LLVMException(ret) - else: - return Module(ret) @staticmethod def from_assembly(fileobj_or_str): @@ -373,83 +358,68 @@ class Module(llvm.Ownable, llvm.Cacheable): fileobj_or_str -- takes a file-like object or string that contains - a module represented in llvm-ir assembly. + a module represented in llvm-ir assembly. """ - - if isinstance(fileobj_or_str, _util.unicode_type): - data = fileobj_or_str.encode('utf-8') - elif isinstance(fileobj_or_str, bytes): - data = fileobj_or_str + if isinstance(fileobj_or_str, str): + ir = fileobj_or_str else: - data = fileobj_or_str.read() - if isinstance(data, _util.unicode_type): - data = data.encode() - ret = _core.LLVMGetModuleFromAssembly(data) - if not ret: - raise llvm.LLVMException("Unable to create module from assembly") - elif isinstance(ret, str): - raise llvm.LLVMException(ret) - else: - return Module(ret) - - def __init__(self, ptr): - """DO NOT CALL DIRECTLY. - - Use the static method `Module.new' instead. - """ - llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule) + ir = fileobj_or_str.read() + errbuf = BytesIO() + context = api.llvm.getGlobalContext() + m = api.llvm.ParseAssemblyString(ir, None, api.llvm.SMDiagnostic.new(), + context) + errbuf.close() + return Module(m) def __str__(self): """Text representation of a module. - Returns the textual representation (`llvm assembly') of the - module. Use it like this: + Returns the textual representation (`llvm assembly') of the + module. Use it like this: - ll = str(module_obj) - print module_obj # same as `print ll' - """ - return _core.LLVMDumpModuleToString(self.ptr) + ll = str(module_obj) + print module_obj # same as `print ll' + """ + return str(self._ptr) def __eq__(self, rhs): + assert isinstance(rhs, Module), type(rhs) if isinstance(rhs, Module): return str(self) == str(rhs) else: return False - + def __ne__(self, rhs): - return not self == rhs + return not (self == rhs) + def _get_target(self): - return _core.LLVMGetTarget(self.ptr) + return self._ptr.getTargetTriple() def _set_target(self, value): - return _core.LLVMSetTarget(self.ptr, value) + return self._ptr.setTargetTriple(value) target = property(_get_target, _set_target, - """The target triple string describing the target host.""" - ) + doc="The target triple string describing the target host.") + def _get_data_layout(self): - return _core.LLVMGetDataLayout(self.ptr) + return self._ptr.getDataLayout() def _set_data_layout(self, value): - _core.LLVMSetDataLayout(self.ptr, value) + return self._ptr.setDataLayout(value) data_layout = property(_get_data_layout, _set_data_layout, - """The data layout string for the module's target platform. + doc = """The data layout string for the module's target platform. - The data layout strings is an encoded representation of - the type sizes and alignments expected by this module. - """ - ) + The data layout strings is an encoded representation of + the type sizes and alignments expected by this module. + """ + ) @property def pointer_size(self): - """Pointer size of target platform. - - Can be 0, 32 or 64. Zero represents - llvm::Module::AnyPointerSize.""" - return _core.LLVMModuleGetPointerSize(self.ptr) + return self._ptr.getPointerSize() def link_in(self, other, preserve=False): """Link the `other' module into this one. @@ -459,115 +429,160 @@ class Module(llvm.Ownable, llvm.Cacheable): The `other' module is no longer valid after this method is invoked, all refs to it should be dropped. - + In the future, this API might be replaced with a full-fledged Linker class. """ - check_is_module(other) - if not preserve: - other.forget() # remove it from object cache - result = _core.LLVMLinkModules(self.ptr, other.ptr, int(bool(preserve))) - if result is not None: - raise llvm.LLVMException(result) - if not preserve: - # Prevent user from using the other module - other.ptr = None - # Use a dummy owner to prevent other.ptr to be deleted - other._own(llvm.DummyOwner()) + assert isinstance(other, Module) + enum_mode = api.llvm.Linker.LinkerMode + mode = enum_mode.PreserveSource if preserve else enum_mode.DestroySource + + with contextlib.closing(BytesIO()) as errmsg: + failed = api.llvm.Linker.LinkModules(self._ptr, + other._ptr, + mode, + errmsg) + if failed: + raise llvm.LLVMException(errmsg) def get_type_named(self, name): - """Return a Type object with the given name.""" - ptr = _core.LLVMGetTypeByName(self.ptr, name) - if ptr: - kind = _core.LLVMGetTypeKind(ptr) - return _make_type(ptr, kind) - return None + typ = self._ptr.getTypeByName(name) + if typ: + return StructType(typ) def add_global_variable(self, ty, name, addrspace=0): """Add a global variable of given type with given name.""" - return GlobalVariable.new(self, ty, name, addrspace) + external = api.llvm.GlobalVariable.LinkageTypes.ExternalLinkage + notthreadlocal = api.llvm.GlobalVariable.ThreadLocalMode.NotThreadLocal + init = None + insertbefore = None + ptr = api.llvm.GlobalVariable.new(self._ptr, + ty._ptr, + False, + external, + init, + name, + insertbefore, + notthreadlocal, + addrspace) + return _make_value(ptr) def get_global_variable_named(self, name): """Return a GlobalVariable object for the given name.""" - return GlobalVariable.get(self, name) + ptr = self._ptr.getNamedGlobal(name) + if ptr is None: + raise llvm.LLVMException("No global named: %s" % name) + return _make_value(ptr) @property def global_variables(self): - """All global variables in this module.""" - return _util.wrapiter(_core.LLVMGetFirstGlobal, - _core.LLVMGetNextGlobal, self.ptr, _make_value) + return list(map(_make_value, self._ptr.list_globals())) def add_function(self, ty, name): """Add a function of given type with given name.""" return Function.new(self, ty, name) +# fn = self.get_function_named(name) +# if fn is not None: +# raise llvm.LLVMException("Duplicated function %s" % name) +# return self.get_or_insert_function(ty, name) def get_function_named(self, name): """Return a Function object representing function with given name.""" return Function.get(self, name) +# fn = self._ptr.getFunction(name) +# if fn is not None: +# return _make_value(fn) def get_or_insert_function(self, ty, name): """Like get_function_named(), but does add_function() first, if - function is not present.""" + function is not present.""" return Function.get_or_insert(self, ty, name) +# constant = self._ptr.getOrInsertFunction(name, ty._ptr) +# try: +# fn = constant._downcast(api.llvm.Function) +# except ValueError: +# # bitcasted to function type +# return _make_value(constant) +# else: +# return _make_value(fn) @property def functions(self): """All functions in this module.""" - return _util.wrapiter(_core.LLVMGetFirstFunction, - _core.LLVMGetNextFunction, self.ptr, _make_value) + return list(map(_make_value, self._ptr.list_functions())) def verify(self): """Verify module. - Checks module for errors. Raises `llvm.LLVMException' on any - error.""" - ret = _core.LLVMVerifyModule(self.ptr) - # Note: LLVM has a bug in preverifier that will always abort - # the process upon failure. - if ret != "": - raise llvm.LLVMException(ret) + Checks module for errors. Raises `llvm.LLVMException' on any + error.""" + action = api.llvm.VerifierFailureAction.ReturnStatusAction + errio = BytesIO() + broken = api.llvm.verifyModule(self._ptr, action, errio) + if broken: + raise llvm.LLVMException(errio.getvalue()) def to_bitcode(self, fileobj=None): """Write bitcode representation of module to given file-like object. fileobj -- A file-like object to where the bitcode is written. - If it is None, the bitcode is returned. + If it is None, the bitcode is returned. Return value -- Returns None if fileobj is not None. - Otherwise, return the bitcode as a bytestring. + Otherwise, return the bitcode as a bytestring. """ - - data = _core.LLVMGetBitcodeFromModule(self.ptr) - if not data: - raise llvm.LLVMException("Unable to create bitcode") - if fileobj is not None: - fileobj.write(data) - else: - return data - - def add_library(self, name): - return _core.LLVMModuleAddLibrary(self.ptr, name) + ret = False + if fileobj is None: + ret = True + fileobj = BytesIO + api.llvm.WriteBitcodeToFile(self._ptr, fileobj) + if ret: + return fileobj.getvalue() def _get_id(self): - return _core.LLVMGetModuleIdentifier(self.ptr) + return self._ptr.getModuleIdentifier() def _set_id(self, string): - _core.LLVMSetModuleIdentifier(self.ptr, string) + self._ptr.setModuleIdentifier(string) id = property(_get_id, _set_id) + def _to_native_something(self, fileobj, cgft): + + cgft = api.llvm.TargetMachine.CodeGenFileType.CGFT_AssemblyFile + cgft = api.llvm.TargetMachine.CodeGenFileType.CGFT_ObjectFile + + from llvm.ee import TargetMachine + from llvm.passes import PassManager + from llvmpy import extra + tm = TargetMachine.new()._ptr + pm = PassManager.new()._ptr + formatted + failed = tm.addPassesToEmitFile(pm, fileobj, cgft, False) + + if failed: + raise llvm.LLVMException("Failed to write native object file") + if ret: + return fileobj.getvalue() + + def to_native_object(self, fileobj=None): '''Outputs the byte string of the module as native object code If a fileobj is given, the output is written to it; Otherwise, the output is returned ''' - data = _core.LLVMGetNativeCodeFromModule(self.ptr, 0) - if fileobj is not None: - fileobj.write(data) - else: - return data + ret = False + if fileobj is None: + ret = True + fileobj = BytesIO() + from llvm.ee import TargetMachine + tm = TargetMachine.new() + fileobj.write(tm.emit_object(self)) + if ret: + return fileobj.getvalue() + def to_native_assembly(self, fileobj=None): '''Outputs the byte string of the module as native assembly code @@ -575,76 +590,88 @@ class Module(llvm.Ownable, llvm.Cacheable): If a fileobj is given, the output is written to it; Otherwise, the output is returned ''' - data = _core.LLVMGetNativeCodeFromModule(self.ptr, 1) - if fileobj is not None: - fileobj.write(data) - else: - return data + ret = False + if fileobj is None: + ret = True + fileobj = StringIO() + from llvm.ee import TargetMachine + tm = TargetMachine.new() + asm = tm.emit_assembly(self) + fileobj.write(asm) + if ret: + return fileobj.getvalue() + def get_or_insert_named_metadata(self, name): - ptr = _core.LLVMModuleGetOrInsertNamedMetaData(self.ptr, name) - return NamedMetaData(ptr) + return NamedMetaData(self._ptr.getOrInsertNamedMetadata(name)) def get_named_metadata(self, name): - ptr = _core.LLVMModuleGetNamedMetaData(self.ptr, name) - return NamedMetaData(ptr) + md = self._ptr.getNamedMetadata(name) + if md: + return NamedMetaData(md) def clone(self): - return Module(_core.LLVMCloneModule(self.ptr)) + return Module(api.llvm.CloneModule(self._ptr)) -#===----------------------------------------------------------------------=== -# Types -#===----------------------------------------------------------------------=== - -class Type(object): +class Type(llvm.Wrapper): """Represents a type, like a 32-bit integer or an 80-bit x86 float. Use one of the static methods to create an instance. Example: - ty = Type.double() + ty = Type.double() """ + _type_ = api.llvm.Type + + def __init__(self, ptr): + ptr = ptr._downcast(type(self)._type_) + super(Type, self).__init__(ptr) + + @property + def kind(self): + return self._ptr.getTypeID() @staticmethod def int(bits=32): """Create an integer type having the given bit width.""" - if bits == 1: - return _make_type(_core.LLVMInt1Type(), TYPE_INTEGER) - elif bits == 8: - return _make_type(_core.LLVMInt8Type(), TYPE_INTEGER) - elif bits == 16: - return _make_type(_core.LLVMInt16Type(), TYPE_INTEGER) - elif bits == 32: - return _make_type(_core.LLVMInt32Type(), TYPE_INTEGER) - elif bits == 64: - return _make_type(_core.LLVMInt64Type(), TYPE_INTEGER) - else: - bits = int(bits) # bits must be an int - return _make_type(_core.LLVMIntType(bits), TYPE_INTEGER) + context = api.llvm.getGlobalContext() + ptr = api.llvm.Type.getIntNTy(context, bits) + return Type(ptr) @staticmethod def float(): """Create a 32-bit floating point type.""" - return _make_type(_core.LLVMFloatType(), TYPE_FLOAT) + context = api.llvm.getGlobalContext() + ptr = api.llvm.Type.getFloatTy(context) + return Type(ptr) @staticmethod def double(): """Create a 64-bit floating point type.""" - return _make_type(_core.LLVMDoubleType(), TYPE_DOUBLE) + context = api.llvm.getGlobalContext() + ptr = api.llvm.Type.getDoubleTy(context) + return Type(ptr) @staticmethod def x86_fp80(): """Create a 80-bit x86 floating point type.""" - return _make_type(_core.LLVMX86FP80Type(), TYPE_X86_FP80) + context = api.llvm.getGlobalContext() + ptr = api.llvm.Type.getX86_FP80Ty(context) + return Type(ptr) @staticmethod def fp128(): """Create a 128-bit floating point type (with 112-bit - mantissa).""" - return _make_type(_core.LLVMFP128Type(), TYPE_FP128) - + mantissa).""" + context = api.llvm.getGlobalContext() + ptr = api.llvm.Type.getFP128Ty(context) + return Type(ptr) + @staticmethod def ppc_fp128(): """Create a 128-bit floating point type (two 64-bits).""" - return _make_type(_core.LLVMPPCFP128Type(), TYPE_PPC_FP128) + context = api.llvm.getGlobalContext() + ptr = api.llvm.Type.getPPC_FP128Ty(context) + return Type(ptr) + @staticmethod def function(return_ty, param_tys, var_arg=False): @@ -654,20 +681,19 @@ class Type(object): `return_ty', takes arguments of types as given in the iterable `param_tys'. Set `var_arg' to True (default is False) for a variadic function.""" - check_is_type(return_ty) - var_arg = _to_int(var_arg) # ensure int - params = unpack_types(param_tys) - return _make_type(_core.LLVMFunctionType(return_ty.ptr, params, - var_arg), TYPE_FUNCTION) + ptr = api.llvm.FunctionType.get(return_ty._ptr, + llvm._extract_ptrs(param_tys), + var_arg) + return FunctionType(ptr) @staticmethod def opaque(name): """Create a opaque StructType""" + context = api.llvm.getGlobalContext() if not name: - raise llvm.LLVMException("Must specify a name") - - objptr = _core.LLVMStructTypeIdentified(name) - return _make_type(objptr, TYPE_STRUCT) + raise llvm.LLVMException("Opaque type must have a non-empty name") + ptr = api.llvm.StructType.create(context, name) + return StructType(ptr) @staticmethod def struct(element_tys, name=''): # not packed @@ -679,7 +705,18 @@ class Type(object): If name is not '', creates a identified type; otherwise, creates a literal type.""" - return Type.__struct(element_tys, packed=False, name=name) + context = api.llvm.getGlobalContext() + is_packed = False + if name: + ptr = api.llvm.StructType.create(context, name) + ptr.setBody(llvm._extract_ptrs(element_tys), is_packed) + else: + ptr = api.llvm.StructType.get(context, + llvm._extract_ptrs(element_tys), + is_packed) + + + return StructType(ptr) @staticmethod def packed_struct(element_tys, name=''): @@ -691,21 +728,11 @@ class Type(object): If name is not '', creates a identified type; otherwise, creates a literal type.""" - return Type.__struct(element_tys, packed=True, name=name) - - @staticmethod - def __struct(element_tys, packed, name): - elems = unpack_types(element_tys) - packed = int(bool(packed)) - - if name: # create Identified StructType - objptr = _core.LLVMStructTypeIdentified(name) - _core.LLVMSetStructBody(objptr, elems, packed) - else: # create Literal StructType - objptr = _core.LLVMStructType(elems, packed) - - return _make_type(objptr, TYPE_STRUCT) - + context = api.llvm.getGlobalContext() + is_packed = True + ptr = api.llvm.StructType.create(context) + ptr.setBody(llvm._extract_ptrs(element_tys), is_packed) + return StructType(ptr) @staticmethod def array(element_ty, count): @@ -713,10 +740,8 @@ class Type(object): Creates a type for an array of elements of type `element_ty', having 'count' elements.""" - check_is_type(element_ty) - count = int(count) # must be an int - return _make_type(_core.LLVMArrayType(element_ty.ptr, count), - TYPE_ARRAY) + ptr = api.llvm.ArrayType.get(element_ty._ptr, count) + return ArrayType(ptr) @staticmethod def pointer(pointee_ty, addr_space=0): @@ -724,10 +749,8 @@ class Type(object): Creates a pointer type, which can point to values of type `pointee_ty', in the address space `addr_space'.""" - check_is_type(pointee_ty) - addr_space = int(addr_space) # must be an int - return _make_type(_core.LLVMPointerType(pointee_ty.ptr, - addr_space), TYPE_POINTER) + ptr = api.llvm.PointerType.get(pointee_ty._ptr, addr_space) + return PointerType(ptr) @staticmethod def vector(element_ty, count): @@ -735,222 +758,208 @@ class Type(object): Creates a type for a vector of elements of type `element_ty', having `count' elements.""" - check_is_type(element_ty) - count = int(count) # must be an int - return _make_type(_core.LLVMVectorType(element_ty.ptr, count), - TYPE_VECTOR) + ptr = api.llvm.VectorType.get(element_ty._ptr, count) + return VectorType(ptr) @staticmethod def void(): """Create a void type. Represents the `void' type.""" - return _make_type(_core.LLVMVoidType(), TYPE_VOID) + context = api.llvm.getGlobalContext() + ptr = api.llvm.Type.getVoidTy(context) + return Type(ptr) @staticmethod def label(): """Create a label type.""" - return _make_type(_core.LLVMLabelType(), TYPE_LABEL) + context = api.llvm.getGlobalContext() + ptr = api.llvm.Type.getLabelTy(context) + return Type(ptr) - def __init__(self, ptr, kind): - """DO NOT CALL DIRECTLY. + def __new__(cls, ptr): + tyid = ptr.getTypeID() - Use one of the static methods instead.""" - self.ptr = ptr - self.kind = kind - """An enum (int) value denoting which type this is. + idmap = { + TYPE_HALF: IntegerType, + TYPE_INTEGER: IntegerType, + TYPE_FUNCTION: FunctionType, + TYPE_STRUCT: StructType, + TYPE_ARRAY: ArrayType, + TYPE_POINTER: PointerType, + TYPE_VECTOR: VectorType, + } - Use the symbolic constants TYPE_* defined in llvm.core - module.""" + try: + newcls = idmap[tyid] + except KeyError: + newcls = Type + obj = llvm.Wrapper.__new__(newcls) + return obj def __str__(self): - """Text representation of a type. - - Returns the textual representation (`llvm assembly') of the type.""" - return _core.LLVMDumpTypeToString(self.ptr) + return str(self._ptr) def __eq__(self, rhs): - if isinstance(rhs, Type): - return str(self) == str(rhs) - else: - return False + return self._ptr is rhs._ptr def __ne__(self, rhs): - return not self == rhs - + return not (self == rhs) class IntegerType(Type): """Represents an integer type.""" + _type_ = api.llvm.IntegerType @property def width(self): """The width of the integer type, in bits.""" - return _core.LLVMGetIntTypeWidth(self.ptr) - + return self._ptr.getIntegerBitWidth() class FunctionType(Type): """Represents a function type.""" + _type_ = api.llvm.FunctionType @property def return_type(self): """The type of the value returned by this function.""" - ptr = _core.LLVMGetReturnType(self.ptr) - kind = _core.LLVMGetTypeKind(ptr) - return _make_type(ptr, kind) + return Type(self._ptr.getReturnType()) @property def vararg(self): """True if this function is variadic.""" - return _core.LLVMIsFunctionVarArg(self.ptr) != 0 + return self._ptr.isVarArg() @property def args(self): """An iterable that yields Type objects, representing the types of the - arguments accepted by this function, in order.""" - pp = _core.LLVMGetFunctionTypeParams(self.ptr) - return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ] + arguments accepted by this function, in order.""" + return [Type(self._ptr.getParamType(i)) for i in range(self.arg_count)] @property def arg_count(self): """Number of arguments accepted by this function. - Same as len(obj.args), but faster.""" - return _core.LLVMCountParamTypes(self.ptr) + Same as len(obj.args), but faster.""" + return self._ptr.getNumParams() class StructType(Type): """Represents a structure type.""" + _type_ = api.llvm.StructType @property def element_count(self): """Number of elements (members) in the structure. - Same as len(obj.elements), but faster.""" - return _core.LLVMCountStructElementTypes(self.ptr) + Same as len(obj.elements), but faster.""" + return self._ptr.getNumElements() @property def elements(self): - """An iterable that yieldsd Type objects, representing the types of the - elements (members) of the structure, in order.""" - pp = _core.LLVMGetStructElementTypes(self.ptr) - return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ] + """An iterable that yields Type objects, representing the types of the + elements (members) of the structure, in order.""" + return [Type(self._ptr.getElementType(i)) + for i in range(self._ptr.getNumElements())] def set_body(self, elems, packed=False): """Filled the body of a opaque type. - """ + """ # check if not self.is_opaque: raise llvm.LLVMException("Body is already defined.") - # prepare arguments - elems = unpack_types(elems) - if packed: - packed = 1 - else: - packed = 0 - - # call c API - _core.LLVMSetStructBody(self.ptr, elems, packed) + self._ptr.setBody(llvm._extract_ptrs(elems), packed) @property def packed(self): """True if the structure is packed, False otherwise.""" - return _core.LLVMIsPackedStruct(self.ptr) != 0 + return self._ptr.isPacked() def _set_name(self, name): - _core.LLVMSetStructName(self.ptr, name) + self._ptr.setName(name) def _get_name(self): - return _core.LLVMGetStructName(self.ptr) + return self._ptr.getName() name = property(_get_name, _set_name) @property def is_literal(self): - return bool(_core.LLVMIsLiteralStruct(self.ptr)) + return self._ptr.isLiteral() @property def is_identified(self): - return not _core.LLVMIsLiteralStruct(self.ptr) + return not self.is_literal @property def is_opaque(self): - return bool(_core.LLVMIsOpaqueStruct(self.ptr)) + return self._ptr.isOpaque() class ArrayType(Type): """Represents an array type.""" + _type_ = api.llvm.ArrayType @property def element(self): - ptr = _core.LLVMGetElementType(self.ptr) - kind = _core.LLVMGetTypeKind(ptr) - return _make_type(ptr, kind) + return Type(self._ptr.getArrayElementType()) @property def count(self): - return _core.LLVMGetArrayLength(self.ptr) - + return self._ptr.getNumElements() class PointerType(Type): + _type_ = api.llvm.PointerType @property def pointee(self): - ptr = _core.LLVMGetElementType(self.ptr) - kind = _core.LLVMGetTypeKind(ptr) - return _make_type(ptr, kind) + return Type(self._ptr.getPointerElementType()) @property def address_space(self): - return _core.LLVMGetPointerAddressSpace(self.ptr) - + return self._ptr.getAddressSpace() class VectorType(Type): - + _type_ = api.llvm.VectorType + @property def element(self): - ptr = _core.LLVMGetElementType(self.ptr) - kind = _core.LLVMGetTypeKind(ptr) - return _make_type(ptr, kind) + return Type(self._ptr.getVectorElementType()) @property def count(self): - return _core.LLVMGetVectorSize(self.ptr) + return self._ptr.getNumElements() +class Value(llvm.Wrapper): + _type_ = api.llvm.Value -#===----------------------------------------------------------------------=== -# Type factory method -#===----------------------------------------------------------------------=== + def __init__(self, builder, ptr): + assert builder is _ValueFactory -# type ID -> class map -__class_for_typeid = { - TYPE_INTEGER : IntegerType, - TYPE_FUNCTION : FunctionType, - TYPE_STRUCT : StructType, - TYPE_ARRAY : ArrayType, - TYPE_POINTER : PointerType, - TYPE_VECTOR : VectorType, -} - -def _make_type(ptr, kind): - class_obj = __class_for_typeid.get(kind) - if class_obj: - return class_obj(ptr, kind) - else: - # "generic" type - return Type(ptr, kind) - - -#===----------------------------------------------------------------------=== -# Values -#===----------------------------------------------------------------------=== - -class Value(llvm.Cacheable): - - def __init__(self, ptr): - self.ptr = ptr + if type(self._type_) is type: + if isinstance(ptr, self._type_): # is not downcast + casted = ptr + else: + casted = ptr._downcast(self._type_) + else: + try: + for ty in self._type_: + if isinstance(ptr, ty): # is not downcast + casted = ptr + else: + try: + casted = ptr._downcast(ty) + except ValueError: + pass + else: + break + else: + casted = ptr + except TypeError: + casted = ptr + super(Value, self).__init__(casted) def __str__(self): - return _core.LLVMDumpValueToString(self.ptr) + return str(self._ptr) def __eq__(self, rhs): if isinstance(rhs, Value): @@ -962,290 +971,238 @@ class Value(llvm.Cacheable): return not self == rhs def _get_name(self): - return _core.LLVMGetValueName(self.ptr) + return self._ptr.getName() def _set_name(self, value): - return _core.LLVMSetValueName(self.ptr, value) + return self._ptr.setName(value) name = property(_get_name, _set_name) @property def value_id(self): - return _core.LLVMValueGetID(self.ptr) + return self._ptr.getValueID() @property def type(self): - ptr = _core.LLVMTypeOf(self.ptr) - kind = _core.LLVMGetTypeKind(ptr) - return _make_type(ptr, kind) + return Type(self._ptr.getType()) @property def use_count(self): - return _core.LLVMValueGetNumUses(self.ptr) - + return self._ptr.getNumUses() + @property def uses(self): - return [ _make_value(v) for v in _core.LLVMValueGetUses(self.ptr) ] - + return list(map(_make_value, self._ptr.list_use())) class User(Value): + _type_ = api.llvm.User @property def operand_count(self): - return _core.LLVMUserGetNumOperands(self.ptr) + return self._ptr.getNumOperands() @property def operands(self): """Yields operands of this instruction.""" - return [self._get_operand(i) for i in range(self.operand_count)] - - def _get_operand(self, i): - return _make_value(_core.LLVMUserGetOperand(self.ptr, i)) + return [_make_value(self._ptr.getOperand(i)) + for i in range(self.operand_count)] class Constant(User): + _type_ = api.llvm.Constant @staticmethod def null(ty): - check_is_type(ty) - return _make_value(_core.LLVMConstNull(ty.ptr)) + return _make_value(api.llvm.Constant.getNullValue(ty._ptr)) @staticmethod def all_ones(ty): - check_is_type(ty) - return _make_value(_core.LLVMConstAllOnes(ty.ptr)) + return _make_value(api.llvm.Constant.getAllOnesValue(ty._ptr)) @staticmethod def undef(ty): - check_is_type(ty) - return _make_value(_core.LLVMGetUndef(ty.ptr)) + return _make_value(api.llvm.UndefValue.get(ty._ptr)) @staticmethod def int(ty, value): - check_is_type(ty) - return _make_value(_core.LLVMConstInt(ty.ptr, value, 0)) + return _make_value(api.llvm.ConstantInt.get(ty._ptr, int(value), False)) @staticmethod def int_signextend(ty, value): - check_is_type(ty) - return _make_value(_core.LLVMConstInt(ty.ptr, value, 1)) + return _make_value(api.llvm.ConstantInt.get(ty._ptr, int(value), True)) @staticmethod def real(ty, value): - check_is_type(ty) - if isinstance(value, str): - return _make_value(_core.LLVMConstRealOfString(ty.ptr, value)) - else: - return _make_value(_core.LLVMConstReal(ty.ptr, value)) + return _make_value(api.llvm.ConstantFP.get(ty._ptr, float(value))) @staticmethod def string(strval): # dont_null_terminate=True - return _make_value(_core.LLVMConstString(strval, 1)) + cxt = api.llvm.getGlobalContext() + return _make_value(api.llvm.ConstantDataArray.getString(cxt, strval, False)) @staticmethod def stringz(strval): # dont_null_terminate=False - return _make_value(_core.LLVMConstString(strval, 0)) + cxt = api.llvm.getGlobalContext() + return _make_value(api.llvm.ConstantDataArray.getString(cxt, strval, True)) @staticmethod def array(ty, consts): - check_is_type(ty) - const_ptrs = unpack_constants(consts) - return _make_value(_core.LLVMConstArray(ty.ptr, const_ptrs)) + aryty = Type.array(ty, len(consts)) + return _make_value(api.llvm.ConstantArray.get(aryty._ptr, + llvm._extract_ptrs(consts))) @staticmethod def struct(consts): # not packed - const_ptrs = unpack_constants(consts) - return _make_value(_core.LLVMConstStruct(const_ptrs, 0)) + return _make_value(api.llvm.ConstantStruct.getAnon(llvm._extract_ptrs(consts), + False)) @staticmethod def packed_struct(consts): - const_ptrs = unpack_constants(consts) - return _make_value(_core.LLVMConstStruct(const_ptrs, 1)) + return _make_value(api.llvm.ConstantStruct.getAnon(llvm._extract_ptrs(consts), + False)) @staticmethod def vector(consts): - const_ptrs = unpack_constants(consts) - return _make_value(_core.LLVMConstVector(const_ptrs)) + return _make_value(api.llvm.ConstantVector.get(llvm._extract_ptrs(consts))) @staticmethod def sizeof(ty): - check_is_type(ty) - return _make_value(_core.LLVMSizeOf(ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getSizeOf(ty._ptr)) def neg(self): - return _make_value(_core.LLVMConstNeg(self.ptr)) + return _make_value(api.llvm.ConstantExpr.getNeg(self._ptr)) def not_(self): - return _make_value(_core.LLVMConstNot(self.ptr)) + return _make_value(api.llvm.ConstantExpr.getNot(self._ptr)) def add(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstAdd(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getAdd(self._ptr, rhs._ptr)) def fadd(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstFAdd(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getFAdd(self._ptr, rhs._ptr)) def sub(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstSub(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getSub(self._ptr, rhs._ptr)) def fsub(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstFSub(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getFSub(self._ptr, rhs._ptr)) def mul(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstMul(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getMul(self._ptr, rhs._ptr)) def fmul(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstFMul(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getFMul(self._ptr, rhs._ptr)) def udiv(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstUDiv(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getUDiv(self._ptr, rhs._ptr)) def sdiv(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstSDiv(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getSDiv(self._ptr, rhs._ptr)) def fdiv(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstFDiv(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getFDiv(self._ptr, rhs._ptr)) def urem(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstURem(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getURem(self._ptr, rhs._ptr)) def srem(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstSRem(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getSRem(self._ptr, rhs._ptr)) def frem(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstFRem(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getFRem(self._ptr, rhs._ptr)) def and_(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstAnd(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getAnd(self._ptr, rhs._ptr)) def or_(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstOr(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getOr(self._ptr, rhs._ptr)) def xor(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstXor(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getXor(self._ptr, rhs._ptr)) def icmp(self, int_pred, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstICmp(int_pred, self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getICmp(int_pred, self._ptr, rhs._ptr)) def fcmp(self, real_pred, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstFCmp(real_pred, self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getFCmp(real_pred, self._ptr, rhs._ptr)) def shl(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstShl(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getShl(self._ptr, rhs._ptr)) def lshr(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstLShr(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getLShr(self._ptr, rhs._ptr)) def ashr(self, rhs): - check_is_constant(rhs) - return _make_value(_core.LLVMConstAShr(self.ptr, rhs.ptr)) + return _make_value(api.llvm.ConstantExpr.getAShr(self._ptr, rhs._ptr)) def gep(self, indices): - index_ptrs = unpack_constants(indices) - return _make_value(_core.LLVMConstGEP(self.ptr, index_ptrs)) + indices = llvm._extract_ptrs(indices) + return _make_value(api.llvm.ConstantExpr.getGetElementPtr(self._ptr, indices)) def trunc(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstTrunc(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getTrunc(self._ptr, ty._ptr)) def sext(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstSExt(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getSExt(self._ptr, ty._ptr)) def zext(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstZExt(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getZExt(self._ptr, ty._ptr)) def fptrunc(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstFPTrunc(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getFPTrunc(self._ptr, ty._ptr)) def fpext(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstFPExt(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getFPExtend(self._ptr, ty._ptr)) def uitofp(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstUIToFP(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getUIToFP(self._ptr, ty._ptr)) def sitofp(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstSIToFP(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getSIToFP(self._ptr, ty._ptr)) def fptoui(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstFPToUI(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getFPToUI(self._ptr, ty._ptr)) def fptosi(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstFPToSI(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getFPToSI(self._ptr, ty._ptr)) def ptrtoint(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstPtrToInt(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getPtrToInt(self._ptr, ty._ptr)) def inttoptr(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstIntToPtr(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getIntToPtr(self._ptr, ty._ptr)) def bitcast(self, ty): - check_is_type(ty) - return _make_value(_core.LLVMConstBitCast(self.ptr, ty.ptr)) + return _make_value(api.llvm.ConstantExpr.getBitCast(self._ptr, ty._ptr)) def select(self, true_const, false_const): - check_is_constant(true_const) - check_is_constant(false_const) - return _make_value( - _core.LLVMConstSelect(self.ptr, true_const.ptr, false_const.ptr)) + return _make_value(api.llvm.ConstantExpr.getSelect(self._ptr, + true_const._ptr, + false_const._ptr)) def extract_element(self, index): # note: self must be a _vector_ constant - check_is_constant(index) - return _make_value( - _core.LLVMConstExtractElement(self.ptr, index.ptr)) + return _make_value(api.llvm.ConstantExpr.getExtractElement(self._ptr, index._ptr)) def insert_element(self, value, index): - # note: self must be a _vector_ constant - check_is_constant(value) - check_is_constant(index) - return _make_value( - _core.LLVMConstInsertElement(self.ptr, value.ptr, index.ptr)) + return _make_value(api.llvm.ConstantExpr.getExtractElement(self._ptr, + value._ptr, + index._ptr)) def shuffle_vector(self, vector_b, mask): - # note: self must be a _vector_ constant - check_is_constant(vector_b) - # note: vector_b must be a _vector_ constant - check_is_constant(mask) - return _make_value( - _core.LLVMConstShuffleVector(self.ptr, vector_b.ptr, mask.ptr)) - + return _make_value(api.llvm.ConstantExpr.getShuffleVector(self._ptr, + vector_b._ptr, + mask._ptr)) class ConstantExpr(Constant): + _type_ = api.llvm.ConstantExpr + @property def opcode(self): - return _core.LLVMGetConstExprOpcode(self.ptr) + return self._ptr.getOpcode() @property def opcode_name(self): - return _core.LLVMGetConstExprOpcodeName(self.ptr) - + return self._ptr.getOpcodeName() class ConstantAggregateZero(Constant): pass @@ -1258,18 +1215,21 @@ class ConstantDataArray(Constant): class ConstantDataVector(Constant): pass + class ConstantInt(Constant): + _type_ = api.llvm.ConstantInt + @property def z_ext_value(self): '''Obtain the zero extended value for an integer constant value.''' # Warning: assertion failure when value does not fit in 64 bits - return _core.LLVMConstIntGetZExtValue(self.ptr) + return self._ptr.getZExtValue() @property def s_ext_value(self): '''Obtain the sign extended value for an integer constant value.''' # Warning: assertion failure when value does not fit in 64 bits - return _core.LLVMConstIntGetSExtValue(self.ptr) + return self._ptr.getSExtValue() class ConstantFP(Constant): @@ -1295,290 +1255,349 @@ class ConstantPointerNull(Constant): class UndefValue(Constant): pass - class GlobalValue(Constant): - - def __init__(self, ptr): - Constant.__init__(self, ptr) - # Hang on to the module, don't let it die before we do. - # It is nice to have just a map of functions without - # retaining a ref to the owning module. - self._module_obj = self.module - - def _delete(self): - # Called in subclass delete() methods. - self._module_obj = None + _type_ = api.llvm.GlobalValue def _get_linkage(self): - return _core.LLVMGetLinkage(self.ptr) + return self._ptr.getLinkage() + def _set_linkage(self, value): - _core.LLVMSetLinkage(self.ptr, value) + self._ptr.setLinkage(value) + linkage = property(_get_linkage, _set_linkage) def _get_section(self): - return _core.LLVMGetSection(self.ptr) + return self._ptr.getSection() + def _set_section(self, value): - return _core.LLVMSetSection(self.ptr, value) + return self._ptr.setSection(value) + section = property(_get_section, _set_section) def _get_visibility(self): - return _core.LLVMGetVisibility(self.ptr) + return self._ptr.getVisibility() + def _set_visibility(self, value): - return _core.LLVMSetVisibility(self.ptr, value) + return self._ptr.setVisibility(value) + visibility = property(_get_visibility, _set_visibility) def _get_alignment(self): - return _core.LLVMGetAlignment(self.ptr) + return self._ptr.getAlignment() + def _set_alignment(self, value): - return _core.LLVMSetAlignment(self.ptr, value) + return self._ptr.setAlignment(value) + alignment = property(_get_alignment, _set_alignment) @property def is_declaration(self): - return _core.LLVMIsDeclaration(self.ptr) != 0 + return self._ptr.isDeclaration() @property def module(self): - return Module(_core.LLVMGetGlobalParent(self.ptr)) + return Module(self._ptr.getParent()) + + class GlobalVariable(GlobalValue): + _type_ = api.llvm.GlobalVariable @staticmethod def new(module, ty, name, addrspace=0): - check_is_module(module) - check_is_type(ty) - return _make_value(_core.LLVMAddGlobalInAddressSpace(module.ptr, ty.ptr, name, addrspace)) + linkage = api.llvm.GlobalValue.LinkageTypes + external_linkage = linkage.ExternalLinkage + tlmode = api.llvm.GlobalVariable.ThreadLocalMode + not_threadlocal = tlmode.NotThreadLocal + gv = api.llvm.GlobalVariable.new(module._ptr, + ty._ptr, + False, # is constant + external_linkage, + None, # initializer + name, + None, # insert before + not_threadlocal, + addrspace) + return _make_value(gv) @staticmethod def get(module, name): - check_is_module(module) - ptr = _core.LLVMGetNamedGlobal(module.ptr, name) - if not ptr: - raise llvm.LLVMException("no global named `%s`" % name) - return _make_value(ptr) + gv = _make_value(module._ptr.getNamedGlobal(name)) + if not gv: + llvm.LLVMException("no global named `%s`" % name) + return gv def delete(self): - self._delete() - _core.LLVMDeleteGlobal(self.ptr) - self.forget() - self.ptr = None + _ValueFactory.delete(self._ptr) + self._ptr.eraseFromParent() def _get_initializer(self): - if _core.LLVMHasInitializer(self.ptr): - return _make_value(_core.LLVMGetInitializer(self.ptr)) - else: + if not self._ptr.hasInitializer(): return None + return _make_value(self._ptr.getInitializer()) def _set_initializer(self, const): - check_is_constant(const) - _core.LLVMSetInitializer(self.ptr, const.ptr) + self._ptr.setInitializer(const._ptr) def _del_initializer(self): - check_is_constant(const) + self._ptr.setInitializer(None) initializer = property(_get_initializer, _set_initializer) def _get_is_global_constant(self): - return _core.LLVMIsGlobalConstant(self.ptr) + return self._ptr.isConstant() def _set_is_global_constant(self, value): - value = _to_int(value) - _core.LLVMSetGlobalConstant(self.ptr, value) + self._ptr.setConstant(value) - global_constant = \ - property(_get_is_global_constant, _set_is_global_constant) + global_constant = property(_get_is_global_constant, + _set_is_global_constant) def _get_thread_local(self): - return bool(_core.LLVMIsThreadLocal(self.ptr)) + return self._ptr.isThreadLocal() + def _set_thread_local(self, value): - value = _to_int(value) - _core.LLVMSetThreadLocal(self.ptr, value) + return self._ptr.setThreadLocal(value) thread_local = property(_get_thread_local, _set_thread_local) class Argument(Value): + _type_ = api.llvm.Argument def add_attribute(self, attr): - _core.LLVMAddAttribute(self.ptr, attr) + context = api.llvm.getGlobalContext() + attrbldr = api.llvm.AttrBuilder.new() + attrbldr.addAttribute(attr) + attrs = api.llvm.Attributes.get(context, attrbldr) + self._ptr.addAttr(attrs) def remove_attribute(self, attr): - _core.LLVMRemoveAttribute(self.ptr, attr) + context = api.llvm.getGlobalContext() + attrbldr = api.llvm.AttrBuilder.new() + attrbldr.addAttribute(attr) + attrs = api.llvm.Attributes.get(context, attrbldr) + self._ptr.removeAttr(attrs) def _set_alignment(self, align): - _core.LLVMSetParamAlignment(self.ptr, align) + context = api.llvm.getGlobalContext() + attrbldr = api.llvm.AttrBuilder.new() + attrbldr.addAlignmentAttr(align) + attrs = api.llvm.Attributes.get(context, attrbldr) + self._ptr.addAttr(attrs) def _get_alignment(self): - return _core.LLVMGetParamAlignment(self.ptr) - - alignment = \ - property(_get_alignment, _set_alignment) + return self._ptr.getParamAlignment() + alignment = property(_get_alignment, + _set_alignment) class Function(GlobalValue): + _type_ = api.llvm.Function @staticmethod def new(module, func_ty, name): - check_is_module(module) - check_is_type(func_ty) - return _make_value(_core.LLVMAddFunction(module.ptr, name, - func_ty.ptr)) + try: + fn = Function.get(module, name) + except llvm.LLVMException: + return Function.get_or_insert(module, func_ty, name) + else: + raise llvm.LLVMException("Duplicated function %s" % name) + @staticmethod def get_or_insert(module, func_ty, name): - check_is_module(module) - check_is_type(func_ty) - return _make_value(_core.LLVMModuleGetOrInsertFunction(module.ptr, - name, func_ty.ptr)) + constant = module._ptr.getOrInsertFunction(name, func_ty._ptr) + try: + fn = constant._downcast(api.llvm.Function) + except ValueError: + # bitcasted to function type + return _make_value(constant) + else: + return _make_value(fn) @staticmethod def get(module, name): - check_is_module(module) - ptr = _core.LLVMGetNamedFunction(module.ptr, name) - if not ptr: + fn = module._ptr.getFunction(name) + if fn is None: raise llvm.LLVMException("no function named `%s`" % name) - return _make_value(ptr) + else: + return _make_value(fn) @staticmethod def intrinsic(module, intrinsic_id, types): - check_is_module(module) - ptrs = unpack_types(types) - return _make_value( - _core.LLVMGetIntrinsic(module.ptr, intrinsic_id, ptrs)) + fn = api.llvm.Intrinsic.getDeclaration(module._ptr, + intrinsic_id, + llvm._extract_ptrs(types)) + return _make_value(fn) def delete(self): - self._delete() - _core.LLVMDeleteFunction(self.ptr) - self.forget() - self.ptr = None + _ValueFactory.delete(self._ptr) + self._ptr.eraseFromParent() @property def intrinsic_id(self): - return _core.LLVMGetIntrinsicID(self.ptr) + self._ptr.getIntrinsicID() + + def _get_cc(self): + return self._ptr.getCallingConv() + + def _set_cc(self, value): + self._ptr.setCallingConv(value) - def _get_cc(self): return _core.LLVMGetFunctionCallConv(self.ptr) - def _set_cc(self, value): _core.LLVMSetFunctionCallConv(self.ptr, value) calling_convention = property(_get_cc, _set_cc) - def _get_coll(self): return _core.LLVMGetGC(self.ptr) - def _set_coll(self, value): _core.LLVMSetGC(self.ptr, value) + def _get_coll(self): + return self._ptr.getGC() + + def _set_coll(self, value): + return self._ptr.setGC(value) + collector = property(_get_coll, _set_coll) # the nounwind attribute: - def _get_does_not_throw(self): return _core.LLVMGetDoesNotThrow(self.ptr) - def _set_does_not_throw(self,value): _core.LLVMSetDoesNotThrow(self.ptr, value) + def _get_does_not_throw(self): + return self._ptr.doesNotThrow() + + def _set_does_not_throw(self,value): + assert value + self._ptr.setDoesNotThrow() + does_not_throw = property(_get_does_not_throw, _set_does_not_throw) @property def args(self): - return _util.wrapiter(_core.LLVMGetFirstParam, - _core.LLVMGetNextParam, self.ptr, _make_value) + args = self._ptr.getArgumentList() + return list(map(_make_value, args)) @property def basic_block_count(self): - return _core.LLVMCountBasicBlocks(self.ptr) + return len(self.basic_blocks) @property def entry_basic_block(self): - if self.basic_block_count == 0: - return None - return _make_value(_core.LLVMGetEntryBasicBlock(self.ptr)) + assert self.basic_block_count + return _make_value(self._ptr.getEntryBlock()) def get_entry_basic_block(self): - """Deprecated, use entry_basic_block property.""" + "Deprecated. Use entry_basic_block instead" return self.entry_basic_block def append_basic_block(self, name): - return _make_value(_core.LLVMAppendBasicBlock(self.ptr, name)) + context = api.llvm.getGlobalContext() + bb = api.llvm.BasicBlock.Create(context, name, self._ptr, None) + return _make_value(bb) @property def basic_blocks(self): - return _util.wrapiter(_core.LLVMGetFirstBasicBlock, - _core.LLVMGetNextBasicBlock, self.ptr, _make_value) - + return list(map(_make_value, self._ptr.getBasicBlockList())) + def viewCFG(self): - return _core.LLVMViewFunctionCFG(self.ptr) + return self._ptr.viewCFG() def add_attribute(self, attr): - _core.LLVMAddFunctionAttr(self.ptr, attr) + self._ptr.addFnAttr(attr) def remove_attribute(self, attr): - _core.LLVMRemoveFunctionAttr(self.ptr, attr) + context = api.llvm.getGlobalContext() + attrbldr = api.llvm.AttrBuilder.new() + attrbldr.addAttribute(attr) + attrs = api.llvm.Attributes.get(context, attrbldr) + self._ptr.removeFnAttr(attrs) def viewCFGOnly(self): - return _core.LLVMViewFunctionCFGOnly(self.ptr) + return self._ptr.viewCFGOnly() def verify(self): # Although we're just asking LLVM to return the success or # failure, it appears to print result to stderr and abort. - + # Note: LLVM has a bug in preverifier that will always abort # the process upon failure. - return _core.LLVMVerifyFunction(self.ptr) != 0 + actions = api.llvm.VerifierFailureAction + broken = api.llvm.verifyFunction(self._ptr, + actions.ReturnStatusAction) + if broken: + # If broken, then re-run to print the message + api.llvm.verifyFunction(self._ptr, actions.PrintMessageAction) + raise llvm.LLVMException("Function %s failed verification" % + self.name) #===----------------------------------------------------------------------=== # InlineAsm #===----------------------------------------------------------------------=== class InlineAsm(Value): + _type_ = api.llvm.InlineAsm + @staticmethod def get(functype, asm, constrains, side_effect=False, - align_stack=False, dialect=0): - assert dialect == 0, "LLVM 3.1 does not implement dialect selection" - check_is_type(functype) - pycap = _core.LLVMGetFunctionFromInlineAsm(functype.ptr, asm, - constrains, int(side_effect), - int(align_stack), dialect) - return _make_value(pycap) + align_stack=False, dialect=api.llvm.InlineAsm.AsmDialect.AD_ATT): + ilasm = api.llvm.InlineAsm.get(functype._ptr, asm, constrains, + side_effect, align_stack, dialect) + return _make_value(ilasm) #===----------------------------------------------------------------------=== # MetaData #===----------------------------------------------------------------------=== class MetaData(Value): + _type_ = api.llvm.MDNode + @staticmethod def get(module, values): ''' values -- must be an iterable of Constant or None. None is treated as "null". ''' - vs = unpack_values_or_none(values) - ptr = _core.LLVMMetaDataGet(module.ptr, vs) - return MetaData(ptr) + context = api.llvm.getGlobalContext() + ptr = api.llvm.MDNode.get(context, llvm._extract_ptrs(values)) + return _make_value(ptr) @staticmethod def get_named_operands(module, name): - lst = _core.LLVMGetNamedMetadataOperands(module.ptr, name) - return [MetaData(ptr) for ptr in lst] + namedmd = module.get_named_metadata(name) + if not namedmd: + return [] + return [_make_value(namedmd._ptr.getOperand(i)) + for i in range(namedmd._ptr.getNumOperands())] @staticmethod def add_named_operand(module, name, operand): - _core.LLVMAddNamedMetadataOperand(module.ptr, name, operand.ptr) + namedmd = module.get_or_insert_named_metadata(name)._ptr + namedmd.addOperand(operand._ptr) @property def operand_count(self): - return _core.LLVMMetaDataGetNumOperands(self.ptr) + return self._ptr.getNumOperands() @property def operands(self): """Yields operands of this metadata.""" - return [self._get_operand(i) for i in range(self.operand_count)] - - def _get_operand(self, i): - val = _core.LLVMMetaDataGetOperand(self.ptr, i) - if val: # metadata operands can be None - return _make_value(val) + res = [] + for i in range(self.operand_count): + op = self._ptr.getOperand(i) + if op is None: + res.append(None) + else: + res.append(_make_value(op)) + return res class MetaDataString(Value): + _type_ = api.llvm.MDString + @staticmethod def get(module, s): - ptr = _core.LLVMMetaDataStringGet(module.ptr, s) - return MetaDataString(ptr) + context = api.llvm.getGlobalContext() + ptr = api.llvm.MDString.get(context, s) + return _make_value(ptr) @property def string(self): '''Same as MDString::getString''' - return self.name + return self._ptr.getString() + + +class NamedMetaData(llvm.Wrapper): -class NamedMetaData(llvm.Cacheable): @staticmethod def get_or_insert(mod, name): return mod.get_or_insert_named_metadata(name) @@ -1587,467 +1606,470 @@ class NamedMetaData(llvm.Cacheable): def get(mod, name): return mod.get_named_metadata(name) - def __init__(self, ptr): - self.ptr = ptr - def delete(self): - _core.LLVMEraseNamedMetaData(self.ptr) - + _ValueFactory.delete(self._ptr) + self._ptr.eraseFromParent() + @property def name(self): - return _core.LLVMNamedMetaDataGetName(self.ptr) + return self._ptr.getName() def __str__(self): - return _core.LLVMDumpNamedMDToString(self.ptr) + return str(self._ptr) def add(self, operand): - _core.LLVMNamedMetaDataAddOperand(self.ptr, operand.ptr) + self._ptr.addOperand(operand._ptr) + #===----------------------------------------------------------------------=== # Instruction #===----------------------------------------------------------------------=== class Instruction(User): + _type_ = api.llvm.Instruction @property def basic_block(self): - return _make_value(_core.LLVMGetInstructionParent(self.ptr)) + return _make_value(self._ptr.getParent()) @property def is_terminator(self): - return _core.LLVMInstIsTerminator(self.ptr) != 0 + return self._ptr.isTerminator() @property def is_binary_op(self): - return _core.LLVMInstIsBinaryOp(self.ptr) != 0 - + return self._ptr.isBinaryOp() + @property def is_shift(self): - return _core.LLVMInstIsShift(self.ptr) != 0 + return self._ptr.isShift() @property def is_cast(self): - return _core.LLVMInstIsCast(self.ptr) != 0 + return self._ptr.isCast() @property def is_logical_shift(self): - return _core.LLVMInstIsLogicalShift(self.ptr) != 0 + return self._ptr.isLogicalShift() @property def is_arithmetic_shift(self): - return _core.LLVMInstIsArithmeticShift(self.ptr) != 0 + return self._ptr.isArithmeticShift() @property def is_associative(self): - return _core.LLVMInstIsAssociative(self.ptr) != 0 + return self._ptr.isAssociative() @property def is_commutative(self): - return _core.LLVMInstIsCommutative(self.ptr) != 0 - + return self._ptr.isCommutative() + @property def is_volatile(self): """True if this is a volatile load or store.""" - return _core.LLVMInstIsVolatile(self.ptr) != 0 + if api.llvm.LoadInst.classof(self._ptr): + return self._ptr._downcast(api.llvm.LoadInst).isVolatile() + elif api.llvm.StoreInst.classof(self._ptr): + return self._ptr._downcast(api.llvm.StoreInst).isVolatile() + else: + return False def set_volatile(self, flag): - return _core.LLVMSetVolatile(self.ptr, int(bool(flag))) + if api.llvm.LoadInst.classof(self._ptr): + return self._ptr._downcast(api.llvm.LoadInst).setVolatile(flag) + elif api.llvm.StoreInst.classof(self._ptr): + return self._ptr._downcast(api.llvm.StoreInst).setVolatile(flag) + else: + return False def set_metadata(self, kind, metadata): - return _core.LLVMInstSetMetaData(self.ptr, kind, metadata.ptr) + self._ptr.setMetadata(kind, metadata._ptr) @property def opcode(self): - return _core.LLVMInstGetOpcode(self.ptr) + return self._ptr.getOpcode() @property def opcode_name(self): - return _core.LLVMInstGetOpcodeName(self.ptr) + return self._ptr.getOpcodeName() def erase_from_parent(self): - return _core.LLVMInstructionEraseFromParent(self.ptr) + return self._ptr.eraseFromParent() + class CallOrInvokeInstruction(Instruction): + _type_ = api.llvm.CallInst, api.llvm.InvokeInst + + def _get_cc(self): + return self._ptr.getCallingConv() + + def _set_cc(self, value): + return self._ptr.setCallingConv(value) - def _get_cc(self): return _core.LLVMGetInstructionCallConv(self.ptr) - def _set_cc(self, value): _core.LLVMSetInstructionCallConv(self.ptr, value) calling_convention = property(_get_cc, _set_cc) def add_parameter_attribute(self, idx, attr): - _core.LLVMAddInstrAttribute(self.ptr, idx, attr) + context = api.llvm.getGlobalContext() + attrbldr = api.llvm.AttrBuilder.new() + attrbldr.addAttribute(attr) + attrs = api.llvm.Attributes.get(context, attrbldr) + self._ptr.addAttribute(idx, attrs) def remove_parameter_attribute(self, idx, attr): - _core.LLVMRemoveInstrAttribute(self.ptr, idx, attr) + context = api.llvm.getGlobalContext() + attrbldr = api.llvm.AttrBuilder.new() + attrbldr.addAttribute(attr) + attrs = api.llvm.Attributes.get(context, attrbldr) + self._ptr.removeAttribute(idx, attrs) def set_parameter_alignment(self, idx, align): - _core.LLVMSetInstrParamAlignment(self.ptr, idx, align) + context = api.llvm.getGlobalContext() + attrbldr = api.llvm.AttrBuilder.new() + attrbldr.addAlignmentAttr(align) + attrs = api.llvm.Attributes.get(context, attrbldr) + self._ptr.addAttribute(idx, attrs) def _get_called_function(self): - function = _core.LLVMInstGetCalledFunction(self.ptr) + function = self._ptr.getCalledFunction() if function: # Return value can be None on indirect call/invoke return _make_value(function) def _set_called_function(self, function): - _core.LLVMInstSetCalledFunction(self.ptr, function.ptr) + self._ptr.setCalledFunction(function._ptr) called_function = property(_get_called_function, _set_called_function) - # tail call is valid only for 'call', not 'invoke' - # disabled for now - #def _get_tc(self): return _core.LLVMIsTailCall(self.ptr) - #def _set_tc(self, value): _core.LLVMSetTailCall(self.ptr, value) - #tail_call = property(_get_tc, _set_tc) - class PHINode(Instruction): + _type_ = api.llvm.PHINode @property def incoming_count(self): - return _core.LLVMCountIncoming(self.ptr) + return self._ptr.getNumIncomingValues() def add_incoming(self, value, block): - check_is_value(value) - check_is_basic_block(block) - _core.LLVMAddIncoming1(self.ptr, value.ptr, block.ptr) + self._ptr.addIncoming(value._ptr, block._ptr) def get_incoming_value(self, idx): - return _make_value(_core.LLVMGetIncomingValue(self.ptr, idx)) + return _make_value(self._ptr.getIncomingValue(idx)) def get_incoming_block(self, idx): - return _make_value(_core.LLVMGetIncomingBlock(self.ptr, idx)) + return _make_value(self._ptr.getIncomingBlock(idx)) class SwitchInstruction(Instruction): def add_case(self, const, bblk): - check_is_constant(const) # and has to be an int too - check_is_basic_block(bblk) - _core.LLVMAddCase(self.ptr, const.ptr, bblk.ptr) + self._ptr.addCase(const._ptr, bblk._ptr) class CompareInstruction(Instruction): @property def predicate(self): - return _core.LLVMCmpInstGetPredicate(self.ptr) - - + return self._ptr.getPredicate() #===----------------------------------------------------------------------=== # Basic block #===----------------------------------------------------------------------=== class BasicBlock(Value): + _type_ = api.llvm.BasicBlock def insert_before(self, name): - return _make_value(_core.LLVMInsertBasicBlock(self.ptr, name)) + context = api.llvm.getGlobalContext() + ptr = api.llvm.BasicBlock.Create(context, name, self.function._ptr, + self._ptr) + return _make_value(ptr) def delete(self): - _core.LLVMDeleteBasicBlock(self.ptr) - self.forget() - self.ptr = None + _ValueFactory.delete(self._ptr) + self._ptr.eraseFromParent() @property def function(self): - func_ptr = _core.LLVMGetBasicBlockParent(self.ptr) - return _make_value(func_ptr) + return _make_value(self._ptr.getParent()) @property def instructions(self): - return _util.wrapiter(_core.LLVMGetFirstInstruction, - _core.LLVMGetNextInstruction, self.ptr, _make_value) - + return list(map(_make_value, self._ptr.getInstList())) #===----------------------------------------------------------------------=== # Value factory method #===----------------------------------------------------------------------=== -# value ID -> class map -__class_for_valueid = { - VALUE_ARGUMENT : Argument, - VALUE_BASIC_BLOCK : BasicBlock, - VALUE_FUNCTION : Function, - VALUE_GLOBAL_ALIAS : GlobalValue, - VALUE_GLOBAL_VARIABLE : GlobalVariable, - VALUE_UNDEF_VALUE : UndefValue, - VALUE_CONSTANT_EXPR : ConstantExpr, - VALUE_CONSTANT_AGGREGATE_ZERO : ConstantAggregateZero, - VALUE_CONSTANT_DATA_ARRAY : ConstantDataArray, - VALUE_CONSTANT_DATA_VECTOR : ConstantDataVector, - VALUE_CONSTANT_INT : ConstantInt, - VALUE_CONSTANT_FP : ConstantFP, - VALUE_CONSTANT_ARRAY : ConstantArray, - VALUE_CONSTANT_STRUCT : ConstantStruct, - VALUE_CONSTANT_VECTOR : ConstantVector, - VALUE_CONSTANT_POINTER_NULL : ConstantPointerNull, - VALUE_MD_NODE : MetaData, - VALUE_MD_STRING : MetaDataString, - VALUE_INLINE_ASM : InlineAsm, - VALUE_INSTRUCTION + OPCODE_PHI : PHINode, - VALUE_INSTRUCTION + OPCODE_CALL : CallOrInvokeInstruction, - VALUE_INSTRUCTION + OPCODE_INVOKE : CallOrInvokeInstruction, - VALUE_INSTRUCTION + OPCODE_SWITCH : SwitchInstruction, - VALUE_INSTRUCTION + OPCODE_ICMP : CompareInstruction, - VALUE_INSTRUCTION + OPCODE_FCMP : CompareInstruction -} + +class _ValueFactory(object): + cache = weakref.WeakValueDictionary() + + # value ID -> class map + class_for_valueid = { + VALUE_ARGUMENT : Argument, + VALUE_BASIC_BLOCK : BasicBlock, + VALUE_FUNCTION : Function, + VALUE_GLOBAL_ALIAS : GlobalValue, + VALUE_GLOBAL_VARIABLE : GlobalVariable, + VALUE_UNDEF_VALUE : UndefValue, + VALUE_CONSTANT_EXPR : ConstantExpr, + VALUE_CONSTANT_AGGREGATE_ZERO : ConstantAggregateZero, + VALUE_CONSTANT_DATA_ARRAY : ConstantDataArray, + VALUE_CONSTANT_DATA_VECTOR : ConstantDataVector, + VALUE_CONSTANT_INT : ConstantInt, + VALUE_CONSTANT_FP : ConstantFP, + VALUE_CONSTANT_ARRAY : ConstantArray, + VALUE_CONSTANT_STRUCT : ConstantStruct, + VALUE_CONSTANT_VECTOR : ConstantVector, + VALUE_CONSTANT_POINTER_NULL : ConstantPointerNull, + VALUE_MD_NODE : MetaData, + VALUE_MD_STRING : MetaDataString, + VALUE_INLINE_ASM : InlineAsm, + VALUE_INSTRUCTION + OPCODE_PHI : PHINode, + VALUE_INSTRUCTION + OPCODE_CALL : CallOrInvokeInstruction, + VALUE_INSTRUCTION + OPCODE_INVOKE : CallOrInvokeInstruction, + VALUE_INSTRUCTION + OPCODE_SWITCH : SwitchInstruction, + VALUE_INSTRUCTION + OPCODE_ICMP : CompareInstruction, + VALUE_INSTRUCTION + OPCODE_FCMP : CompareInstruction + } + + @classmethod + def build(cls, ptr): + # try to look in the cache + addr = ptr._capsule.pointer + id = ptr.getValueID() + key = id, addr + try: + obj = cls.cache[key] + return obj + except KeyError: + pass + # find class by value id + ctorcls = cls.class_for_valueid.get(id) + if not ctorcls: + if id > VALUE_INSTRUCTION: # "generic" instruction + ctorcls = Instruction + else: # "generic" value + ctorcls = Value + # cache the obj + obj = ctorcls(_ValueFactory, ptr) + cls.cache[key] = obj + return obj + + @classmethod + def delete(cls, ptr): + del cls.cache[(ptr.getValueID(), ptr._capsule.pointer)] def _make_value(ptr): - kind = _core.LLVMValueGetID(ptr) - # based on kind, create one of the Value subclasses - class_obj = __class_for_valueid.get(kind) - if class_obj: - return class_obj(ptr) - elif kind > VALUE_INSTRUCTION: - # "generic" instruction - return Instruction(ptr) - else: - # "generic" value - return Value(ptr) - + return _ValueFactory.build(ptr) #===----------------------------------------------------------------------=== # Builder #===----------------------------------------------------------------------=== -class Builder(object): +_atomic_orderings = { + 'unordered' : api.llvm.AtomicOrdering.Unordered, + 'monotonic' : api.llvm.AtomicOrdering.Monotonic, + 'acquire' : api.llvm.AtomicOrdering.Acquire, + 'release' : api.llvm.AtomicOrdering.Release, + 'acq_rel' : api.llvm.AtomicOrdering.AcquireRelease, + 'seq_cst' : api.llvm.AtomicOrdering.SequentiallyConsistent +} + +class Builder(llvm.Wrapper): @staticmethod def new(basic_block): - check_is_basic_block(basic_block) - b = Builder(_core.LLVMCreateBuilder()) - b.position_at_end(basic_block) - return b - - def __init__(self, ptr): - self.ptr = ptr - - def __del__(self): - _core.LLVMDisposeBuilder(self.ptr) + context = api.llvm.getGlobalContext() + ptr = api.llvm.IRBuilder.new(context) + ptr.SetInsertPoint(basic_block._ptr) + return Builder(ptr) def position_at_beginning(self, bblk): """Position the builder at the beginning of the given block. Next instruction inserted will be first one in the block.""" - check_is_basic_block(bblk) - # Avoids using "blk.instructions", which will fetch all the - # instructions into a list. Don't try this at home, though. - inst_ptr = _core.LLVMGetFirstInstruction(bblk.ptr) - if inst_ptr: - # Issue #10: inst_ptr can be None if b/b has no insts. - inst = _make_value(inst_ptr) - self.position_before(inst) + + # Instruction list won't be long anyway, + # Does not matter much to build a list of all instructions + instrs = bblk.instructions + if instrs: + self.position_before(instrs[0]) + else: + self.position_at_end(bblk) def position_at_end(self, bblk): """Position the builder at the end of the given block. Next instruction inserted will be last one in the block.""" - _core.LLVMPositionBuilderAtEnd(self.ptr, bblk.ptr) + + self._ptr.SetInsertPoint(bblk._ptr) def position_before(self, instr): """Position the builder before the given instruction. - The instruction can belong to a basic block other than the - current one.""" - _core.LLVMPositionBuilderBefore(self.ptr, instr.ptr) - - @property - def block(self): - """Deprecated, use basic_block property instead.""" - return _make_value(_core.LLVMGetInsertBlock(self.ptr)) + The instruction can belong to a basic block other than the + current one.""" + self._ptr.SetInsertPoint(instr._ptr) @property def basic_block(self): """The basic block where the builder is positioned.""" - return _make_value(_core.LLVMGetInsertBlock(self.ptr)) + return _make_value(self._ptr.GetInsertBlock()) # terminator instructions + def _guard_terminators(self): + if __debug__: + import warnings + for instr in self.basic_block.instructions: + if instr.is_terminator: + warnings.warn("BasicBlock can only have one terminator") def ret_void(self): - return _make_value(_core.LLVMBuildRetVoid(self.ptr)) - + self._guard_terminators() + return _make_value(self._ptr.CreateRetVoid()) + def ret(self, value): - check_is_value(value) - return _make_value(_core.LLVMBuildRet(self.ptr, value.ptr)) + self._guard_terminators() + return _make_value(self._ptr.CreateRet(value._ptr)) def ret_many(self, values): - vs = unpack_values(values) - return _make_value(_core.LLVMBuildRetMultiple(self.ptr, vs)) + self._guard_terminators() + values = llvm._extract_ptrs(values) + return _make_value(self._ptr.CreateAggregateRet(values, len(values))) def branch(self, bblk): - check_is_basic_block(bblk) - if __debug__: - for instr in self.basic_block.instructions: - assert not instr.is_terminator, "BasicBlock can only have one terminator" - return _make_value(_core.LLVMBuildBr(self.ptr, bblk.ptr)) + self._guard_terminators() + return _make_value(self._ptr.CreateBr(bblk._ptr)) def cbranch(self, if_value, then_blk, else_blk): - check_is_value(if_value) - check_is_basic_block(then_blk) - check_is_basic_block(else_blk) - return _make_value( - _core.LLVMBuildCondBr(self.ptr, - if_value.ptr, then_blk.ptr, else_blk.ptr)) + self._guard_terminators() + return _make_value(self._ptr.CreateCondBr(if_value._ptr, + then_blk._ptr, + else_blk._ptr)) def switch(self, value, else_blk, n=10): - check_is_value(value) # value has to be of any 'int' type - check_is_basic_block(else_blk) - return _make_value( - _core.LLVMBuildSwitch(self.ptr, value.ptr, else_blk.ptr, n)) + self._guard_terminators() + return _make_value(self._ptr.CreateSwitch(value._ptr, + else_blk._ptr, + n)) def invoke(self, func, args, then_blk, catch_blk, name=""): - check_is_callable(func) - check_is_basic_block(then_blk) - check_is_basic_block(catch_blk) - args2 = unpack_values(args) - return _make_value( - _core.LLVMBuildInvoke(self.ptr, func.ptr, args2, - then_blk.ptr, catch_blk.ptr, name)) + self._guard_terminators() + return _make_value(self._ptr.CreateInvoke(func._ptr, + then_blk._ptr, + catch_blk._ptr, + llvm._extract_ptrs(args))) def unreachable(self): - return _make_value(_core.LLVMBuildUnreachable(self.ptr)) + self._guard_terminators() + return _make_value(self._ptr.CreateUnreachable()) # arithmethic, bitwise and logical def add(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value(_core.LLVMBuildAdd(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateAdd(lhs._ptr, rhs._ptr, name)) def fadd(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value(_core.LLVMBuildFAdd(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateFAdd(lhs._ptr, rhs._ptr, name)) def sub(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value(_core.LLVMBuildSub(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateSub(lhs._ptr, rhs._ptr, name)) def fsub(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value(_core.LLVMBuildFSub(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateFSub(lhs._ptr, rhs._ptr, name)) def mul(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value(_core.LLVMBuildMul(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateMul(lhs._ptr, rhs._ptr, name)) def fmul(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value(_core.LLVMBuildFMul(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateFMul(lhs._ptr, rhs._ptr, name)) def udiv(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildUDiv(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateUDiv(lhs._ptr, rhs._ptr, name)) def sdiv(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildSDiv(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateSDiv(lhs._ptr, rhs._ptr, name)) def fdiv(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildFDiv(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateFDiv(lhs._ptr, rhs._ptr, name)) def urem(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildURem(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateURem(lhs._ptr, rhs._ptr, name)) def srem(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildSRem(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateSRem(lhs._ptr, rhs._ptr, name)) def frem(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildFRem(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateFRem(lhs._ptr, rhs._ptr, name)) def shl(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildShl(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateShl(lhs._ptr, rhs._ptr, name)) def lshr(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildLShr(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateLShr(lhs._ptr, rhs._ptr, name)) def ashr(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildAShr(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateAShr(lhs._ptr, rhs._ptr, name)) def and_(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildAnd(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateAnd(lhs._ptr, rhs._ptr, name)) def or_(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildOr(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateOr(lhs._ptr, rhs._ptr, name)) def xor(self, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildXor(self.ptr, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateXor(lhs._ptr, rhs._ptr, name)) def neg(self, val, name=""): - check_is_value(val) - return _make_value(_core.LLVMBuildNeg(self.ptr, val.ptr, name)) + return _make_value(self._ptr.CreateNeg(val._ptr, name)) def not_(self, val, name=""): - check_is_value(val) - return _make_value(_core.LLVMBuildNot(self.ptr, val.ptr, name)) + return _make_value(self._ptr.CreateNot(val._ptr, name)) # memory def malloc(self, ty, name=""): - check_is_type(ty) - return _make_value(_core.LLVMBuildMalloc(self.ptr, ty.ptr, name)) - + context = api.llvm.getGlobalContext() + allocsz = api.llvm.ConstantExpr.getSizeOf(ty._ptr) + ity = allocsz.getType() + malloc = api.llvm.CallInst.CreateMalloc(self.basic_block._ptr, + ity, + ty._ptr, + allocsz, + None, + None, + "") + inst = self._ptr.Insert(malloc, name) + return _make_value(inst) + def malloc_array(self, ty, size, name=""): - check_is_type(ty) - check_is_value(size) - return _make_value( - _core.LLVMBuildArrayMalloc(self.ptr, ty.ptr, size.ptr, name)) + context = api.llvm.getGlobalContext() + allocsz = api.llvm.ConstantExpr.getSizeOf(ty._ptr) + ity = allocsz.getType() + malloc = api.llvm.CallInst.CreateMalloc(self.basic_block._ptr, + ity, + ty._ptr, + allocsz, + size._ptr, + None, + "") + inst = self._ptr.Insert(malloc, name) + return _make_value(inst) def alloca(self, ty, name=""): - check_is_type(ty) - return _make_value(_core.LLVMBuildAlloca(self.ptr, ty.ptr, name)) + intty = Type.int() + return _make_value(self._ptr.CreateAlloca(ty._ptr, None, name)) def alloca_array(self, ty, size, name=""): - check_is_type(ty) - check_is_value(size) - return _make_value( - _core.LLVMBuildArrayAlloca(self.ptr, ty.ptr, size.ptr, name)) + return _make_value(self._ptr.CreateAlloca(ty._ptr, size._ptr, name)) def free(self, ptr): - check_is_value(ptr) - return _make_value(_core.LLVMBuildFree(self.ptr, ptr.ptr)) + free = api.llvm.CallInst.CreateFree(ptr._ptr, self.basic_block._ptr) + inst = self._ptr.Insert(free) + return _make_value(inst) def load(self, ptr, name="", align=0, volatile=False, invariant=False): - check_is_value(ptr) - inst = _make_value(_core.LLVMBuildLoad(self.ptr, ptr.ptr, name)) + inst = _make_value(self._ptr.CreateLoad(ptr._ptr, name)) if align: - _core.LLVMLdSetAlignment(inst.ptr, align) + inst._ptr.setAlignment(align) if volatile: inst.set_volatile(volatile) if invariant: @@ -2057,202 +2079,136 @@ class Builder(object): return inst def store(self, value, ptr, align=0, volatile=False): - check_is_value(value) - check_is_value(ptr) - inst = _make_value(_core.LLVMBuildStore(self.ptr, value.ptr, ptr.ptr)) + inst = _make_value(self._ptr.CreateStore(value._ptr, ptr._ptr)) if align: - _core.LLVMStSetAlignment(inst.ptr, align) + inst._ptr.setAlignment(align) if volatile: inst.set_volatile(volatile) return inst def gep(self, ptr, indices, name="", inbounds=False): - check_is_value(ptr) - index_ptrs = unpack_values(indices) if inbounds: - ret = _core.LLVMBuildInBoundsGEP(self.ptr, ptr.ptr, index_ptrs, name) + ret = self._ptr.CreateInBoundsGEP(ptr._ptr, + llvm._extract_ptrs(indices), + name) else: - ret = _core.LLVMBuildGEP(self.ptr, ptr.ptr, index_ptrs, name) + ret = self._ptr.CreateGEP(ptr._ptr, + llvm._extract_ptrs(indices), + name) return _make_value(ret) # casts and extensions def trunc(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildTrunc(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateTrunc(value._ptr, dest_ty._ptr, name)) def zext(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildZExt(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateZExt(value._ptr, dest_ty._ptr, name)) def sext(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildSExt(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateSExt(value._ptr, dest_ty._ptr, name)) def fptoui(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildFPToUI(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateFPToUI(value._ptr, dest_ty._ptr, name)) def fptosi(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildFPToSI(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateFPToSI(value._ptr, dest_ty._ptr, name)) def uitofp(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildUIToFP(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateUIToFP(value._ptr, dest_ty._ptr, name)) def sitofp(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildSIToFP(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateSIToFP(value._ptr, dest_ty._ptr, name)) def fptrunc(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildFPTrunc(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateFPTrunc(value._ptr, dest_ty._ptr, name)) def fpext(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildFPExt(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateFPExt(value._ptr, dest_ty._ptr, name)) def ptrtoint(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildPtrToInt(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreatePtrToInt(value._ptr, dest_ty._ptr, name)) def inttoptr(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildIntToPtr(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateIntToPtr(value._ptr, dest_ty._ptr, name)) def bitcast(self, value, dest_ty, name=""): - check_is_value(value) - check_is_type(dest_ty) - return _make_value( - _core.LLVMBuildBitCast(self.ptr, value.ptr, dest_ty.ptr, name)) + return _make_value(self._ptr.CreateBitCast(value._ptr, dest_ty._ptr, name)) # comparisons def icmp(self, ipred, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateICmp(ipred, lhs._ptr, rhs._ptr, name)) def fcmp(self, rpred, lhs, rhs, name=""): - check_is_value(lhs) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name)) + return _make_value(self._ptr.CreateFCmp(rpred, lhs._ptr, rhs._ptr, name)) # misc def extract_value(self, retval, idx, name=""): - check_is_value(retval) - return _make_value( - _core.LLVMBuildGetResult(self.ptr, retval.ptr, idx, name)) + return _make_value(self._ptr.CreateExtractValue(retval._ptr, [idx], name)) # obsolete synonym for extract_value getresult = extract_value def insert_value(self, retval, rhs, idx, name=""): - check_is_value(retval) - check_is_value(rhs) - return _make_value( - _core.LLVMBuildInsertValue(self.ptr, retval.ptr, rhs.ptr, idx, - name)) + return _make_value(self._ptr.CreateInsertValue(retval._ptr, + rhs._ptr, + [idx], + name)) def phi(self, ty, name=""): - check_is_type(ty) - return _make_value(_core.LLVMBuildPhi(self.ptr, ty.ptr, name)) + return _make_value(self._ptr.CreatePHI(ty._ptr, 2, name)) def call(self, fn, args, name=""): - check_is_callable(fn) - err_template = 'Argument type mismatch: expected %s but got %s' + for i, (t, v) in enumerate(zip(fn.type.pointee.args, args)): if t != v.type: raise TypeError(err_template % (t, v.type)) - arg_ptrs = unpack_values(args) - - if (isinstance(fn, Function) and \ - fn.module is not self.basic_block.function.module): - raise ValueError("Intermodule function call") - return _make_value( - _core.LLVMBuildCall(self.ptr, fn.ptr, arg_ptrs, name)) + arg_ptrs = llvm._extract_ptrs(args) + return _make_value(self._ptr.CreateCall(fn._ptr, arg_ptrs, name)) def select(self, cond, then_value, else_value, name=""): - check_is_value(cond) - check_is_value(then_value) - check_is_value(else_value) - return _make_value( - _core.LLVMBuildSelect(self.ptr, cond.ptr, - then_value.ptr, else_value.ptr, name)) + return _make_value(self._ptr.CreateSelect(cond._ptr, then_value._ptr, + else_value._ptr, name)) def vaarg(self, list_val, ty, name=""): - check_is_value(list_val) - check_is_type(ty) - return _make_value( - _core.LLVMBuildVAArg(self.ptr, list_val.ptr, ty.ptr, name)) + return _make_value(self._ptr.CreateVAArg(list_val._ptr, ty._ptr, name)) def extract_element(self, vec_val, idx_val, name=""): - check_is_value(vec_val) - check_is_value(idx_val) - return _make_value( - _core.LLVMBuildExtractElement(self.ptr, vec_val.ptr, - idx_val.ptr, name)) + return _make_value(self._ptr.CreateExtractElement(vec_val._ptr, + idx_val._ptr, + name)) + def insert_element(self, vec_val, elt_val, idx_val, name=""): - check_is_value(vec_val) - check_is_value(elt_val) - check_is_value(idx_val) - return _make_value( - _core.LLVMBuildInsertElement(self.ptr, vec_val.ptr, - elt_val.ptr, idx_val.ptr, name)) + return _make_value(self._ptr.CreateInsertElement(vec_val._ptr, + elt_val._ptr, + idx_val._ptr, + name)) def shuffle_vector(self, vecA, vecB, mask, name=""): - check_is_value(vecA) - check_is_value(vecB) - check_is_value(mask) - return _make_value( - _core.LLVMBuildShuffleVector(self.ptr, - vecA.ptr, vecB.ptr, mask.ptr, name)) - + return _make_value(self._ptr.CreateShuffleVector(vecA._ptr, + vecB._ptr, + mask._ptr, + name)) # atomics def atomic_cmpxchg(self, ptr, old, new, ordering, crossthread=True): - check_is_value(ptr) - check_is_value(old) - check_is_value(new) - inst = _core.LLVMBuildAtomicCmpXchg(self.ptr, ptr.ptr, old.ptr, new.ptr, - ordering.lower(), - int(bool(crossthread))) - return _make_value(inst) + return _make_value(self._ptr.CreateAtomicCmpXchg(ptr._ptr, + old._ptr, + new._ptr, + _atomic_orderings[ordering], + _sync_scope(crossthread))) def atomic_rmw(self, op, ptr, val, ordering, crossthread=True): - check_is_value(ptr) - check_is_value(val) - inst = _core.LLVMBuildAtomicRMW(self.ptr, op.lower(), ptr.ptr, val.ptr, - ordering.lower(), int(bool(crossthread))) - return _make_value(inst) + op_dict = dict((k.lower(), v) + for k, v in vars(api.llvm.AtomicRMWInst.BinOp).items()) + op = op_dict[op] + return _make_value(self._ptr.CreateAtomicRMW(op, ptr._ptr, val._ptr, + _atomic_orderings[ordering], + _sync_scope(crossthread))) def atomic_xchg(self, *args, **kwargs): return self.atomic_rmw('xchg', *args, **kwargs) @@ -2286,70 +2242,32 @@ class Builder(object): def atomic_umin(self, *args, **kwargs): return self.atomic_rmw('umin', *args, **kwargs) - - + def atomic_load(self, ptr, ordering, align=1, crossthread=True, volatile=False, name=""): - check_is_value(ptr) - inst = _make_value(_core.LLVMBuildAtomicLoad( - self.ptr, ptr.ptr, int(align), - ordering.lower(), int(bool(crossthread)))) - if volatile: - inst.set_volatile(volatile) - if inst: - inst.name = name + inst = self.load(ptr, align=align, volatile=volatile, name=name) + inst._ptr.setAtomic(_atomic_orderings[ordering], + _sync_scope(crossthread)) return inst def atomic_store(self, value, ptr, ordering, align=1, crossthread=True, volatile=False): - check_is_value(value) - check_is_value(ptr) - inst = _make_value(_core.LLVMBuildAtomicStore( - self.ptr, ptr.ptr, value.ptr, int(align), - ordering.lower(), int(bool(crossthread)))) - if volatile: - inst.set_volatile(volatile) + inst = self.store(value, ptr, align=align, volatile=volatile) + inst._ptr.setAtomic(_atomic_orderings[ordering], + _sync_scope(crossthread)) return inst + def fence(self, ordering, crossthread=True): - inst = _make_value(_core.LLVMBuildFence(self.ptr, ordering.lower(), - int(bool(crossthread)))) - return inst + return _make_value(self._ptr.CreateFence(_atomic_orderings[ordering], + _sync_scope(crossthread))) -#===----------------------------------------------------------------------=== -# Memory buffer -#===----------------------------------------------------------------------=== - -class MemoryBuffer(object): - - @staticmethod - def from_file(fname): - ret = _core.LLVMCreateMemoryBufferWithContentsOfFile(fname) - if isinstance(ret, str): - return (None, ret) - else: - obj = MemoryBuffer(ret) - return (obj, "") - - @staticmethod - def from_stdin(): - ret = _core.LLVMCreateMemoryBufferWithSTDIN() - if isinstance(ret, str): - return (None, ret) - else: - obj = MemoryBuffer(ret) - return (obj, "") - - def __init__(self, ptr): - self.ptr = ptr - - def __del__(self): - _core.LLVMDisposeMemoryBuffer(self.ptr) - - -#===----------------------------------------------------------------------=== -# Misc -#===----------------------------------------------------------------------=== +def _sync_scope(crossthread): + if crossthread: + scope = api.llvm.SynchronizationScope.CrossThread + else: + scope = api.llvm.SynchronizationScope.SingleThread + return scope def load_library_permanently(filename): """Load a shared library. @@ -2357,45 +2275,48 @@ def load_library_permanently(filename): Load the given shared library (filename argument specifies the full path of the .so file) using LLVM. Symbols from these are available from the execution engine thereafter.""" - - ret = _core.LLVMLoadLibraryPermanently(filename) - if isinstance(ret, str): - raise llvm.LLVMException(ret) + with contextlib.closing(BytesIO()) as errmsg: + failed = api.llvm.sys.DynamicLibrary.LoadPermanentLibrary(filename, + errmsg) + if failed: + raise llvm.LLVMException(errmsg.getvalue()) def inline_function(call): - check_is_value(call) - return bool(_core.LLVMInlineFunction(call.ptr)) + info = api.llvm.InlineFunctionInfo.new() + return api.llvm.InlineFunction(call._ptr, info) def parse_environment_options(progname, envname): - _core.LLVMParseEnvOpts(progname, envname) + api.llvm.cl.ParseEnvironmentOptions(progname, envname) -#===----------------------------------------------------------------------=== -# Initialization -#===----------------------------------------------------------------------=== -if _core.LLVMInitializeNativeTarget(): +if api.llvm.InitializeNativeTarget(): raise llvm.LLVMException("No native target!?") -if _core.LLVMInitializeNativeTargetAsmPrinter(): +if api.llvm.InitializeNativeTargetAsmPrinter(): # should this be an optional feature? # should user trigger the initialization? raise llvm.LLVMException("No native asm printer!?") +#===----------------------------------------------------------------------=== +# Initialization +#===----------------------------------------------------------------------=== HAS_PTX = HAS_NVPTX = False + if True: # use PTX? try: - _core.LLVMInitializePTXTarget() - _core.LLVMInitializePTXTargetInfo() - _core.LLVMInitializePTXTargetMC() - _core.LLVMInitializePTXAsmPrinter() + api.LLVMInitializePTXTarget() + api.LLVMInitializePTXTargetInfo() + api.LLVMInitializePTXTargetMC() + api.LLVMInitializePTXAsmPrinter() HAS_PTX = True except AttributeError: try: - _core.LLVMInitializeNVPTXTarget() - _core.LLVMInitializeNVPTXTargetInfo() - _core.LLVMInitializeNVPTXTargetMC() - _core.LLVMInitializeNVPTXAsmPrinter() + api.LLVMInitializeNVPTXTarget() + api.LLVMInitializeNVPTXTargetInfo() + api.LLVMInitializeNVPTXTargetMC() + api.LLVMInitializeNVPTXAsmPrinter() HAS_NVPTX = True except AttributeError: pass + diff --git a/llvm/debuginfo.py b/llvm/debuginfo.py deleted file mode 100644 index 0f18b33..0000000 --- a/llvm/debuginfo.py +++ /dev/null @@ -1,398 +0,0 @@ -""" -Support for debug info metadata. -""" - -import functools - -import llvm.core -from llvm import _dwarf - -#---------------------------------------------------------------------------- -# Some types and type checking functions -#---------------------------------------------------------------------------- - -int32_t = llvm.core.Type.int(32) -bool_t = llvm.core.Type.int(1) -p_int32_t = llvm.core.Type.pointer(int32_t) -null = llvm.core.Constant.null(p_int32_t) - -i32 = functools.partial(llvm.core.Constant.int, int32_t) -i1 = functools.partial(llvm.core.Constant.int, bool_t) - -def is_md(value): - return isinstance(value, (llvm.core.MetaData, llvm.core.NamedMetaData, - llvm.core.Value)) - -def is_mdstr(value): - return isinstance(value, (llvm.core.MetaDataString, llvm.core.Value)) - -#---------------------------------------------------------------------------- -# Callbacks for debug type descriptors -#---------------------------------------------------------------------------- - -def get_i32(llvm_module, value): - return i32(value) - -def get_i1(llvm_module, value): - return i1(value) - -def get_md(llvm_module, value): - if is_md(value): - return value - return value.get_metadata(llvm_module) - -def get_mdstr(llvm_module, value): - if is_mdstr(value): - return value - return llvm.core.MetaDataString.get(llvm_module, value) - -def get_mdlist(llvm_module, value): - if isinstance(value, list): - value = MDList([value]) - return get_md(llvm_module, value) - -def get_lfunc(llvm_module, lfunc): - assert lfunc.module is llvm_module - return lfunc - -#---------------------------------------------------------------------------- -# Debug descriptors that generate LLVM Metadata -#---------------------------------------------------------------------------- - -class desc(object): - """ - Descriptor of a debug field. - - field_name: - name of the field (keyword argument name) - build_metadata: - metadata callback :: (llvm_module, Python value) -> LLVM Value - default: - default value for this field - """ - - def __init__(self, field_name, build_metadata, default=None): - self.field_name = field_name - self.build_metadata = build_metadata - self.default = default - - -def build_operand_list(type_descriptors, idx2name, operands, kwargs): - """ - Build the list of operands from the positional and keyword arguments - to a DebugInfoDescriptor. - - E.g. FileDescriptor("foo.c", "/path/to/file", compile_unit=compile_unit) - - idx2name: {0 : 'source_filename', - 1 : 'source_filedir', - 2 : 'compile_unit' } - operands: ["foo.c", "/path/to/file"] - kwargs: { 'compile_unit' : compile_unit } - """ - for i in range(len(operands), len(type_descriptors)): - name = idx2name[i] - if name in kwargs: - op = kwargs[name] - else: - typedesc = type_descriptors[i] - assert typedesc.default is not None, ( - "No value found for field %s" % typedesc.field_name) - op = typedesc.default - - operands.append(op) - - return operands - - -class DebugInfoDescriptor(object): - """ - Base class to describe a debug info descriptor. - - See http://llvm.org/docs/SourceLevelDebugging.html - """ - - type_descriptors = None # [desc(...)] - idx2name = None # { "field_idx" : field_name } - name2idx = None # { "field_name" : field_idx } - - # Whether the debug descriptor is allowed to be incomplete - # The policy seems unclear ? - accept_optional_data = False - - def __init__(self, *args, **kwargs): - self.class_init() - self.metadata_cache = {} - - operands = list(args) - if kwargs or not self.accept_optional_data: - operands = build_operand_list(self.type_descriptors, - self.idx2name, operands, kwargs) - - self.operands = operands - self.operands_dict = dict( - (typedesc.field_name, operand) - for typedesc, operand in zip(self.type_descriptors, operands)) - - @classmethod - def class_init(cls): - if cls.idx2name is None and cls.type_descriptors is not None: - cls.name2idx = {} - cls.idx2name = {} - - for i, typedesc in enumerate(cls.type_descriptors): - cls.name2idx[typedesc.field_name] = i - cls.idx2name[i] = typedesc.field_name - - def add_metadata(self, metadata_name, metadata): - """ - Replace a metadata value in the operand list. - """ - idx = self.name2idx[metadata_name] - self.operands[idx] = metadata - - #------------------------------------------------------------------------ - # Define metadata in a module - #------------------------------------------------------------------------ - - def get_metadata(self, llvm_module): - """ - Get an existing metadata node for the given LLVM module, or build - one from this instance. - """ - if llvm_module in self.metadata_cache: - node = self.metadata_cache[llvm_module] - else: - node = self.build_metadata(llvm_module) - self.metadata_cache[llvm_module] = node - - return node - - def build_metadata(self, llvm_module): - "Build a metadata node for the given LLVM module" - mdops = [] - for type_desc, operand in zip(self.type_descriptors, self.operands): - try: - field_value = type_desc.build_metadata(llvm_module, operand) - except Exception, e: - if type_desc.build_metadata is get_md: - raise - - raise ValueError("Invalid value for field %r: %s" % ( - type_desc.field_name, e)) - - mdops.append(field_value) - - return llvm.core.MetaData.get(llvm_module, mdops) - - def define(self, llvm_module): - """ - Define this debug descriptor as named debug metadata for the module. - """ - md = self.get_metadata(llvm_module) - llvm.core.MetaData.add_named_operand(llvm_module, "dbg", md) - -#---------------------------------------------------------------------------- -# Convenience descriptors -#---------------------------------------------------------------------------- - -class MDList(DebugInfoDescriptor): - """ - [MetaData] - """ - - def __init__(self, operands): - self.type_descriptors = [desc("op", get_md)] * len(operands) - super(MDList, self).__init__(*operands) - -empty = MDList([]) - -#---------------------------------------------------------------------------- -# Dwarf Debug descriptors -#---------------------------------------------------------------------------- - -class CompileUnitDescriptor(DebugInfoDescriptor): - """ - !0 = metadata !{ - i32, ;; Tag = 17 + LLVMDebugVersion (DW_TAG_compile_unit) - i32, ;; Unused field. - i32, ;; DWARF language identifier (ex. DW_LANG_C89) - metadata, ;; Source file name - metadata, ;; Source file directory (includes trailing slash) - metadata ;; Producer (ex. "4.0.1 LLVM (LLVM research group)") - i1, ;; True if this is a main compile unit. - i1, ;; True if this is optimized. - metadata, ;; Flags - i32 ;; Runtime version - metadata ;; List of enums types - metadata ;; List of retained types - metadata ;; List of subprograms - metadata ;; List of global variables - } - """ - - accept_optional_data = True - - type_descriptors = [ - desc("tag", get_i32), - desc("unused", get_i32), - - # Positional argument list starts here: - desc("langid", get_i32), - desc("source_filename", get_mdstr), - desc("source_filedir", get_mdstr), - desc("producer", get_mdstr), - desc("is_main", get_i1, default=False), - desc("is_optimized", get_i1, default=False), - desc("compile_flags", get_mdstr, default=""), - desc("runtime_version", get_i32, default=0), - desc("enum_types", get_mdlist, default=empty), - desc("retained_types", get_mdlist, default=empty), - desc("subprograms", get_mdlist, default=empty), - desc("global_vars", get_mdlist, default=empty), - ] - - def __init__(self, *args, **kwargs): - super(CompileUnitDescriptor, self).__init__( - _dwarf.DW_TAG_compile_unit + _dwarf.LLVMDebugVersion, # tag - 0, # unused - *args, **kwargs) - - def define(self, llvm_module): - """ - Define this debug descriptor as named debug metadata for the module. - """ - md = self.get_metadata(llvm_module) - llvm.core.MetaData.add_named_operand(llvm_module, "llvm.dbg.cu", md) - - -class FileDescriptor(DebugInfoDescriptor): - """ - !0 = metadata !{ - i32, ;; Tag = 41 + LLVMDebugVersion (DW_TAG_file_type) - metadata, ;; Source file name - metadata, ;; Source file directory (includes trailing slash) - metadata ;; Unused - } - """ - - type_descriptors = [ - desc("tag", get_i32), - - # Positional argument list starts here: - desc("source_filename", get_mdstr), - desc("source_filedir", get_mdstr), - desc("compile_unit", get_md, default=null), - ] - - def __init__(self, *args, **kwargs): - super(FileDescriptor, self).__init__( - _dwarf.DW_TAG_file_type + _dwarf.LLVMDebugVersion, # Tag - *args, **kwargs) - - @classmethod - def from_compileunit(cls, compile_unit_descriptor): - return cls(compile_unit_descriptor.operands_dict["source_filename"], - compile_unit_descriptor.operands_dict["source_filedir"], - compile_unit_descriptor) - - -class SubprogramDescriptor(DebugInfoDescriptor): - """ - !2 = metadata !{ - i32, ;; Tag = 46 + LLVMDebugVersion (DW_TAG_subprogram) - i32, ;; Unused field. - metadata, ;; Reference to context descriptor - metadata, ;; Name - metadata, ;; Display name (fully qualified C++ name) - metadata, ;; MIPS linkage name (for C++) - metadata, ;; Reference to file where defined - i32, ;; Line number where defined - metadata, ;; Reference to type descriptor - i1, ;; True if the global is local to compile unit (static) - i1, ;; True if the global is defined in the compile unit (not extern) - i32, ;; Line number where the scope of the subprogram begins - i32, ;; Virtuality, e.g. dwarf::DW_VIRTUALITY__virtual - i32, ;; Index into a virtual function - metadata, ;; indicates which base type contains the vtable pointer for the - ;; derived class - i32, ;; Flags - Artifical, Private, Protected, Explicit, Prototyped. - i1, ;; isOptimized - Function * , ;; Pointer to LLVM function - metadata, ;; Lists function template parameters - metadata, ;; Function declaration descriptor - metadata ;; List of function variables - } - """ - - accept_optional_data = True - - type_descriptors = [ - desc("tag", get_i32), - desc("unused", get_i32), - - # Positional argument list starts here: - desc("file_desc", get_md), - desc("name", get_mdstr), - desc("display_name", get_mdstr), - desc("mips_linkage_name", get_mdstr), - desc("source_file_ref", get_md), - desc("line_number", get_i32), - desc("signature", get_md), - desc("is_local", get_i1, default=False), - desc("is_definition", get_i1, default=True), - desc("virtual_attribute", get_i32, default=0), - desc("virtual_index", get_i32, default=0), - desc("virttab", get_i32, default=0), - desc("flags", get_i32, default=0), - desc("is_optimized", get_i1, default=False), - desc("llvm_func", get_lfunc), - # Template params - # Func decl - # Func vars - ] - - def __init__(self, *args, **kwargs): - super(SubprogramDescriptor, self).__init__( - _dwarf.DW_TAG_subprogram + _dwarf.LLVMDebugVersion, # Tag - 0, # Unused - *args, **kwargs) - -class BlockDescriptor(DebugInfoDescriptor): - """ - !3 = metadata !{ - i32, ;; Tag = 11 + LLVMDebugVersion (DW_TAG_lexical_block) - metadata,;; Reference to context descriptor - i32, ;; Line number - i32 ;; Column number - } - """ - - type_descriptors = [ - desc("tag", get_i32), - - # Positional argument list starts here: - desc("context_descr", get_md), # FileDescr | BlockDescr | - # SubprogDescr | ComputeUnit - desc("line_number", get_i32), - desc("col_number", get_i32), - ] - - def __init__(self, *args, **kwargs): - super(BlockDescriptor, self).__init__( - _dwarf.DW_TAG_lexical_block + _dwarf.LLVMDebugVersion, - *args, **kwargs) - -class PositionInfoDescriptor(DebugInfoDescriptor): - """ - line number, column number, scope, and original scope - """ - - type_descriptors = [ - desc("line_number", get_i32), - desc("col_number", get_i32), - desc("context_descr", get_md), # Scope of instruction - # (FileDescr etc) - desc("original_context_descr", get_md, # The original scope if inlined - default=null), - ] diff --git a/llvm/ee.py b/llvm/ee.py index e5d6ef1..672a0b6 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -28,44 +28,15 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -"""Execution Engine and related classes. +"Execution Engine and related classes." -""" - -import llvm # top-level, for common stuff -import llvm.core as core # module, function etc. -import llvm._core as _core # C wrappers -import llvm._util as _util # utility functions -import logging -import os - -logger = logging.getLogger(__name__) - - -# re-export TargetData for backward compatibility. -from llvm.passes import TargetData - -def _detect_avx_support(): - '''FIXME: This is a workaround for AVX support. - ''' - disable_avx_detect = int(os.environ.get('LLVMPY_DISABLE_AVX_DETECT', 0)) - if disable_avx_detect: - return False # enable AVX if user disable AVX detect - force_disable_avx = int(os.environ.get('LLVMPY_FORCE_DISABLE_AVX', 0)) - if force_disable_avx: - return True # force disable AVX - # auto-detect avx - try: - for line in open('/proc/cpuinfo'): - if line.lstrip().startswith('flags') and 'avx' in line.split(): - # enable AVX if flags contain AVX - return False - except IOError: - pass # disable AVX if no /proc/cpuinfo is found - return True # disable AVX if flags does not have AVX - -FORCE_DISABLE_AVX = _detect_avx_support() +from io import BytesIO +import contextlib +import llvm +from llvm import core +from llvm.passes import TargetData, TargetTransformInfo +from llvmpy import api, extra #===----------------------------------------------------------------------=== # Enumerations #===----------------------------------------------------------------------=== @@ -74,39 +45,41 @@ BO_BIG_ENDIAN = 0 BO_LITTLE_ENDIAN = 1 # CodeModel -CM_DEFAULT = 0 -CM_JITDEFAULT = 1 -CM_SMALL = 2 -CM_KERNEL = 3 -CM_MEDIUM = 4 -CM_LARGE = 5 +CM_DEFAULT = api.llvm.CodeModel.Model.Default +CM_JITDEFAULT = api.llvm.CodeModel.Model.JITDefault +CM_SMALL = api.llvm.CodeModel.Model.Small +CM_KERNEL = api.llvm.CodeModel.Model.Kernel +CM_MEDIUM = api.llvm.CodeModel.Model.Medium +CM_LARGE = api.llvm.CodeModel.Model.Large #===----------------------------------------------------------------------=== # Generic value #===----------------------------------------------------------------------=== -class GenericValue(object): +class GenericValue(llvm.Wrapper): @staticmethod def int(ty, intval): - core.check_is_type(ty) - ptr = _core.LLVMCreateGenericValueOfInt(ty.ptr, intval, 0) + ptr = api.llvm.GenericValue.CreateInt(ty._ptr, int(intval), False) return GenericValue(ptr) @staticmethod def int_signed(ty, intval): - core.check_is_type(ty) - ptr = _core.LLVMCreateGenericValueOfInt(ty.ptr, intval, 1) + ptr = api.llvm.GenericValue.CreateInt(ty._ptr, int(intval), True) return GenericValue(ptr) @staticmethod def real(ty, floatval): - core.check_is_type(ty) # only float or double - ptr = _core.LLVMCreateGenericValueOfFloat(ty.ptr, floatval) + if str(ty) == 'float': + ptr = api.llvm.GenericValue.CreateFloat(float(floatval)) + elif str(ty) == 'double': + ptr = api.llvm.GenericValue.CreateDouble(float(floatval)) + else: + raise Exception('Unreachable') return GenericValue(ptr) @staticmethod - def pointer(*args): + def pointer(addr): ''' One argument version takes (addr). Two argument version takes (ty, addr). [Deprecated] @@ -114,79 +87,46 @@ class GenericValue(object): `ty` is unused. `addr` is an integer representing an address. - TODO: remove two argument version. ''' - if len(args)==2: - logger.warning("Deprecated: Two argument version of " - "GenericValue.pointer() is deprecated.") - addr = args[1] - elif len(args)!=1: - raise TypeError("pointer() takes 1 or 2 arguments.") - else: - addr = args[0] - ptr = _core.LLVMCreateGenericValueOfPointer(addr) + ptr = api.llvm.GenericValue.CreatePointer(int(addr)) return GenericValue(ptr) - def __init__(self, ptr): - self.ptr = ptr - - def __del__(self): - _core.LLVMDisposeGenericValue(self.ptr) - def as_int(self): - return _core.LLVMGenericValueToInt(self.ptr, 0) + return self._ptr.toUnsignedInt() def as_int_signed(self): - return _core.LLVMGenericValueToInt(self.ptr, 1) + return self._ptr.toSignedInt() def as_real(self, ty): - core.check_is_type(ty) # only float or double - return _core.LLVMGenericValueToFloat(ty.ptr, self.ptr) + return self._ptr.toFloat(ty._ptr) def as_pointer(self): - return _core.LLVMGenericValueToPointer(self.ptr) - - -# helper functions for generic value objects -def check_is_generic_value(obj): _util.check_gen(obj, GenericValue) -def _unpack_generic_values(objlist): - return _util.unpack_gen(objlist, check_is_generic_value) - + return self._ptr.toPointer() #===----------------------------------------------------------------------=== # Engine builder #===----------------------------------------------------------------------=== -class EngineBuilder(object): +class EngineBuilder(llvm.Wrapper): @staticmethod def new(module): - core.check_is_module(module) - _util.check_is_unowned(module) - obj = _core.LLVMCreateEngineBuilder(module.ptr) - return EngineBuilder(obj, module) - - def __init__(self, ptr, module): - self.ptr = ptr - self._module = module - self.__has_mattrs = False - - def __del__(self): - _core.LLVMDisposeEngineBuilder(self.ptr) + ptr = api.llvm.EngineBuilder.new(module._ptr) + return EngineBuilder(ptr) def force_jit(self): - _core.LLVMEngineBuilderForceJIT(self.ptr) + self._ptr.setEngineKind(api.llvm.EngineKind.Kind.JIT) return self def force_interpreter(self): - _core.LLVMEngineBuilderForceInterpreter(self.ptr) + self._ptr.setEngineKind(api.llvm.EngineKind.Kind.Interpreter) return self def opt(self, level): ''' level valid [0, 1, 2, 3] -- [None, Less, Default, Aggressive] ''' - assert level in range(4) - _core.LLVMEngineBuilderSetOptLevel(self.ptr, level) + assert 0 <= level <= 3 + self._ptr.setOptLevel = level return self def mattrs(self, string): @@ -194,45 +134,39 @@ class EngineBuilder(object): e.g: +sse,-3dnow ''' - self.__has_mattrs = True - if FORCE_DISABLE_AVX: - if 'avx' not in map(lambda x: x.strip(), string.split(',')): - # User did not override - string += ',-avx' - _core.LLVMEngineBuilderSetMAttrs(self.ptr, string.replace(',', ' ')) + self._ptr.setMAttrs(string.split(',')) return self def create(self, tm=None): ''' tm --- Optional. Provide a TargetMachine. Ownership is transfered - to the returned execution engine. + to the returned execution engine. ''' - if not self.__has_mattrs and FORCE_DISABLE_AVX: - self.mattrs('-avx') - - if tm: - _util.check_is_unowned(tm) - ret = _core.LLVMEngineBuilderCreateTM(self.ptr, tm.ptr) + if tm is not None: + engine = self._ptr.create(tm._ptr) else: - ret = _core.LLVMEngineBuilderCreate(self.ptr) - if isinstance(ret, str): - raise llvm.LLVMException(ret) - engine = ExecutionEngine(ret, self._module) - if tm: - tm._own(owner=llvm.DummyOwner) - return engine + engine = self._ptr.create() + return ExecutionEngine(engine) - def select_target(self): + def select_target(self, *args): '''get the corresponding target machine + + Accept no arguments or (triple, march, mcpu, mattrs) ''' - ptr = _core.LLVMTargetMachineFromEngineBuilder(self.ptr) + if args: + triple, march, mcpu, mattrs = args + ptr = self._ptr.selectTarget(triple, march, mcpu, + mattrs.split(',')) + else: + ptr = self._ptr.selectTarget() return TargetMachine(ptr) + #===----------------------------------------------------------------------=== # Execution engine #===----------------------------------------------------------------------=== -class ExecutionEngine(object): +class ExecutionEngine(llvm.Wrapper): @staticmethod def new(module, force_interpreter=False): @@ -241,65 +175,42 @@ class ExecutionEngine(object): eb.force_interpreter() return eb.create() - def __init__(self, ptr, module): - self.ptr = ptr - module._own(self) - - def __del__(self): - _core.LLVMDisposeExecutionEngine(self.ptr) - def disable_lazy_compilation(self, disabled=True): - _core.LLVMExecutionEngineDisableLazyCompilation(self.ptr, - int(bool(disabled))) + self._ptr.DisableLazyCompilation(disabled) def run_function(self, fn, args): - core.check_is_function(fn) - ptrs = _unpack_generic_values(args) - gvptr = _core.LLVMRunFunction2(self.ptr, fn.ptr, ptrs) - return GenericValue(gvptr) + ptr = self._ptr.runFunction(fn._ptr, list(map(lambda x: x._ptr, args))) + return GenericValue(ptr) def get_pointer_to_function(self, fn): - core.check_is_function(fn) - return _core.LLVMGetPointerToFunction(self.ptr,fn.ptr) + return self._ptr.getPointerToFunction(fn._ptr) def get_pointer_to_global(self, val): - core.check_is_global_value(val) - return _core.LLVMGetPointerToGlobal(self.ptr, val.ptr) + return self._ptr.getPointerToGlobal(val._ptr) def add_global_mapping(self, gvar, addr): assert addr >= 0, "Address cannot not be negative" - _core.LLVMAddGlobalMapping(self.ptr, gvar.ptr, addr) + self._ptr.addGlobalMapping(gvar._ptr, addr) def run_static_ctors(self): - _core.LLVMRunStaticConstructors(self.ptr) + self._ptr.runStaticConstructorsDestructors(False) def run_static_dtors(self): - _core.LLVMRunStaticDestructors(self.ptr) + self._ptr.runStaticConstructorsDestructors(True) def free_machine_code_for(self, fn): - core.check_is_function(fn) - _core.LLVMFreeMachineCodeForFunction(self.ptr, fn.ptr) + self._ptr.freeMachineCodeForFunction(fn._ptr) def add_module(self, module): - core.check_is_module(module) - _core.LLVMAddModule(self.ptr, module.ptr) - module._own(self) + self._ptr.addModule(module._ptr) def remove_module(self, module): - core.check_is_module(module) - if module.owner != self: - raise llvm.LLVMException("module is not owned by self") - ret = _core.LLVMRemoveModule2(self.ptr, module.ptr) - if isinstance(ret, str): - raise llvm.LLVMException(ret) - return core.Module(ret) + return self._ptr.removeModule(module._ptr) @property def target_data(self): - td = TargetData(_core.LLVMGetExecutionEngineTargetData(self.ptr)) - td._own(self) - return td - + ptr = self._ptr.getDataLayout() + return TargetData(ptr) #===----------------------------------------------------------------------=== # Target machine @@ -309,84 +220,114 @@ def print_registered_targets(): ''' Note: print directly to stdout ''' - _core.LLVMPrintRegisteredTargetsForVersion() + api.llvm.TargetRegistry.printRegisteredTargetsForVersion() def get_host_cpu_name(): '''return the string name of the host CPU ''' - return _core.LLVMGetHostCPUName() + return api.llvm.sys.getHostCPUName() def get_default_triple(): '''return the target triple of the host in str-rep ''' - return _core.LLVMDefaultTargetTriple() + return api.llvm.sys.getDefaultTargetTriple() -class TargetMachine(llvm.Ownable): +class TargetMachine(llvm.Wrapper): @staticmethod def new(triple='', cpu='', features='', opt=2, cm=CM_DEFAULT): - if not triple and not cpu: + if not triple: triple = get_default_triple() + if not cpu: cpu = get_host_cpu_name() - ptr = _core.LLVMCreateTargetMachine(triple, cpu, features, opt, cm) - return TargetMachine(ptr) + with contextlib.closing(BytesIO()) as error: + target = api.llvm.TargetRegistry.lookupTarget(triple, error) + if not target: + raise llvm.LLVMException(error) + if not target.hasTargetMachine(): + raise llvm.LLVMException(target, "No target machine.") + target_options = api.llvm.TargetOptions.new() + tm = target.createTargetMachine(triple, cpu, features, + target_options, + api.llvm.Reloc.Model.Default, + cm, opt) + if not tm: + raise llvm.LLVMException("Cannot create target machine") + return TargetMachine(tm) @staticmethod def lookup(arch, cpu='', features='', opt=2, cm=CM_DEFAULT): '''create a targetmachine given an architecture name - For a list of architectures, + For a list of architectures, use: `llc -help` - For a list of available CPUs, + For a list of available CPUs, use: `llvm-as < /dev/null | llc -march=xyz -mcpu=help` - For a list of available attributes (features), + For a list of available attributes (features), use: `llvm-as < /dev/null | llc -march=xyz -mattr=help` - ''' - ptr = _core.LLVMTargetMachineLookup(arch, cpu, features, opt, cm) - return TargetMachine(ptr) + ''' + triple = api.llvm.Triple.new() + with contextlib.closing(BytesIO()) as error: + target = api.llvm.TargetRegistry.lookupTarget(arch, triple, error) + if not target: + raise llvm.LLVMException(error) + if not target.hasTargetMachine(): + raise llvm.LLVMException(target, "No target machine.") + target_options = api.llvm.TargetOptions.new() + tm = target.createTargetMachine(str(triple), cpu, features, + target_options, + api.llvm.Reloc.Model.Default, + cm, opt) + if not tm: + raise llvm.LLVMException("Cannot create target machine") + return TargetMachine(tm) - def __init__(self, ptr): - llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeTargetMachine) + def _emit_file(self, module, cgft): + pm = api.llvm.PassManager.new() + os = extra.make_raw_ostream_for_printing() + pm.add(api.llvm.DataLayout.new(str(self.target_data))) + failed = self._ptr.addPassesToEmitFile(pm, os, cgft) + pm.run(module) + return os.str() def emit_assembly(self, module): '''returns byte string of the module as assembly code of the target machine ''' - return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, True) + CGFT = api.llvm.TargetMachine.CodeGenFileType + return self._emit_file(module._ptr, CGFT.CGFT_AssemblyFile) def emit_object(self, module): '''returns byte string of the module as native code of the target machine ''' - return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, False) + CGFT = api.llvm.TargetMachine.CodeGenFileType + return self._emit_file(module._ptr, CGFT.CGFT_ObjectFile) @property def target_data(self): '''get target data of this machine ''' - ptr = _core.LLVMTargetMachineGetTargetData(self.ptr) - td = TargetData(ptr) - td._own(self) - return td + return TargetData(self._ptr.getDataLayout()) @property def target_name(self): - return _core.LLVMTargetMachineGetTargetName(self.ptr) + return self._ptr.getTarget().getName() @property def target_short_description(self): - return _core.LLVMTargetMachineGetTargetShortDescription(self.ptr) + return self._ptr.getTarget().getShortDescription() @property def triple(self): - return _core.LLVMTargetMachineGetTriple(self.ptr) + return self._ptr.getTargetTriple() @property def cpu(self): - return _core.LLVMTargetMachineGetCPU(self.ptr) - + return self._ptr.getTargetCPU() + @property def feature_string(self): - return _core.LLVMTargetMachineGetFS(self.ptr) + return self._ptr.getTargetFeatureString() diff --git a/llvm/extra.cpp b/llvm/extra.cpp deleted file mode 100644 index 7b6c064..0000000 --- a/llvm/extra.cpp +++ /dev/null @@ -1,1361 +0,0 @@ -/* - * Copyright (c) 2008-10, Mahadevan R All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of this software, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * These are some "extra" functions not available in the standard LLVM-C - * bindings, but are required / good-to-have inorder to implement the - * Python bindings. - */ - -// standard includes -#include -#include -#include -#include -#include - -// LLVM includes -#include "llvm/LLVMContext.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Casting.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/GlobalVariable.h" -//#include "llvm/TypeSymbolTable.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/Host.h" - -#include "llvm/IntrinsicInst.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Assembly/Parser.h" -#include "llvm/Support/DynamicLibrary.h" -#include "llvm/PassManager.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/DomPrinter.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" -#include "llvm/Transforms/Instrumentation.h" -#include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Linker.h" -#include "llvm/Support/SourceMgr.h" -#include -#include -#include - - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 - #include "llvm/DataLayout.h" -#else - #include "llvm/Target/TargetData.h" -#endif - -// LLVM-C includes -#include "llvm-c/Core.h" -#include "llvm-c/ExecutionEngine.h" - -// our includes -#include "extra.h" -#include "llvm_c_extra.h" - -namespace llvm{ -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef) -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(NamedMDNode, LLVMNamedMDRef) -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Pass, LLVMPassRef) - -template -inline T **unwrap(LLVMTypeRef *Tys, unsigned Length) { - (void)Length; - return reinterpret_cast(Tys); -} - -} - -/* - * For use in LLVMDumpPasses to dump passes. - */ -class PassRegistryPrinter : public llvm::PassRegistrationListener{ -public: - std::ostringstream stringstream; - - inline virtual void passEnumerate(const llvm::PassInfo * pass_info){ - stringstream << pass_info->getPassArgument() - << "\t" - << pass_info->getPassName() - << "\n"; - } -}; - - -/* Helper method for LLVMDumpXXXToString() methods. */ -template -char *do_print(W obj) -{ - std::string s; - llvm::raw_string_ostream buf(s); - UW *p = llvm::unwrap(obj); - assert(p); - p->print(buf); - return strdup(buf.str().c_str()); -} - -namespace { -using namespace llvm; -const CodeGenOpt::Level OptLevelMap[] = { - CodeGenOpt::None, - CodeGenOpt::Less, - CodeGenOpt::Default, - CodeGenOpt::Aggressive, -}; - -const CodeModel::Model CodeModelMap[] = { - CodeModel::Default, - CodeModel::JITDefault, - CodeModel::Small, - CodeModel::Kernel, - CodeModel::Medium, - CodeModel::Large, -}; - - -} // end anony namespace - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 -LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref){ - using namespace llvm; - TargetMachine * tm = unwrap(tmref); - Pass * tti = new TargetTransformInfo(tm->getScalarTargetTransformInfo(), - tm->getVectorTargetTransformInfo()); - return wrap(tti); -} -#endif - -LLVMPassRef LLVMCreateTargetLibraryInfo(const char * triple){ - using namespace llvm; - Pass * tli = new TargetLibraryInfo(Triple(triple)); - return wrap(tli); -} - -const char * LLVMDefaultTargetTriple(){ - return strdup(llvm::sys::getDefaultTargetTriple().c_str()); -} - -LLVMPassRef LLVMCreatePassByName(const char *name){ - using namespace llvm; - const PassInfo * pi = Pass::lookupPassInfo(StringRef(name)); - if (pi) { - return wrap(pi->createPass()); - } else { // cannot find pass - return NULL; - } -} - -void LLVMDisposePass(LLVMPassRef passref){ - using namespace llvm; - delete unwrap(passref); -} - -const char * LLVMGetPassName(LLVMPassRef passref){ - using namespace llvm; - return unwrap(passref)->getPassName(); -} - -void LLVMPassDump(LLVMPassRef passref){ - using namespace llvm; - return unwrap(passref)->dump(); -} - -void LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref){ - using namespace llvm; - unwrap(pmref)->add(unwrap(passref)); -} - -LLVMValueRef LLVMGetFunctionFromInlineAsm(LLVMTypeRef funcType, - const char inlineAsm[], - const char constrains[], - bool hasSideEffect, - bool isAlignStack, - int asmDialect) -{ - using namespace llvm; - FunctionType *fnty = unwrap(funcType); - // asmDialect does not exist for LLVM 3.1 - InlineAsm *inlineasmobj = InlineAsm::get(fnty, inlineAsm, constrains, - hasSideEffect, isAlignStack); - return wrap(inlineasmobj); -} - -LLVMModuleRef LLVMCloneModule(LLVMModuleRef mod) -{ - using namespace llvm; - return wrap(CloneModule(unwrap(mod))); -} - -const char * LLVMDumpNamedMDToString(LLVMNamedMDRef nmd) -{ - using namespace llvm; - std::string s; - llvm::raw_string_ostream buf(s); - unwrap(nmd)->print(buf, NULL); - return strdup(buf.str().c_str()); -} - -const char * LLVMNamedMetaDataGetName(LLVMNamedMDRef nmd) -{ - using namespace llvm; - return unwrap(nmd)->getName().data(); -} - -void LLVMNamedMetaDataAddOperand(LLVMNamedMDRef nmd, LLVMValueRef md) -{ - using namespace llvm; - unwrap(nmd)->addOperand(unwrap(md)); -} - -void LLVMEraseNamedMetaData(LLVMNamedMDRef nmd) -{ - using namespace llvm; - unwrap(nmd)->eraseFromParent(); -} - -LLVMNamedMDRef LLVMModuleGetOrInsertNamedMetaData(LLVMModuleRef mod, const char *name) -{ - using namespace llvm; - return wrap(unwrap(mod)->getOrInsertNamedMetadata(name)); -} - -LLVMNamedMDRef LLVMModuleGetNamedMetaData(LLVMModuleRef mod, const char *name) -{ - using namespace llvm; - return wrap(unwrap(mod)->getNamedMetadata(name)); -} - -void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind, - LLVMValueRef metaref) -{ - using namespace llvm; - unwrap(instref)->setMetadata(mdkind, unwrap(metaref)); -} - -LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs, - unsigned valct) -{ - using namespace llvm; - LLVMContext & context = unwrap(modref)->getContext(); - MDNode * const node = MDNode::get( - context, - makeArrayRef(unwrap(valrefs, valct), valct)); - return wrap(node); -} - -LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index) -{ - return wrap(llvm::unwrap(mdref)->getOperand(index)); -} - -unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref) -{ - return llvm::unwrap(mdref)->getNumOperands(); -} - -LLVMValueRef LLVMMetaDataStringGet(LLVMModuleRef modref, const char *s) -{ - LLVMContext & context = unwrap(modref)->getContext(); - MDString * const mdstring = MDString::get(context, s); - return wrap(mdstring); -} - -const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst) -{ - return llvm::unwrap(inst)->getOpcodeName(); -} - -unsigned LLVMGetConstExprOpcode(LLVMValueRef inst) -{ - return llvm::unwrap(inst)->getOpcode(); -} - -void LLVMLdSetAlignment(LLVMValueRef inst, unsigned align) -{ - return llvm::unwrap(inst)->setAlignment(align); -} - -void LLVMStSetAlignment(LLVMValueRef inst, unsigned align) -{ - return llvm::unwrap(inst)->setAlignment(align); -} - -const char * LLVMGetHostCPUName() -{ - return strdup(llvm::sys::getHostCPUName().c_str()); -} - -const char * LLVMGetHostCPUFeatures() -{ - // placeholder - // TODO not implemented even in LLVM3.2svn - // llvm::sys::getHostCPUFeatures - return NULL; -} - -int LLVMInitializeNativeTargetAsmPrinter() -{ - return llvm::InitializeNativeTargetAsmPrinter(); -} - - -LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, - const char *features, int opt, - int codemodel, - std::string &error) -{ - using namespace llvm; - Triple TheTriple; - - // begin borrow from LLVM 3.2 code - // because we don't have 3 argument version of lookup() in 3.1 - const Target * TheTarget = NULL; - - const std::string ArchName(arch); - for (TargetRegistry::iterator it = TargetRegistry::begin(), - ie = TargetRegistry::end(); it != ie; ++it) { - if (ArchName == it->getName()) { - TheTarget = &*it; - break; - } - } - - if (!TheTarget) { - error = "Unknown arch"; - return NULL; - } - - Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName); - - if (Type != Triple::UnknownArch){ - TheTriple.setArch(Type); - } - // end borrow from LLVM 3.2 code - - if (!TheTarget->hasTargetMachine()){ - error = "No target machine for the arch"; - return NULL; - } - - TargetOptions no_target_options; - TargetMachine * tm = TheTarget->createTargetMachine(TheTriple.str(), cpu, - features, - no_target_options, - Reloc::Default, - CodeModelMap[codemodel], - OptLevelMap[opt]); - - if (!tm){ - error = "Cannot create target machine"; - return NULL; - } - return wrap(tm); -} - -LLVMTargetMachineRef LLVMCreateTargetMachine(const char *triple, - const char *cpu, - const char *features, - int opt, - int codemodel, - std::string &error) -{ - using namespace llvm; - - std::string TheTriple = triple; - const Target * TheTarget = TargetRegistry::lookupTarget(TheTriple, error); - if (!TheTarget) return NULL; - - TargetOptions no_target_options; - TargetMachine * tm = TheTarget->createTargetMachine(TheTriple, cpu, features, - no_target_options, - Reloc::Default, - CodeModelMap[codemodel], - OptLevelMap[opt]); - if (!tm) { - error = "Cannot create target machine"; - return NULL; - } - return wrap(tm); -} - -LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb) -{ - using namespace llvm; - TargetMachine * tm = unwrap(eb)->selectTarget(); - return wrap(tm); -} - -void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm){ - delete llvm::unwrap(tm); -} - - -unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, - LLVMModuleRef modref, - int assembly, size_t * lenp, - std::string &error) -{ - using namespace llvm; - assert(lenp); - - Module *modulep = unwrap(modref); - assert(modulep); - - // get objectcode into a string - std::string s; - raw_string_ostream buf(s); - - formatted_raw_ostream fso(buf); - - TargetMachine * tm = unwrap(tmref); - - PassManager pm; -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 - if (!tm->getDataLayout()){ - error = "No target data in target machine"; - return NULL; - } - pm.add(new DataLayout(*tm->getDataLayout())); -#else - if (!tm->getTargetData()){ - error = "No target data in target machine"; - return NULL; - } - pm.add(new TargetData(*tm->getTargetData())); -#endif - - - - bool failed; - if( assembly ) { - failed = tm->addPassesToEmitFile(pm, fso, TargetMachine::CGFT_AssemblyFile); - } else { - failed = tm->addPassesToEmitFile(pm, fso, TargetMachine::CGFT_ObjectFile); - } - - if ( failed ) { - error = "No support for emit file"; - return NULL; - } - - pm.run(*modulep); - - // flush all streams - fso.flush(); - buf.flush(); - - const std::string& bc = buf.str(); - - // and then into a new buffer - size_t bclen = bc.size(); - unsigned char *bytes = new unsigned char[bclen]; - memcpy(bytes, bc.data(), bclen); - - /* return */ - *lenp = bclen; - return bytes; -} - -const char* LLVMTargetMachineGetTargetName(LLVMTargetMachineRef tm) -{ - return strdup(llvm::unwrap(tm)->getTarget().getName()); -} - -const char* LLVMTargetMachineGetTargetShortDescription(LLVMTargetMachineRef tm) -{ - return strdup(llvm::unwrap(tm)->getTarget().getShortDescription()); -} - -const char* LLVMTargetMachineGetTriple(LLVMTargetMachineRef tm) -{ - return strdup(llvm::unwrap(tm)->getTargetTriple().str().c_str()); -} - -const char* LLVMTargetMachineGetCPU(LLVMTargetMachineRef tm) -{ - return strdup(llvm::unwrap(tm)->getTargetCPU().str().c_str()); -} - -const char* LLVMTargetMachineGetFS(LLVMTargetMachineRef tm) -{ - return strdup(llvm::unwrap(tm)->getTargetFeatureString().str().c_str()); -} - -void LLVMPrintRegisteredTargetsForVersion(){ - llvm::TargetRegistry::printRegisteredTargetsForVersion(); -} - - - -LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm) -{ - using namespace llvm; -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 - return wrap(new DataLayout(*unwrap(tm)->getDataLayout())); -#else - return wrap(new TargetData(*unwrap(tm)->getTargetData())); -#endif -} - -unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, - size_t * lenp, std::string &error) -{ - using namespace llvm; - assert(lenp); - - Module *modulep = unwrap(module); - assert(modulep); - - // select native default machine - TargetMachine * tm = EngineBuilder(modulep).selectTarget(); - - return LLVMTargetMachineEmitFile(wrap(tm), module, assembly, lenp, error); -} - -static -llvm::AtomicOrdering atomic_ordering_from_string(const char * ordering) -{ - using namespace llvm; - - if ( strcmp(ordering, "unordered") == 0 ) - return Unordered; - else if ( strcmp(ordering, "monotonic") == 0 ) - return Monotonic; - else if ( strcmp(ordering, "acquire") == 0 ) - return Acquire; - else if ( strcmp(ordering, "release") == 0 ) - return Release; - else if ( strcmp(ordering, "acq_rel") == 0 ) - return AcquireRelease; - else if ( strcmp(ordering, "seq_cst") == 0 ) - return SequentiallyConsistent; - else - return NotAtomic; -} - -static -llvm::SynchronizationScope sync_scope_from_int(int crossthread) -{ - if( crossthread ) - return llvm::CrossThread; - else - return llvm::SingleThread; -} - -LLVMValueRef LLVMBuildFence(LLVMBuilderRef builder, const char* ordering, - int crossthread) -{ - using namespace llvm; - AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); - SynchronizationScope sync_scope = sync_scope_from_int(crossthread); - - Value * inst = unwrap(builder)->CreateFence(atomic_order, sync_scope); - return wrap(inst); -} - -LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef builder, const char * opname, - LLVMValueRef ptr, LLVMValueRef val, - const char* ordering, int crossthread) -{ - using namespace llvm; - - AtomicRMWInst::BinOp op; - - if( strcmp(opname, "xchg") == 0 ) - op = AtomicRMWInst::Xchg; - else if( strcmp(opname, "add") == 0 ) - op = AtomicRMWInst::Add; - else if( strcmp(opname, "sub") == 0 ) - op = AtomicRMWInst::Sub; - else if( strcmp(opname, "and") == 0 ) - op = AtomicRMWInst::And; - else if( strcmp(opname, "nand") == 0 ) - op = AtomicRMWInst::Nand; - else if( strcmp(opname, "or") == 0 ) - op = AtomicRMWInst::Or; - else if( strcmp(opname, "xor") == 0 ) - op = AtomicRMWInst::Xor; - else if( strcmp(opname, "max") == 0 ) - op = AtomicRMWInst::Max; - else if( strcmp(opname, "min") == 0 ) - op = AtomicRMWInst::Min; - else if( strcmp(opname, "umax") == 0 ) - op = AtomicRMWInst::UMax; - else if( strcmp(opname, "umin") == 0 ) - op = AtomicRMWInst::UMin; - else - op = AtomicRMWInst::BAD_BINOP; - - AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); - SynchronizationScope sync_scope = sync_scope_from_int(crossthread); - - Value * inst = unwrap(builder)->CreateAtomicRMW(op, unwrap(ptr), unwrap(val), - atomic_order, sync_scope); - return wrap(inst); -} - -LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr, - unsigned align, const char* ordering, - int crossthread) -{ - using namespace llvm; - AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); - SynchronizationScope sync_scope = sync_scope_from_int(crossthread); - - LoadInst * inst = unwrap(builder)->CreateLoad(unwrap(ptr)); - - inst->setAtomic(atomic_order, sync_scope); - inst->setAlignment(align); - - return wrap(inst); -} - -LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder, - LLVMValueRef ptr, LLVMValueRef val, - unsigned align, const char* ordering, - int crossthread) -{ - using namespace llvm; - AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); - SynchronizationScope sync_scope = sync_scope_from_int(crossthread); - - StoreInst * inst = unwrap(builder)->CreateStore(unwrap(val), unwrap(ptr)); - - inst->setAtomic(atomic_order, sync_scope); - inst->setAlignment(align); - - return wrap(inst); -} - -LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, - LLVMValueRef cmp, LLVMValueRef val, - const char* ordering, int crossthread) -{ - using namespace llvm; - - AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); - SynchronizationScope sync_scope = sync_scope_from_int(crossthread); - - Value * inst = unwrap(builder)->CreateAtomicCmpXchg( - unwrap(ptr), unwrap(cmp), unwrap(val), - atomic_order, sync_scope); - return wrap(inst); -} - -LLVMEngineBuilderRef LLVMCreateEngineBuilder(LLVMModuleRef mod) -{ - return llvm::wrap(new EngineBuilder(unwrap(mod))); -} - -void LLVMDisposeEngineBuilder(LLVMEngineBuilderRef eb) -{ - delete llvm::unwrap(eb); -} - -void LLVMEngineBuilderForceJIT(LLVMEngineBuilderRef eb) -{ - using namespace llvm; - unwrap(eb)->setEngineKind(EngineKind::JIT); -} - -void LLVMEngineBuilderForceInterpreter(LLVMEngineBuilderRef eb) -{ - using namespace llvm; - unwrap(eb)->setEngineKind(EngineKind::Interpreter); -} - -void LLVMEngineBuilderSetOptLevel(LLVMEngineBuilderRef eb, int level) -{ - unwrap(eb)->setOptLevel(OptLevelMap[level]); -} - -void LLVMEngineBuilderSetMCPU(LLVMEngineBuilderRef eb, const char * mcpu) -{ // TODO add test when llvm3.2 releases - unwrap(eb)->setMCPU(mcpu); // does not work in llvm3.1 -} - -void LLVMEngineBuilderSetMAttrs(LLVMEngineBuilderRef eb, const char * mattrs) -{ // TODO add test when llvm3.2 releases - std::vector tokenized; - std::istringstream iss(mattrs); - std::string buf; - while ( iss >> buf ){ - tokenized.push_back(buf); - } - unwrap(eb)->setMAttrs(tokenized); // does not work in llvm3.1 -} - -LLVMExecutionEngineRef LLVMEngineBuilderCreate(LLVMEngineBuilderRef eb, std::string & error) -{ - using namespace llvm; - LLVMExecutionEngineRef ret; - - ret = wrap(unwrap(eb)->setErrorStr(&error).create()); - - if ( !error.empty() ) { // error string is set - return NULL; - } else { - return ret; - } -} - -LLVMExecutionEngineRef LLVMEngineBuilderCreateTM(LLVMEngineBuilderRef eb, - LLVMTargetMachineRef tm, - std::string & error) -{ - using namespace llvm; - LLVMExecutionEngineRef ret; - - ret = wrap(unwrap(eb)->setErrorStr(&error).create(unwrap(tm))); - - if ( !error.empty() ) { // error string is set - return NULL; - } else { - return ret; - } -} - -int LLVMPassManagerBuilderGetOptLevel(LLVMPassManagerBuilderRef pmb) -{ - return llvm::unwrap(pmb)->OptLevel; -} - -int LLVMPassManagerBuilderGetSizeLevel(LLVMPassManagerBuilderRef pmb) -{ - return llvm::unwrap(pmb)->SizeLevel; -} - -void LLVMPassManagerBuilderSetVectorize(LLVMPassManagerBuilderRef pmb, int flag) -{ - llvm::unwrap(pmb)->Vectorize = flag; -} - -int LLVMPassManagerBuilderGetVectorize(LLVMPassManagerBuilderRef pmb){ - return llvm::unwrap(pmb)->Vectorize; -} - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 -void LLVMPassManagerBuilderSetLoopVectorize(LLVMPassManagerBuilderRef pmb, - int flag) -{ - llvm::unwrap(pmb)->LoopVectorize = flag; -} - -int LLVMPassManagerBuilderGetLoopVectorize(LLVMPassManagerBuilderRef pmb){ - return llvm::unwrap(pmb)->LoopVectorize; -} -#endif // llvm-3.2 - - -int LLVMPassManagerBuilderGetDisableUnitAtATime(LLVMPassManagerBuilderRef pmb) -{ - return llvm::unwrap(pmb)->DisableUnitAtATime; -} - -int LLVMPassManagerBuilderGetDisableUnrollLoops(LLVMPassManagerBuilderRef pmb) -{ - return llvm::unwrap(pmb)->DisableUnrollLoops; -} - -int LLVMPassManagerBuilderGetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef pmb) -{ - return llvm::unwrap(pmb)->DisableSimplifyLibCalls; -} - - -int LLVMAddPassByName(LLVMPassManagerRef pm, const char * name) -{ - using namespace llvm; - const PassInfo * pi = Pass::lookupPassInfo(StringRef(name)); - if (pi){ - unwrap(pm)->add(pi->createPass()); - return 1; // success - } else { - return 0; // fail -- cannot find pass - } -} - -void LLVMInitializePasses(){ - using namespace llvm; - PassRegistry ®istry = *PassRegistry::getPassRegistry(); - initializeCore(registry); - initializeScalarOpts(registry); - initializeVectorization(registry); - initializeIPO(registry); - initializeAnalysis(registry); - initializeIPA(registry); - initializeTransformUtils(registry); - initializeInstCombine(registry); - initializeInstrumentation(registry); - initializeTarget(registry); -} - -const char * LLVMDumpPasses() -{ - using namespace llvm; - PassRegistry ®istry = *PassRegistry::getPassRegistry(); - PassRegistryPrinter prp; - registry.enumerateWith(&prp); - return strdup(prp.stringstream.str().c_str()); -} - - -int LLVMIsLiteralStruct(LLVMTypeRef type) -{ - return llvm::unwrap(type)->isLiteral(); -} - -LLVMTypeRef LLVMStructTypeIdentified(const char * name) -{ - using namespace llvm; - return wrap(StructType::create(getGlobalContext(), name)); -} - -void LLVMSetStructBody(LLVMTypeRef type, LLVMTypeRef* elemtys, - unsigned elemct, int is_packed) -{ - using namespace llvm; - ArrayRef elemtys_aryref(unwrap(elemtys), elemct); - unwrap(type)->setBody(elemtys_aryref, is_packed); -} - -void LLVMSetStructName(LLVMTypeRef type, const char * name) -{ - llvm::StructType *st = llvm::unwrap(type); - st->setName(name); -} - -char *LLVMGetModuleIdentifier(LLVMModuleRef module) -{ - return strdup(llvm::unwrap(module)->getModuleIdentifier().c_str()); -} - -void LLVMSetModuleIdentifier(LLVMModuleRef module, const char * name) -{ - llvm::unwrap(module)->setModuleIdentifier(name); -} - -char *LLVMDumpModuleToString(LLVMModuleRef module) -{ - std::string s; - llvm::raw_string_ostream buf(s); - llvm::Module *p = llvm::unwrap(module); - assert(p); - p->print(buf, NULL); - return strdup(buf.str().c_str()); -} - -void LLVMModuleAddLibrary(LLVMModuleRef module, const char *name) -{ - llvm::Module *M = llvm::unwrap(module); - llvm::StringRef namestr = llvm::StringRef(name); - M->addLibrary(namestr); - return; -} - -char *LLVMDumpTypeToString(LLVMTypeRef type) -{ - return do_print(type); -} - -char *LLVMDumpValueToString(LLVMValueRef value) -{ - return do_print(value); -} - -unsigned LLVMModuleGetPointerSize(LLVMModuleRef module) -{ - llvm::Module *modulep = llvm::unwrap(module); - assert(modulep); - - llvm::Module::PointerSize p = modulep->getPointerSize(); - if (p == llvm::Module::Pointer32) - return 32; - else if (p == llvm::Module::Pointer64) - return 64; - return 0; -} - -LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module, - const char *name, LLVMTypeRef function_type) -{ - assert(name); - - llvm::Module *modulep = llvm::unwrap(module); - assert(modulep); - - llvm::FunctionType *ftp = llvm::unwrap(function_type); - assert(ftp); - - llvm::Constant *f = modulep->getOrInsertFunction(name, ftp); - return wrap(f); -} - -int LLVMHasInitializer(LLVMValueRef global_var) -{ - llvm::GlobalVariable *gvp = llvm::unwrap(global_var); - assert(gvp); - - return gvp->hasInitializer(); -} - -#define inst_checkfn(ourfn, llvmfn) \ -unsigned ourfn (LLVMValueRef v) { \ - llvm::Instruction *ip = llvm::unwrap(v); \ - assert(ip); \ - return ip-> llvmfn () ? 1 : 0; \ -} - -inst_checkfn(LLVMInstIsTerminator, isTerminator) -inst_checkfn(LLVMInstIsBinaryOp, isBinaryOp) -inst_checkfn(LLVMInstIsShift, isShift) -inst_checkfn(LLVMInstIsCast, isCast) -inst_checkfn(LLVMInstIsLogicalShift, isLogicalShift) -inst_checkfn(LLVMInstIsArithmeticShift, isArithmeticShift) -inst_checkfn(LLVMInstIsAssociative, isAssociative) -inst_checkfn(LLVMInstIsCommutative, isCommutative) - -unsigned LLVMInstIsVolatile(LLVMValueRef v) -{ - using namespace llvm; - Instruction *ip = unwrap(v); - assert(ip); - return ((isa(*ip) && cast(*ip).isVolatile()) || - (isa(*ip) && cast(*ip).isVolatile()) ); -} - -const char *LLVMInstGetOpcodeName(LLVMValueRef inst) -{ - llvm::Instruction *instp = llvm::unwrap(inst); - assert(instp); - return instp->getOpcodeName(); -} - -unsigned LLVMInstGetOpcode(LLVMValueRef inst) -{ - llvm::Instruction *instp = llvm::unwrap(inst); - assert(instp); - return instp->getOpcode(); -} - -unsigned LLVMCmpInstGetPredicate(LLVMValueRef cmpinst) -{ - llvm::CmpInst *instp = llvm::unwrap(cmpinst); - assert(instp); - return instp->getPredicate(); -} - -LLVMValueRef LLVMInstGetCalledFunction(LLVMValueRef inst) -{ - llvm::Instruction *instp = llvm::unwrap(inst); - return llvm::wrap(CallSite(instp).getCalledFunction()); -} - -void LLVMInstSetCalledFunction(LLVMValueRef inst, LLVMValueRef fn) -{ - using namespace llvm; - Instruction *instp = unwrap(inst); - CallSite(instp).setCalledFunction(unwrap(fn)); -} - -///* llvm::unwrap a set of `n' wrapped objects starting at `values', -// * into a vector of pointers to llvm::unwrapped objects `out'. */ -//template -//void unwrap_vec(W *values, unsigned n, std::vector& out) -//{ -// out.clear(); -// out.reserve(n); -// while (n--) { -// UW *p = llvm::unwrap(*values); -// assert(p); -// out.push_back(p); -// ++values; -// } -//} - -///* Same as llvm::unwrap_vec, but use a vector of const pointers. */ -//template -//void unwrap_cvec(W *values, unsigned n, std::vector& out) -//{ -// out.clear(); - -// while (n--) { -// UW *p = llvm::unwrap(*values); -// assert(p); -// out.push_back(p); -// ++values; -// } -//} - - -LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef builder, - LLVMValueRef *values, unsigned n_values) -{ - using namespace llvm; - assert(values); - - IRBuilder<> *builderp = unwrap(builder); - assert(builderp); - - return wrap(builderp->CreateAggregateRet(unwrap(values, n_values), n_values)); -} - -LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, - LLVMValueRef value, unsigned index, const char *name) -{ - assert(name); - - llvm::IRBuilder<> *builderp = llvm::unwrap(builder); - assert(builderp); - - return llvm::wrap(builderp->CreateExtractValue(llvm::unwrap(value), index, name)); -} - -unsigned LLVMValueGetID(LLVMValueRef value) -{ - llvm::Value *valuep = llvm::unwrap(value); - assert(valuep); - - return valuep->getValueID(); -} - - -unsigned LLVMValueGetNumUses(LLVMValueRef value) -{ - llvm::Value *valuep = llvm::unwrap(value); - assert(valuep); - - return valuep->getNumUses(); -} - - -unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs) -{ - llvm::Value *valuep = llvm::unwrap(value); - assert(valuep); - - unsigned n = valuep->getNumUses(); - if (n == 0) - return 0; - - assert(refs); - LLVMValueRef *out = new LLVMValueRef[n]; - if (!out) - return 0; - *refs = out; - - memset(out, 0, sizeof(LLVMValueRef) * n); - llvm::Value::use_iterator it = valuep->use_begin(); - while (it != valuep->use_end()) { - *out++ = llvm::wrap(*it); - ++it; - } - - return n; -} - -void LLVMDisposeValueRefArray(LLVMValueRef *refs) -{ - assert(refs); - delete [] refs; -} - -unsigned LLVMUserGetNumOperands(LLVMValueRef user) -{ - llvm::User *userp = llvm::unwrap(user); - assert(userp); - return userp->getNumOperands(); -} - -LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx) -{ - llvm::User *userp = llvm::unwrap(user); - assert(userp); - llvm::Value *operand = userp->getOperand(idx); - return llvm::wrap(operand); -} - -unsigned LLVMGetDoesNotThrow(LLVMValueRef fn) -{ - llvm::Function *fnp = llvm::unwrap(fn); - assert(fnp); - - return fnp->doesNotThrow(); -} - -void LLVMSetDoesNotThrow(LLVMValueRef fn, int DoesNotThrow) -{ - llvm::Function *fnp = llvm::unwrap(fn); - assert(fnp); - - if ((bool)DoesNotThrow) - fnp->setDoesNotThrow(); -} - - -LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef module, int id, - LLVMTypeRef *types, unsigned n_types) -{ - using namespace llvm; - assert(types); - - Module *modulep = unwrap(module); - assert(modulep); - - Function *intfunc = Intrinsic::getDeclaration(modulep, Intrinsic::ID(id), - makeArrayRef(unwrap(types, n_types), - n_types)); - - return wrap(intfunc); -} - -LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtext, char **out) -{ - assert(asmtext); - assert(out); - - llvm::Module *modulep; - llvm::SMDiagnostic error; - if (!(modulep = llvm::ParseAssemblyString(asmtext, NULL, error, - llvm::getGlobalContext()))) { - std::string s; - llvm::raw_string_ostream buf(s); - error.print("llvm-py", buf); - *out = strdup(buf.str().c_str()); - return NULL; - } - - return wrap(modulep); -} - -LLVMModuleRef LLVMGetModuleFromBitcode(const char *bitcode, unsigned bclen, - char **out) -{ - assert(bitcode); - assert(out); - - llvm::StringRef as_str(bitcode, bclen); - - llvm::MemoryBuffer *mbp; - if (!(mbp = llvm::MemoryBuffer::getMemBufferCopy(as_str))) - return NULL; - - std::string msg; - llvm::Module *modulep; - if (!(modulep = llvm::ParseBitcodeFile(mbp, llvm::getGlobalContext(), - &msg))) - *out = strdup(msg.c_str()); - - delete mbp; - return wrap(modulep); -} - -#if LLVM_VERSION_MAJOR <= 3 && LLVM_VERSION_MINOR < 2 -// Shamelessly copy from LLVM-3.2 -unsigned LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, - int Mode, char **OutMessages) { - std::string Messages; - unsigned Result = Linker::LinkModules(unwrap(Dest), unwrap(Src), Mode, - OutMessages? &Messages : 0); - if (OutMessages) - *OutMessages = strdup(Messages.c_str()); - return Result; -} -#endif - -unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, size_t *lenp) -{ - assert(lenp); - - llvm::Module *modulep = llvm::unwrap(module); - assert(modulep); - - /* get bc into a string */ - std::string s; - llvm::raw_string_ostream buf(s); - llvm::WriteBitcodeToFile(modulep, buf); - const std::string& bc = buf.str(); - - /* and then into a new()-ed block */ - size_t bclen = bc.size(); - unsigned char *bytes = new unsigned char[bclen]; - memcpy(bytes, bc.data(), bclen); - - /* return */ - *lenp = bclen; - return bytes; -} - -/* Return 0 on failure (with errmsg filled in), 1 on success. */ -unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg) -{ - printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@1"); - assert(filename); - printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2"); - assert(errmsg); - printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3"); - - /* Note: the LLVM API returns true on failure. Don't ask why. */ - std::string msg; - printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4"); - if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) { - printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@5"); - *errmsg = strdup(msg.c_str()); - printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@6"); - return 0; - } - printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7"); - return 1; -} - -void LLVMExecutionEngineDisableLazyCompilation(LLVMExecutionEngineRef ee, int flag) -{ - llvm::unwrap(ee)->DisableLazyCompilation(flag); -} - -void *LLVMGetPointerToFunction(LLVMExecutionEngineRef ee, LLVMValueRef fn) -{ - llvm::ExecutionEngine *eep = llvm::unwrap(ee); - assert(eep); - - llvm::Function *fnp = llvm::unwrap(fn); - assert(fnp); - - return eep->getPointerToFunction(fnp); -} - - -int LLVMInlineFunction(LLVMValueRef call) -{ - llvm::Value *callp = llvm::unwrap(call); - assert(callp); - - llvm::InlineFunctionInfo unused; - - llvm::Instruction *II = llvm::dyn_cast(callp); - if (II->getOpcode() == llvm::Instruction::Call) - return llvm::InlineFunction(static_cast(II), unused); - else if (II->getOpcode() == llvm::Instruction::Invoke) - return llvm::InlineFunction(static_cast(II), unused); - else - return 0; -} - -unsigned LLVMGetParamAlignment(LLVMValueRef arg) -{ - llvm::Argument *argp = llvm::unwrap(arg); - assert(argp); - - unsigned argno = argp->getArgNo(); - - return argp->getParent()->getParamAlignment(argno + 1); -} - - -/* Passes. A few passes (listed below) are used directly from LLVM-C, - * rest are defined here. - */ -/* -#define define_pass(P) \ -void LLVMAdd ## P ## Pass (LLVMPassManagerRef passmgr) { \ - using namespace llvm; \ - llvm::PassManagerBase *pmp = llvm::unwrap(passmgr); \ - assert(pmp); \ - pmp->add( create ## P ## Pass ()); \ -} - -define_pass( AAEval ) -define_pass( AliasAnalysisCounter ) -//define_pass( AlwaysInliner ) -//define_pass( BasicAliasAnalysis ) -define_pass( BlockPlacement ) -define_pass( BreakCriticalEdges ) -define_pass( CodeGenPrepare ) -define_pass( DbgInfoPrinter ) -define_pass( DeadCodeElimination ) -define_pass( DeadInstElimination ) -define_pass( DemoteRegisterToMemory ) -define_pass( DomOnlyPrinter ) -define_pass( DomOnlyViewer ) -define_pass( DomPrinter ) -define_pass( DomViewer ) -define_pass( EdgeProfiler ) -//define_pass( GEPSplitter ) -define_pass( GlobalsModRef ) -define_pass( InstCount ) -define_pass( InstructionNamer ) -define_pass( LazyValueInfo ) -define_pass( LCSSA ) -//define_pass( LiveValues ) -define_pass( LoopDependenceAnalysis ) -define_pass( LoopExtractor ) -define_pass( LoopSimplify ) -define_pass( LoopStrengthReduce ) -define_pass( LowerInvoke ) -define_pass( LowerSwitch ) -define_pass( MergeFunctions ) -define_pass( NoAA ) -define_pass( NoProfileInfo ) -define_pass( OptimalEdgeProfiler ) -define_pass( PartialInlining ) -//define_pass( PartialSpecialization ) -define_pass( PostDomOnlyPrinter ) -define_pass( PostDomOnlyViewer ) -define_pass( PostDomPrinter ) -define_pass( PostDomViewer ) -define_pass( ProfileEstimator ) -define_pass( ProfileLoader ) -define_pass( ProfileVerifier ) -define_pass( ScalarEvolutionAliasAnalysis ) -//define_pass( SimplifyHalfPowrLibCalls ) -define_pass( SingleLoopExtractor ) -define_pass( StripNonDebugSymbols ) -//define_pass( StructRetPromotion ) -//define_pass( TailDuplication ) -define_pass( UnifyFunctionExitNodes ) -*/ -/* we support only internalize(true) */ -/* -llvm::ModulePass *createInternalize2Pass() { return llvm::createInternalizePass(true); } -define_pass( Internalize2 ) -*/ diff --git a/llvm/extra.h b/llvm/extra.h deleted file mode 100644 index b734f1b..0000000 --- a/llvm/extra.h +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright (c) 2008-10, Mahadevan R All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of this software, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * These are some "extra" functions not available in the standard LLVM-C - * bindings, but are required / good-to-have inorder to implement the - * Python bindings. - */ - -#ifndef LLVM_PY_EXTRA_H -#define LLVM_PY_EXTRA_H - -// select PTX or NVPTX - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 - #define LLVM_HAS_NVPTX 1 -#else - #define LLVM_HAS_NVPTX 0 -#endif - -#include "llvm-c/Transforms/PassManagerBuilder.h" -#include "llvm_c_extra.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 -/* - * Wraps new TargetTransformInfo( - * TargetMachine::getScalarTargetTransformInfo, - * TargetMachine::getVectorTargetTransformInfo) - */ -LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref); -#endif - -/* - * Wraps new TargetLibraryInfo - */ -LLVMPassRef LLVMCreateTargetLibraryInfo(const char * triple); - -/* - * Wraps llvm::getDefaultTargetTriple - */ -const char * LLVMDefaultTargetTriple(); - -/* - * Wraps Pass::lookupPassInfo and PassInfo::createPass - */ -LLVMPassRef LLVMCreatePassByName(const char *name); - -/* - * Wraps operator delete (Pass*) - */ -void LLVMDisposePass(LLVMPassRef passref); - -/* - * Wraps Pass::getPassName - */ -const char * LLVMGetPassName(LLVMPassRef passref); - -/* - * Wraps PassManager::add - */ -void LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref); - -/* - * Wraps Pass::dump - */ -void LLVMPassDump(LLVMPassRef passref); - -/* - * Wraps llvm:InlineAsm::get - */ -LLVMValueRef LLVMGetFunctionFromInlineAsm(LLVMTypeRef funcType, - const char inlineAsm[], - const char constrains[], - bool hasSideEffect, - bool isAlignStack, - int asmDialect); - -/* - * Wraps llvm::CloneModule - */ -LLVMModuleRef LLVMCloneModule(LLVMModuleRef mod); - - -/* - * Wraps NamedMDNode::print() - */ -const char * LLVMDumpNamedMDToString(LLVMNamedMDRef nmd); - -/* - * Wraps NamedMDNode::getName() - */ -const char * LLVMNamedMetaDataGetName(LLVMNamedMDRef nmd); - -/* - * Wraps NamedMDNode::addOperand() - */ -void LLVMNamedMetaDataAddOperand(LLVMNamedMDRef nmd, LLVMValueRef md); - -/* - * Wraps NamedMDNode::eraseFromParent() - */ -void LLVMEraseNamedMetaData(LLVMNamedMDRef nmd); - -/* - * Wraps Module::getOrInsertNamedMetadata - */ -LLVMNamedMDRef LLVMModuleGetOrInsertNamedMetaData(LLVMModuleRef mod, const char *name); - -/* - * Wraps Module::getNamedMetadata - */ -LLVMNamedMDRef LLVMModuleGetNamedMetaData(LLVMModuleRef mod, const char *name); - -/* - * Wraps Instruction::setMetadata() - */ -void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind, - LLVMValueRef metaref); - -/* - * Wraps MDNode::get() - */ -LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs, - unsigned valct); - -/* - * Wraps MDNode::getOperand() - */ -LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index); - -/* - * Wraps MDNode::getNumOperands() - */ -unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref); - -/* - * Wraps MDString::get() - */ -LLVMValueRef LLVMMetaDataStringGet(LLVMModuleRef modref, const char *s); - -/* - * Wraps ConstantExpr::getOpcodeName() - */ -const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst); - -/* - * Wraps ConstantExpr::getOpcode() - */ -unsigned LLVMGetConstExprOpcode(LLVMValueRef inst); - -/* - * Wraps LoadInst::SetAlignment - */ -void LLVMLdSetAlignment(LLVMValueRef inst, unsigned align); - -/* - * Wraps StoreInst::SetAlignment - */ -void LLVMStSetAlignment(LLVMValueRef inst, unsigned align); - -const char * LLVMGetHostCPUName(); - -int LLVMInitializeNativeTargetAsmPrinter(); - - -LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, - const char *features, int opt, - int codemodel, std::string &error); - -LLVMTargetMachineRef LLVMCreateTargetMachine(const char *arch, const char *cpu, - const char *features, int opt, - int codemodel, - std::string &error); - -/* - * Wraps EngineBuilder::selectTarget - */ -LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb); - -/* - * Wraps operator delete - */ -void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm); - -/* - * Wraps TargetMachine::addPassesToEmitFile - */ -unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, - LLVMModuleRef modref, - int assembly, size_t * lenp, - std::string &error); - -/* - * Wraps TargetMachine::getTargetData - */ -LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm); - -/* - * Wraps TargetMachine::getTarget().getName() - */ -const char* LLVMTargetMachineGetTargetName(LLVMTargetMachineRef tm); - -/* - * Wraps TargetMachine::getTarget().getShortDescription() - */ -const char* LLVMTargetMachineGetTargetShortDescription(LLVMTargetMachineRef tm); - -/* - * Wraps TargetMachine::getTargetTriple - */ -const char * LLVMTargetMachineGetTriple(LLVMTargetMachineRef tm); - -/* - * Wraps TargetMachine::getTargetCPU - */ -const char * LLVMTargetMachineGetCPU(LLVMTargetMachineRef tm); - -/* - * Wraps TargetMachine::getTargetFeatureString - */ -const char * LLVMTargetMachineGetFS(LLVMTargetMachineRef tm); - -/* - * Wraps TargetRegister::printRegisteredTargetsForVersion - */ -void LLVMPrintRegisteredTargetsForVersion(); - -/* - * Wraps TargetMachine::addPassesToEmitFile - */ -unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, - size_t * lenp, std::string &error); - -/* - * Wraps IRBuilder::CreateFence - */ -LLVMValueRef LLVMBuildFence(LLVMBuilderRef builder, const char* ordering, - int crossthread); - -/* - * Wraps IRBuilder::CreateLoad, LoadInst::setAtomic - */ -LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr, - unsigned align, const char* ordering, - int crossthread); -/* - * Wraps IRBuilder::CreateStore, StoreInst::setAtomic - */ -LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder, - LLVMValueRef ptr, LLVMValueRef val, - unsigned align, const char* ordering, - int crossthread); - -/* - * Wraps IRBuilder::CreateAtomicRMW - */ -LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef builder, const char * op, - LLVMValueRef ptr, LLVMValueRef val, - const char* ordering, int crossthread); - -/* - * Wraps IRBuilder::CreateAtomicCmpXchg - */ -LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, - LLVMValueRef cmp, LLVMValueRef val, - const char* ordering, int crossthread); - -/* - * Wraps new EngineBuilder - */ -LLVMEngineBuilderRef LLVMCreateEngineBuilder(LLVMModuleRef mod); - -/* - * Wraps delete EngineBuilder - */ -void LLVMDisposeEngineBuilder(LLVMEngineBuilderRef eb); - - -/* - * Wraps EngineBuilder::setEngineKind(EngineKind::JIT) - */ -void LLVMEngineBuilderForceJIT(LLVMEngineBuilderRef eb); - -/* - * Wraps EngineBuilder::setEngineKind(EngineKind::Interpreter) - */ -void LLVMEngineBuilderForceInterpreter(LLVMEngineBuilderRef eb); - - -/* - * Wraps EngineBuilder::setOptLevel - */ -void LLVMEngineBuilderSetOptLevel(LLVMEngineBuilderRef eb, int level); - -/* - * Wraps EngineBuilder::setMCPU - */ -void LLVMEngineBuilderSetMCPU(LLVMEngineBuilderRef eb, const char * mcpu); - -/* - * Wraps EngineBuilder::setMAttrs - */ -void LLVMEngineBuilderSetMAttrs(LLVMEngineBuilderRef eb, const char * mattrs); - -/* - * Wraps EngineBuilder::setErrorStr and EngineBuilder::create - */ -LLVMExecutionEngineRef LLVMEngineBuilderCreate(LLVMEngineBuilderRef eb, - std::string &error); - -/* - * Wraps EngineBuilder::create(TargetMachine*) - */ -LLVMExecutionEngineRef LLVMEngineBuilderCreateTM(LLVMEngineBuilderRef ebref, - LLVMTargetMachineRef tmref, - std::string & error); - - -/* - * Wraps PassManagerBuilder::OptLevel - */ -int LLVMPassManagerBuilderGetOptLevel(LLVMPassManagerBuilderRef pmb); - -/* - * Wraps PassManagerBuilder::SizeLevel - */ -int LLVMPassManagerBuilderGetSizeLevel(LLVMPassManagerBuilderRef pmb); - -/* - * Wraps PassManagerBuilder::Vectorize - */ -void LLVMPassManagerBuilderSetVectorize(LLVMPassManagerBuilderRef pmb, int flag); - -/* - * Wraps PassManagerBuilder::Vectorize - */ -int LLVMPassManagerBuilderGetVectorize(LLVMPassManagerBuilderRef pmb); - -#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 -/* - * Wraps PassManagerBuilder::LoopVectorize - */ -void LLVMPassManagerBuilderSetLoopVectorize(LLVMPassManagerBuilderRef pmb, - int flag); - -/* - * Wraps PassManagerBuilder::LoopVectorize - */ -int LLVMPassManagerBuilderGetLoopVectorize(LLVMPassManagerBuilderRef pmb); -#endif // llvm-3.2 - -/* - * Wraps PassManagerBuilder::DisableUnitAtATime - */ -int LLVMPassManagerBuilderGetDisableUnitAtATime(LLVMPassManagerBuilderRef pmb); - -/* - * Wraps PassManagerBuilder::DisableUnrollLoops - */ -int LLVMPassManagerBuilderGetDisableUnrollLoops(LLVMPassManagerBuilderRef pmb); - -/* - * Wraps PassManagerBuilder::DisableSimplifyLibCalls - */ -int LLVMPassManagerBuilderGetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef pmb); - -/* - * Wraps PassManager::add - */ -int LLVMAddPassByName(LLVMPassManagerRef pm, const char * name); - -/* - * Wraps initialize* - */ -void LLVMInitializePasses(void); - -/* - * Wraps PassRegistry::enumerateWith() - * Returns a '\n' separated string of all passes available to `opt`. - */ -const char * LLVMDumpPasses(void); - -/* - * Wraps StructType::isLiteral() - */ -int LLVMIsLiteralStruct(LLVMTypeRef type); - -/* - * Wraps StructType::create() - */ -LLVMTypeRef LLVMStructTypeIdentified(const char * name); - -/* - * StructType::setBody() - */ -void LLVMSetStructBody(LLVMTypeRef type, LLVMTypeRef* elemtys, unsigned elemct, int is_packed); - -/* - * Wraps llvm::StructType::setName() - */ -void LLVMSetStructName(LLVMTypeRef type, const char * name); - - -/* - * Wraps llvm::Module::getModuleIdentifier() - */ -char *LLVMGetModuleIdentifier(LLVMModuleRef module); - -/* - * Wraps llvm::Module::setModuleIdentifier() - */ -void LLVMSetModuleIdentifier(LLVMModuleRef module, const char * name); - -/* Notes: - * - Some returned strings must be disposed of by LLVMDisposeMessage. These are - * indicated in the comments. Where it is not indicated, DO NOT call dispose. - */ - -/* Wraps llvm::Module::print(). Dispose the returned string after use, via - * LLVMDisposeMessage(). */ -char *LLVMDumpModuleToString(LLVMModuleRef module); - -/* Wraps llvm::Module::addLibrary(name). */ -void LLVMModuleAddLibrary(LLVMModuleRef module, const char *name); - -/* Wraps llvm::Type::print(). Dispose the returned string after use, via - * LLVMDisposeMessage(). */ -char *LLVMDumpTypeToString(LLVMTypeRef type); - -/* Wraps llvm::Value::print(). Dispose the returned string after use, via - * LLVMDisposeMessage(). */ -char *LLVMDumpValueToString(LLVMValueRef Val); - -/* Wraps llvm::IRBuilder::CreateRet(). */ -LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef bulder, LLVMValueRef *values, - unsigned n_values); - -/* Wraps llvm::IRBuilder::CreateGetResult(). */ -LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value, - unsigned index, const char *name); - -/* Wraps llvm::Value::getValueID(). */ -unsigned LLVMValueGetID(LLVMValueRef value); - -/* Wraps llvm::Value::getNumUses(). */ -unsigned LLVMValueGetNumUses(LLVMValueRef value); - -/* Wraps llvm::Value::use_{begin,end}. Allocates LLVMValueRef's as - * required. Number of objects are returned as return value. If that is - * greater than zero, the pointer given out must be freed by a - * subsequent call to LLVMDisposeValueRefArray(). */ -unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs); - -/* See above. */ -void LLVMDisposeValueRefArray(LLVMValueRef *refs); - -/* Wraps llvm:User::getNumOperands(). */ -unsigned LLVMUserGetNumOperands(LLVMValueRef user); - -/* Wraps llvm:User::getOperand(). */ -LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx); - -/* Wraps llvm::ConstantExpr::getVICmp(). */ -LLVMValueRef LLVMConstVICmp(LLVMIntPredicate predicate, LLVMValueRef lhs, - LLVMValueRef rhs); - -/* Wraps llvm::ConstantExpr::getVFCmp(). */ -LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate predicate, LLVMValueRef lhs, - LLVMValueRef rhs); - -/* Wraps llvm::IRBuilder::CreateVICmp(). */ -LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef builder, LLVMIntPredicate predicate, - LLVMValueRef lhs, LLVMValueRef rhs, const char *name); - -/* Wraps llvm::IRBuilder::CreateVFCmp(). */ -LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef builder, LLVMRealPredicate predicate, - LLVMValueRef lhs, LLVMValueRef rhs, const char *name); - -/* Wraps llvm::Intrinsic::getDeclaration(). */ -LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef builder, int id, - LLVMTypeRef *types, unsigned n_types); - -/* Wraps llvm::Function::doesNotThrow(). */ -unsigned LLVMGetDoesNotThrow(LLVMValueRef fn); - -/* Wraps llvm::Function::setDoesNotThrow(). */ -void LLVMSetDoesNotThrow(LLVMValueRef fn, int DoesNotThrow); - -/* Wraps llvm::Module::getPointerSize(). */ -unsigned LLVMModuleGetPointerSize(LLVMModuleRef module); - -/* Wraps llvm::Module::getOrInsertFunction(). */ -LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module, - const char *name, LLVMTypeRef function_type); - -/* Wraps llvm::GlobalVariable::hasInitializer(). */ -int LLVMHasInitializer(LLVMValueRef global_var); - -/* The following functions wrap various llvm::Instruction::isXXX() functions. - * All of them take an instruction and return 0 (isXXX returned false) or 1 - * (isXXX returned false). */ -unsigned LLVMInstIsTerminator (LLVMValueRef inst); -unsigned LLVMInstIsBinaryOp (LLVMValueRef inst); -unsigned LLVMInstIsShift (LLVMValueRef inst); -unsigned LLVMInstIsCast (LLVMValueRef inst); -unsigned LLVMInstIsLogicalShift (LLVMValueRef inst); -unsigned LLVMInstIsArithmeticShift (LLVMValueRef inst); -unsigned LLVMInstIsAssociative (LLVMValueRef inst); -unsigned LLVMInstIsCommutative (LLVMValueRef inst); -unsigned LLVMInstIsTrapping (LLVMValueRef inst); - -/* As above, but these are wrap methods from subclasses of Instruction. */ -unsigned LLVMInstIsVolatile (LLVMValueRef inst); - -/* Wraps llvm::Instruction::getOpcodeName(). */ -const char *LLVMInstGetOpcodeName(LLVMValueRef inst); - -/* Wraps llvm::Instruction::getOpcode(). */ -unsigned LLVMInstGetOpcode(LLVMValueRef inst); - -/* Wraps llvm::CmpInst::getPredicate(). */ -unsigned LLVMCmpInstGetPredicate(LLVMValueRef cmpinst); - -/* Wraps llvm::CallSite::getCalledFunction. - */ -LLVMValueRef LLVMInstGetCalledFunction(LLVMValueRef inst); - -/* Wraps llvm::CallSite::setCalledFunction. - */ -void LLVMInstSetCalledFunction(LLVMValueRef inst, LLVMValueRef fn); - -/* Wraps llvm::ParseAssemblyString(). Returns a module reference or NULL (with - * `out' pointing to an error message). Dispose error message after use, via - * LLVMDisposeMessage(). */ -LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtxt, char **out); - -/* Wraps llvm::ParseBitcodeFile(). Returns a module reference or NULL (with - * `out' pointing to an error message). Dispose error message after use, via - * LLVMDisposeMessage(). */ -LLVMModuleRef LLVMGetModuleFromBitcode(const char *bc, unsigned bclen, - char **out); - -#if LLVM_VERSION_MAJOR <= 3 && LLVM_VERSION_MINOR < 2 -/* Wraps llvm::Linker::LinkModules(). Returns 0 on failure (with errmsg - * filled in) and 1 on success. Dispose error message after use with - * LLVMDisposeMessage(). */ -unsigned LLVMLinkModules(LLVMModuleRef dest, LLVMModuleRef src, int mode, - char **errmsg); -#endif -/* Returns pointer to a heap-allocated block of `*len' bytes containing bit code - * for the given module. NULL on error. */ -unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, size_t *len); - -/* Wraps llvm::sys::DynamicLibrary::LoadLibraryPermanently(). Returns 0 on - * failure (with errmsg filled in) and 1 on success. Dispose error message after - * use, via LLVMDisposeMessage(). */ -unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg); - -/* Wraps llvm::ExecutionEngine::DisableLazyCompilation(bool) - */ -void LLVMExecutionEngineDisableLazyCompilation(LLVMExecutionEngineRef ee, - int flag); - -/* Wraps llvm::ExecutionEngine::getPointerToFunction(). Returns a pointer - * to the JITted function. */ -void *LLVMGetPointerToFunction(LLVMExecutionEngineRef ee, LLVMValueRef fn); - -/* Wraps llvm::InlineFunction(). Inlines a function. C is the call - * instruction, created by LLVMBuildCall. Even if it fails, the Function - * containing the call is still in a proper state (not changed). - */ -int LLVMInlineFunction(LLVMValueRef call); - -/* Wraps llvm::getAlignmentFromAttrs from Attributes.h. Compliments the - * already available LLVMSetParamAlignment(). */ -unsigned LLVMGetParamAlignment(LLVMValueRef arg); - -/* Passes. Some passes are used directly from LLVM-C, rest are declared - * here. */ - -/* -#define declare_pass(P) \ - void LLVMAdd ## P ## Pass (LLVMPassManagerRef PM); - -declare_pass( AAEval ) -declare_pass( AliasAnalysisCounter ) -declare_pass( AlwaysInliner ) -declare_pass( BasicAliasAnalysis ) -declare_pass( BlockPlacement ) -declare_pass( BreakCriticalEdges ) -declare_pass( CodeGenPrepare ) -declare_pass( DbgInfoPrinter ) -declare_pass( DeadCodeElimination ) -declare_pass( DeadInstElimination ) -declare_pass( DemoteRegisterToMemory ) -declare_pass( DomOnlyPrinter ) -declare_pass( DomOnlyViewer ) -declare_pass( DomPrinter ) -declare_pass( DomViewer ) -declare_pass( EdgeProfiler ) -//declare_pass( GEPSplitter ) -declare_pass( GlobalsModRef ) -declare_pass( InstCount ) -declare_pass( InstructionNamer ) -declare_pass( LazyValueInfo ) -declare_pass( LCSSA ) -//declare_pass( LiveValues ) -declare_pass( LoopDependenceAnalysis ) -declare_pass( LoopExtractor ) -declare_pass( LoopSimplify ) -declare_pass( LoopStrengthReduce ) -declare_pass( LowerInvoke ) -declare_pass( LowerSwitch ) -declare_pass( MergeFunctions ) -declare_pass( NoAA ) -declare_pass( NoProfileInfo ) -declare_pass( OptimalEdgeProfiler ) -declare_pass( PartialInlining ) -//declare_pass( PartialSpecialization ) -declare_pass( PostDomOnlyPrinter ) -declare_pass( PostDomOnlyViewer ) -declare_pass( PostDomPrinter ) -declare_pass( PostDomViewer ) -declare_pass( ProfileEstimator ) -declare_pass( ProfileLoader ) -declare_pass( ProfileVerifier ) -declare_pass( ScalarEvolutionAliasAnalysis ) -declare_pass( SimplifyHalfPowrLibCalls ) -declare_pass( SingleLoopExtractor ) -declare_pass( StripNonDebugSymbols ) -declare_pass( StructRetPromotion ) -declare_pass( TailDuplication ) -declare_pass( UnifyFunctionExitNodes ) - -declare_pass( Internalize2 ) -*/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LLVM_PY_EXTRA_H */ - diff --git a/llvm/llvm_c_extra.h b/llvm/llvm_c_extra.h deleted file mode 100644 index 5728875..0000000 --- a/llvm/llvm_c_extra.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef LLVM_C_EXTRA_H_ -#define LLVM_C_EXTRA_H_ - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - -// Resurrect from llvm-c/Core.h -#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \ -inline ty *unwrap(ref P) { \ - return reinterpret_cast(P); \ -} \ - \ -inline ref wrap(const ty *P) { \ - return reinterpret_cast(const_cast(P)); \ -} - -typedef struct LLVMOpaqueEngineBuilder *LLVMEngineBuilderRef; -typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; -typedef struct LLVMOpaqueNamedMD *LLVMNamedMDRef; -typedef struct LLVMOpaquePass *LLVMPassRef; - -#ifdef __cplusplus - } -#endif - -#endif //LLVM_C_EXTRA_H_ - diff --git a/llvm/passes.py b/llvm/passes.py index 4d7efb4..9f706d8 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -37,122 +37,99 @@ are available. import llvm # top-level, for common stuff import llvm.core as core # module, function etc. -import llvm._core as _core # C wrappers -import llvm._util as _util # Utility functions +from llvmpy import api -import warnings #===----------------------------------------------------------------------=== # Pass manager builder #===----------------------------------------------------------------------=== -class PassManagerBuilder(object): +class PassManagerBuilder(llvm.Wrapper): @staticmethod def new(): - return PassManagerBuilder(_core.LLVMPassManagerBuilderCreate()) - - def __init__(self, ptr): - self.ptr = ptr - - def __del__(self): - _core.LLVMPassManagerBuilderDispose(self.ptr) + return PassManagerBuilder(api.llvm.PassManagerBuilder.new()) def populate(self, pm): if isinstance(pm, FunctionPassManager): - return _core.LLVMPassManagerBuilderPopulateFunctionPassManager( - self.ptr, pm.ptr) + self._ptr.populateFunctionPassManager(pm._ptr) else: - return _core.LLVMPassManagerBuilderPopulateModulePassManager( - self.ptr, pm.ptr) + self._ptr.populateModulePassManager(pm._ptr) + @property + def opt_level(self): + return self._ptr.OptLevel - def _set_opt_level(self, optlevel): - _core.LLVMPassManagerBuilderSetOptLevel(self.ptr, optlevel) + @opt_level.setter + def opt_level(self, optlevel): + self._ptr.OptLevel = optlevel - def _get_opt_level(self): - return _core.LLVMPassManagerBuilderGetOptLevel(self.ptr) + @property + def size_level(self): + return self._ptr.SizeLevel - opt_level = property(_get_opt_level, _set_opt_level) + @size_level.setter + def size_level(self, sizelevel): + self._ptr.SizeLevel = sizelevel - def _set_size_level(self, sizelevel): - _core.LLVMPassManagerBuilderSetSizeLevel(self.ptr, sizelevel) + @property + def vectorize(self): + return self._ptr.Vectorize - def _get_size_level(self): - return _core.LLVMPassManagerBuilderGetSizeLevel(self.ptr) + @vectorize.setter + def vectorize(self, enable): + self._ptr.Vectorize = enable + - size_level = property(_get_size_level, _set_size_level) - - def _set_vectorize(self, enable): - _core.LLVMPassManagerBuilderSetVectorize(self.ptr, int(bool(enable))) - - def _get_vectorize(self): - return bool(_core.LLVMPassManagerBuilderGetVectorize(self.ptr)) - - vectorize = property(_get_vectorize, _set_vectorize) - - def _set_loop_vectorize(self, enable): - if llvm.version >= (3, 2): - _core.LLVMPassManagerBuilderSetLoopVectorize(self.ptr, - int(bool(enable))) - elif enable: - warnings.warn("Ignored. LLVM-3.1 & prior do not support loop vectorizer.") - - def _get_loop_vectorize(self): + @property + def loop_vectorize(self): try: - return bool(_core.LLVMPassManagerBuilderGetLoopVectorize(self.ptr)) + return self._ptr.LoopVectorize except AttributeError: return False - loop_vectorize = property(_get_loop_vectorize, _set_loop_vectorize) + @loop_vectorize.setter + def loop_vectorize(self, enable): + if llvm.version >= (3, 2): + self._ptr.LoopVectorize = enable + elif enable: + warnings.warn("Ignored. LLVM-3.1 & prior do not support loop vectorizer.") - def _set_disable_unit_at_a_time(self, disable): - return _core.LLVMPassManagerBuilderSetDisableUnitAtATime( - self.ptr, disable) + @property + def disable_unit_at_a_time(self): + return self._ptr.DisableUnitAtATime - def _get_disable_unit_at_a_time(self): - return _core.LLVMPassManagerBuilderGetDisableUnitAtATime( - self.ptr) + @disable_unit_at_a_time.setter + def disable_unit_at_a_time(self, disable): + self._ptr.DisableUnitAtATime = disable - disable_unit_at_a_time = property(_get_disable_unit_at_a_time, - _set_disable_unit_at_a_time) + @property + def disable_unroll_loops(self): + return self._ptr.DisableUnrollLoops - def _set_disable_unroll_loops(self, disable): - return _core.LLVMPassManagerBuilderGetDisableUnrollLoops( - self.ptr, disable) + @disable_unroll_loops.setter + def disable_unroll_loops(self, disable): + self._ptr.DisableUnrollLoops = disable - def _get_disable_unroll_loops(self): - return _core.LLVMPassManagerBuilderGetDisableUnrollLoops(self.ptr) + @property + def disable_simplify_lib_calls(self): + return self._ptr.DisableSimplifyLibCalls - disable_unroll_loops = property(_get_disable_unroll_loops, - _set_disable_unroll_loops) - - def _set_disable_simplify_lib_calls(self, disable): - return _core.LLVMPassManagerBuilderGetDisableSimplifyLibCalls( - self.ptr, disable) - - def _get_disable_simplify_lib_calls(self): - return _core.LLVMPassManagerBuilderGetDisableSimplifyLibCalls(self.ptr) - - disable_simplify_lib_calls = property(_get_disable_simplify_lib_calls, - _set_disable_simplify_lib_calls) + @disable_simplify_lib_calls.setter + def disable_simplify_lib_calls(self, disable): + self._ptr.DisableSimplifyLibCalls = disable def use_inliner_with_threshold(self, threshold): - _core.LLVMPassManagerBuilderUseInlinerWithThreshold(self.ptr, threshold) + self._ptr.Inliner = api.llvm.createFunctionInliningPass(threshold) + #===----------------------------------------------------------------------=== # Pass manager #===----------------------------------------------------------------------=== -class PassManager(object): +class PassManager(llvm.Wrapper): @staticmethod def new(): - return PassManager(_core.LLVMCreatePassManager()) - - def __init__(self, ptr): - self.ptr = ptr - - def __del__(self): - _core.LLVMDisposePassManager(self.ptr) + return PassManager(api.llvm.PassManager.new()) def add(self, pass_obj): '''Add a pass to the pass manager. @@ -160,68 +137,59 @@ class PassManager(object): pass_obj --- Either a Pass instance, a string name of a pass ''' if isinstance(pass_obj, Pass): - _util.check_is_unowned(pass_obj) - _core.LLVMAddPass(self.ptr, pass_obj.ptr) - pass_obj._own(self) # PassManager owns the pass - elif _util.isstring(pass_obj): - self._add_pass(pass_obj) + self._ptr.add(pass_obj._ptr) else: - raise llvm.LLVMException("invalid pass_id (%s)" % pass_obj) + self._add_pass(str(pass_obj)) def _add_pass(self, pass_name): - status = _core.LLVMAddPassByName(self.ptr, pass_name) - if not status: + passreg = api.llvm.PassRegistry.getPassRegistry() + a_pass = passreg.getPassInfo(pass_name).createPass() + if not a_pass: assert pass_name not in PASSES, "Registered but not found?" raise llvm.LLVMException('Invalid pass name "%s"' % pass_name) + self._ptr.add(a_pass) def run(self, module): - core.check_is_module(module) - return _core.LLVMRunPassManager(self.ptr, module.ptr) + return self._ptr.run(module._ptr) class FunctionPassManager(PassManager): @staticmethod def new(module): - core.check_is_module(module) - ptr = _core.LLVMCreateFunctionPassManagerForModule(module.ptr) + ptr = api.llvm.FunctionPassManager.new(module._ptr) return FunctionPassManager(ptr) def __init__(self, ptr): PassManager.__init__(self, ptr) def initialize(self): - _core.LLVMInitializeFunctionPassManager(self.ptr) + self._ptr.doInitialization() def run(self, fn): - core.check_is_function(fn) - return _core.LLVMRunFunctionPassManager(self.ptr, fn.ptr) + return self._ptr.run(fn._ptr) def finalize(self): - _core.LLVMFinalizeFunctionPassManager(self.ptr) - - + self._ptr.doFinalization() #===----------------------------------------------------------------------=== # Passes #===----------------------------------------------------------------------=== -class Pass(llvm.Ownable): +class Pass(llvm.Wrapper): '''Pass Inferface - ''' - def __init__(self, ptr): - llvm.Ownable.__init__(self, ptr, _core.LLVMDisposePass) - self.__name = '' + ''' @staticmethod def new(name): '''Create a new pass by name. - Note: Not all pass has a default constructor. LLVM will kill - the process if an the pass requires arguments to construct. - The error cannot be caught. - ''' - ptr = _core.LLVMCreatePassByName(name) - p = Pass(ptr) + Note: Not all pass has a default constructor. LLVM will kill + the process if an the pass requires arguments to construct. + The error cannot be caught. + ''' + passreg = api.llvm.PassRegistry.getPassRegistry() + a_pass = passreg.getPassInfo(name).createPass() + p = Pass(a_pass) p.__name = name return p @@ -229,15 +197,17 @@ class Pass(llvm.Ownable): def name(self): '''The name used in PassRegistry. ''' - return self.__name + try: + return self.__name + except AttributeError: + return @property def description(self): - return _core.LLVMGetPassName(self.ptr) + return self._ptr.getPassName() def dump(self): - return _core.LLVMPassDump(self.ptr) - + return self._ptr.dump() #===----------------------------------------------------------------------=== # Target data @@ -247,67 +217,59 @@ class TargetData(Pass): @staticmethod def new(strrep): - return TargetData(_core.LLVMCreateTargetData(strrep)) + ptr = api.llvm.DataLayout.new(strrep) + return TargetData(ptr) def clone(self): return TargetData.new(str(self)) def __str__(self): - return _core.LLVMTargetDataAsString(self.ptr) + return self._ptr.getStringRepresentation() @property def byte_order(self): - return _core.LLVMByteOrder(self.ptr) + if self._ptr.isLittleEndian(): + return 1 + else: + return 0 @property def pointer_size(self): - return _core.LLVMPointerSize(self.ptr) + return self._ptr.getPointerSize() @property def target_integer_type(self): - ptr = _core.LLVMIntPtrType(self.ptr); - return core.IntegerType(ptr, core.TYPE_INTEGER) + context = api.llvm.getGlobalContext() + return api.llvm.IntegerType(api.llvm.Type.getInt32Ty(context)) def size(self, ty): - core.check_is_type(ty) - return _core.LLVMSizeOfTypeInBits(self.ptr, ty.ptr) + return self._ptr.getTypeSizeInBits(ty._ptr) def store_size(self, ty): - core.check_is_type(ty) - return _core.LLVMStoreSizeOfType(self.ptr, ty.ptr) + return self._ptr.getTypeStoreSize(ty._ptr) def abi_size(self, ty): - core.check_is_type(ty) - return _core.LLVMABISizeOfType(self.ptr, ty.ptr) + return self._ptr.getTypeAllocSize(ty._ptr) def abi_alignment(self, ty): - core.check_is_type(ty) - return _core.LLVMABIAlignmentOfType(self.ptr, ty.ptr) + return self._ptr.getABITypeAlignment(ty._ptr) def callframe_alignment(self, ty): - core.check_is_type(ty) - return _core.LLVMCallFrameAlignmentOfType(self.ptr, ty.ptr) + return self._ptr.getCallFrameTypeAlignment(ty._ptr) def preferred_alignment(self, ty_or_gv): if isinstance(ty_or_gv, core.Type): - return _core.LLVMPreferredAlignmentOfType(self.ptr, - ty_or_gv.ptr) + return self._ptr.getPrefTypeAlignment(ty_or_gv._ptr) elif isinstance(ty_or_gv, core.GlobalVariable): - return _core.LLVMPreferredAlignmentOfGlobal(self.ptr, - ty_or_gv.ptr) + return self._ptr.getPreferredAlignment(ty_or_gv._ptr) else: raise core.LLVMException("argument is neither a type nor a global variable") def element_at_offset(self, ty, ofs): - core.check_is_type_struct(ty) - ofs = int(ofs) # ofs is unsigned long long - return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs) + return self._ptr.getStructLayout(ty._ptr).getElementContainingOffset(ofs) def offset_of_element(self, ty, el): - core.check_is_type_struct(ty) - el = int(el) # el should be an int - return _core.LLVMOffsetOfElement(self.ptr, ty.ptr, el) - + return self._ptr.getStructLayout(ty._ptr).getElementOffset(el) #===----------------------------------------------------------------------=== # Target Library Info @@ -316,19 +278,20 @@ class TargetData(Pass): class TargetLibraryInfo(Pass): @staticmethod def new(triple): - ptr = _core.LLVMCreateTargetLibraryInfo(triple) + triple = api.llvm.Triple.new(str(triple)) + ptr = api.llvm.TargetLibraryInfo.new(triple) return TargetLibraryInfo(ptr) - #===----------------------------------------------------------------------=== -# Target Transform Info +# Target Transformation Info #===----------------------------------------------------------------------=== class TargetTransformInfo(Pass): @staticmethod def new(targetmachine): - llvm.require_version_at_least(3, 2) - ptr = _core.LLVMCreateTargetTransformInfo(targetmachine.ptr) + scalartti = targetmachine._ptr.getScalarTargetTransformInfo() + vectortti = targetmachine._ptr.getVectorTargetTransformInfo() + ptr = api.llvm.TargetTransformInfo.new(scalartti, vectortti) return TargetTransformInfo(ptr) @@ -339,18 +302,18 @@ class TargetTransformInfo(Pass): def build_pass_managers(tm, opt=2, loop_vectorize=False, vectorize=False, inline_threshold=2000, pm=True, fpm=True, mod=None): ''' - tm --- The TargetMachine for which the passes are optimizing for. - The TargetMachine must stay alive until the pass managers - are removed. - opt --- [0-3] Optimization level. Default to 2. - loop_vectorize --- [boolean] Whether to use loop-vectorizer. - vectorize --- [boolean] Whether to use basic-block vectorizer. - inline_threshold --- [int] Threshold for the inliner. - features --- [str] CPU feature string. - pm --- [boolean] Whether to build a module-level pass-manager. - fpm --- [boolean] Whether to build a function-level pass-manager. - mod --- [Module] The module object for the FunctionPassManager. - ''' + tm --- The TargetMachine for which the passes are optimizing for. + The TargetMachine must stay alive until the pass managers + are removed. + opt --- [0-3] Optimization level. Default to 2. + loop_vectorize --- [boolean] Whether to use loop-vectorizer. + vectorize --- [boolean] Whether to use basic-block vectorizer. + inline_threshold --- [int] Threshold for the inliner. + features --- [str] CPU feature string. + pm --- [boolean] Whether to build a module-level pass-manager. + fpm --- [boolean] Whether to build a function-level pass-manager. + mod --- [Module] The module object for the FunctionPassManager. + ''' if pm: pm = PassManager.new() if fpm: @@ -383,7 +346,6 @@ def build_pass_managers(tm, opt=2, loop_vectorize=False, vectorize=False, from collections import namedtuple return namedtuple('passmanagers', ['pm', 'fpm'])(pm=pm, fpm=fpm) - #===----------------------------------------------------------------------=== # Misc. #===----------------------------------------------------------------------=== @@ -392,16 +354,26 @@ def build_pass_managers(tm, opt=2, loop_vectorize=False, vectorize=False, PASSES = None def _dump_all_passes(): - passes_sep_by_line = _core.LLVMDumpPasses() - strip = lambda S : S.strip() - for line in passes_sep_by_line.splitlines(): - passarg, passname = map(strip, line.split('\t', 1)) - if passarg: - yield passarg, passname + passreg = api.llvm.PassRegistry.getPassRegistry() + for name, desc in passreg.enumerate(): + yield name, desc def _initialize_passes(): global PASSES - _core.LLVMInitializePasses() + + passreg = api.llvm.PassRegistry.getPassRegistry() + + api.llvm.initializeCore(passreg) + api.llvm.initializeScalarOpts(passreg) + api.llvm.initializeVectorization(passreg) + api.llvm.initializeIPO(passreg) + api.llvm.initializeAnalysis(passreg) + api.llvm.initializeIPA(passreg) + api.llvm.initializeTransformUtils(passreg) + api.llvm.initializeInstCombine(passreg) + api.llvm.initializeInstrumentation(passreg) + api.llvm.initializeTarget(passreg) + PASSES = dict(_dump_all_passes()) # build globals diff --git a/llvm/py3k_update.diff b/llvm/py3k_update.diff deleted file mode 100644 index 2bb11a9..0000000 --- a/llvm/py3k_update.diff +++ /dev/null @@ -1,973 +0,0 @@ ---- .\setup-win32.py (original) -+++ .\setup-win32.py (refactored) -@@ -145,10 +145,10 @@ - - # get llvm config - llvm_dir, llvm_build_dir, is_good = get_llvm_config() -- print "Using llvm-dir=" + llvm_dir + " and llvm-build-dir=" + llvm_build_dir -+ print("Using llvm-dir=" + llvm_dir + " and llvm-build-dir=" + llvm_build_dir) - if not is_good: -- print "Cannot find llvm-dir or llvm-build-dir" -- print "Try again with --llvm-dir=/path/to/llvm-top-dir --llvm-build-dir=/path/to/llvm/cmake/dir." -+ print("Cannot find llvm-dir or llvm-build-dir") -+ print("Try again with --llvm-dir=/path/to/llvm-top-dir --llvm-build-dir=/path/to/llvm/cmake/dir.") - return 1 - - # setup ---- .\setup.py (original) -+++ .\setup.py (refactored) -@@ -120,10 +120,10 @@ - # get llvm config - llvm_config, is_good = get_llvm_config() - if is_good: -- print "Using llvm-config=" + llvm_config -+ print("Using llvm-config=" + llvm_config) - else: -- print "Cannot invoke llvm-config (tried '%s')." % llvm_config -- print "Try again with --llvm-config=/path/to/llvm-config." -+ print("Cannot invoke llvm-config (tried '%s')." % llvm_config) -+ print("Try again with --llvm-config=/path/to/llvm-config.") - return 1 - - # setup ---- .\llvm\__init__.py (original) -+++ .\llvm\__init__.py (refactored) -@@ -68,12 +68,12 @@ - - def _own(self, owner): - if self.owner: -- raise LLVMException, "object already owned" -+ raise LLVMException("object already owned") - self.owner = owner - - def _disown(self): - if not self.owner: -- raise LLVMException, "not owned" -+ raise LLVMException("not owned") - self.owner = None - - def __del__(self): -@@ -135,15 +135,13 @@ - # Cacheables - #===----------------------------------------------------------------------=== - --class Cacheable(object): -+class Cacheable(object, metaclass=_ObjectCache): - """Objects that can be cached. - - Objects that wrap a PyCObject are cached to avoid "aliasing", i.e., - two Python objects each containing a PyCObject which internally points - to the same C pointer.""" - -- __metaclass__ = _ObjectCache -- - def forget(self): - _ObjectCache.forget(self) - ---- .\llvm\_util.py (original) -+++ .\llvm\_util.py (refactored) -@@ -45,11 +45,11 @@ - if not isinstance(obj, typ): - typ_str = typ.__name__ - msg = "argument not an instance of llvm.core.%s" % typ_str -- raise TypeError, msg -+ raise TypeError(msg) - - def check_is_unowned(ownable): - if ownable.owner: -- raise llvm.LLVMException, "object is already owned" -+ raise llvm.LLVMException("object is already owned") - - - #===----------------------------------------------------------------------=== ---- .\llvm\core.py (original) -+++ .\llvm\core.py (refactored) -@@ -297,7 +297,7 @@ - if isinstance(typ, PointerType) and \ - isinstance(typ.pointee, FunctionType): - return -- raise TypeError, "argument is neither a function nor a function pointer" -+ raise TypeError("argument is neither a function nor a function pointer") - - def _to_int(v): - if v: -@@ -341,9 +341,9 @@ - data = fileobj.read() - ret = _core.LLVMGetModuleFromBitcode(data) - if not ret: -- raise llvm.LLVMException, "Unable to create module from bitcode" -+ raise llvm.LLVMException("Unable to create module from bitcode") - elif isinstance(ret, str): -- raise llvm.LLVMException, ret -+ raise llvm.LLVMException(ret) - else: - return Module(ret) - -@@ -355,10 +355,9 @@ - data = fileobj.read() - ret = _core.LLVMGetModuleFromAssembly(data) - if not ret: -- raise llvm.LLVMException, \ -- "Unable to create module from assembly" -+ raise llvm.LLVMException("Unable to create module from assembly") - elif isinstance(ret, str): -- raise llvm.LLVMException, ret -+ raise llvm.LLVMException(ret) - else: - return Module(ret) - -@@ -437,7 +436,7 @@ - other.forget() # remove it from object cache - ret = _core.LLVMLinkModules(self.ptr, other.ptr) - if isinstance(ret, str): -- raise llvm.LLVMException, ret -+ raise llvm.LLVMException(ret) - # Do not try to destroy the other module's llvm::Module*. - other._own(llvm.DummyOwner()) - -@@ -506,7 +505,7 @@ - error.""" - ret = _core.LLVMVerifyModule(self.ptr) - if ret != "": -- raise llvm.LLVMException, ret -+ raise llvm.LLVMException(ret) - - def to_bitcode(self, fileobj): - """Write bitcode representation of module to given file-like -@@ -514,7 +513,7 @@ - - data = _core.LLVMGetBitcodeFromModule(self.ptr) - if not data: -- raise llvm.LLVMException, "Unable to create bitcode" -+ raise llvm.LLVMException("Unable to create bitcode") - fileobj.write(data) - - -@@ -1236,7 +1235,7 @@ - check_is_module(module) - ptr = _core.LLVMGetNamedGlobal(module.ptr, name) - if not ptr: -- raise llvm.LLVMException, ("no global named `%s`" % name) -+ raise llvm.LLVMException("no global named `%s`" % name) - return _make_value(ptr) - - def delete(self): -@@ -1307,7 +1306,7 @@ - check_is_module(module) - ptr = _core.LLVMGetNamedFunction(module.ptr, name) - if not ptr: -- raise llvm.LLVMException, ("no function named `%s`" % name) -+ raise llvm.LLVMException("no function named `%s`" % name) - return _make_value(ptr) - - @staticmethod -@@ -2006,7 +2005,7 @@ - - ret = _core.LLVMLoadLibraryPermanently(filename) - if isinstance(ret, str): -- raise llvm.LLVMException, ret -+ raise llvm.LLVMException(ret) - - def inline_function(call): - check_is_value(call) ---- .\llvm\ee.py (original) -+++ .\llvm\ee.py (refactored) -@@ -103,12 +103,11 @@ - return _core.LLVMPreferredAlignmentOfGlobal(self.ptr, - ty_or_gv.ptr) - else: -- raise core.LLVMException, \ -- "argument is neither a type nor a global variable" -+ raise core.LLVMException("argument is neither a type nor a global variable") - - def element_at_offset(self, ty, ofs): - core.check_is_type_struct(ty) -- ofs = long(ofs) # ofs is unsigned long long -+ ofs = int(ofs) # ofs is unsigned long long - return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs) - - def offset_of_element(self, ty, el): -@@ -185,7 +184,7 @@ - _util.check_is_unowned(module) - ret = _core.LLVMCreateExecutionEngine(module.ptr, int(force_interpreter)) - if isinstance(ret, str): -- raise llvm.LLVMException, ret -+ raise llvm.LLVMException(ret) - return ExecutionEngine(ret, module) - - def __init__(self, ptr, module): -@@ -223,10 +222,10 @@ - def remove_module(self, module): - core.check_is_module(module) - if module.owner != self: -- raise llvm.LLVMException, "module is not owned by self" -+ raise llvm.LLVMException("module is not owned by self") - ret = _core.LLVMRemoveModule2(self.ptr, module.ptr) - if isinstance(ret, str): -- raise llvm.LLVMException, ret -+ raise llvm.LLVMException(ret) - return core.Module(ret) - - @property ---- .\llvm\passes.py (original) -+++ .\llvm\passes.py (refactored) -@@ -245,8 +245,7 @@ - elif tgt_data_or_pass_id in _pass_creator: - self._add_pass(tgt_data_or_pass_id) - else: -- raise llvm.LLVMException, \ -- ("invalid pass_id (%s)" % str(tgt_data_or_pass_id)) -+ raise llvm.LLVMException("invalid pass_id (%s)" % str(tgt_data_or_pass_id)) - - def _add_target_data(self, tgt): - _core.LLVMAddTargetData(tgt.ptr, self.ptr) ---- .\test\JITTutorial1.py (original) -+++ .\test\JITTutorial1.py (refactored) -@@ -28,4 +28,4 @@ - - bldr.ret (tmp_2) - --print module -+print(module) ---- .\test\JITTutorial2.py (original) -+++ .\test\JITTutorial2.py (refactored) -@@ -47,4 +47,4 @@ - recur_2 = bldr.call (gcd, (x_sub_y, y,), "tmp") - bldr.ret (recur_2) - --print module -+print(module) ---- .\test\asm.py (original) -+++ .\test\asm.py (refactored) -@@ -9,9 +9,9 @@ - - # write it's assembly representation to a file - asm = str(m) --print >> file("/tmp/testasm.ll", "w"), asm -+print(asm, file=file("/tmp/testasm.ll", "w")) - - # read it back into a module - m2 = Module.from_assembly(file("/tmp/testasm.ll")) --print m2 -+print(m2) - ---- .\test\call-jit-ctypes.py (original) -+++ .\test\call-jit-ctypes.py (refactored) -@@ -42,7 +42,7 @@ - - if 0: - # print the created module -- print my_module -+ print(my_module) - - # compile the function - ee = ExecutionEngine.new(my_module) ---- .\test\example-jit.py (original) -+++ .\test\example-jit.py (refactored) -@@ -29,5 +29,5 @@ - retval = ee.run_function(f_sum, [arg1, arg2]) - - # The return value is also GenericValue. Let's print it. --print "returned", retval.as_int() -+print("returned", retval.as_int()) - ---- .\test\example.py (original) -+++ .\test\example.py (refactored) -@@ -41,5 +41,5 @@ - - # We've completed the definition now! Let's see the LLVM assembly - # language representation of what we've created: --print my_module -+print(my_module) - ---- .\test\intrinsic.py (original) -+++ .\test\intrinsic.py (refactored) -@@ -16,7 +16,7 @@ - val = Constant.int(Type.int(), 42) - bswap = Function.intrinsic(mod, INTR_BSWAP, [Type.int()]) - b.call(bswap, [val]) --print mod -+print(mod) - - # the output is: - # -@@ -50,7 +50,7 @@ - onemc2 = b.sub(one, cos2, "onemc2") - sin = b.call(sqrt, [onemc2], "sin") - b.ret(sin) --print mod -+print(mod) - - # - # ; ModuleID = 'test' ---- .\test\objcache.py (original) -+++ .\test\objcache.py (refactored) -@@ -4,17 +4,17 @@ - - def check(a, b): - if a is b: -- print "OK" -+ print("OK") - else: -- print "FAIL" -+ print("FAIL") - - def check_isnot(a, b): - if not (a is b): -- print "OK" -+ print("OK") - else: -- print "FAIL" -+ print("FAIL") - --print "Testing module aliasing ..", -+print("Testing module aliasing ..", end=' ') - m1 = Module.new('a') - t = Type.int() - ft = Type.function(t, [t]) -@@ -22,75 +22,75 @@ - m2 = f1.module - check(m1, m2) - --print "Testing global vairable aliasing 1 .. ", -+print("Testing global vairable aliasing 1 .. ", end=' ') - gv1 = GlobalVariable.new(m1, t, "gv") - gv2 = GlobalVariable.get(m1, "gv") - check(gv1, gv2) - --print "Testing global vairable aliasing 2 .. ", -+print("Testing global vairable aliasing 2 .. ", end=' ') - gv3 = m1.global_variables[0] - check(gv1, gv3) - --print "Testing global vairable aliasing 3 .. ", -+print("Testing global vairable aliasing 3 .. ", end=' ') - gv2 = None - gv3 = None - gv1.delete() - gv4 = GlobalVariable.new(m1, t, "gv") - check_isnot(gv1, gv4) - --print "Testing function aliasing 1 ..", -+print("Testing function aliasing 1 ..", end=' ') - b1 = f1.append_basic_block('entry') - f2 = b1.function - check(f1, f2) - --print "Testing function aliasing 2 ..", -+print("Testing function aliasing 2 ..", end=' ') - f3 = m1.get_function_named("func") - check(f1, f3) - --print "Testing function aliasing 3 ..", -+print("Testing function aliasing 3 ..", end=' ') - f4 = Function.get_or_insert(m1, ft, "func") - check(f1, f4) - --print "Testing function aliasing 4 ..", -+print("Testing function aliasing 4 ..", end=' ') - f5 = Function.get(m1, "func") - check(f1, f5) - --print "Testing function aliasing 5 ..", -+print("Testing function aliasing 5 ..", end=' ') - f6 = m1.get_or_insert_function(ft, "func") - check(f1, f6) - --print "Testing function aliasing 6 ..", -+print("Testing function aliasing 6 ..", end=' ') - f7 = m1.functions[0] - check(f1, f7) - --print "Testing argument aliasing .. ", -+print("Testing argument aliasing .. ", end=' ') - a1 = f1.args[0] - a2 = f1.args[0] - check(a1, a2) - --print "Testing basic block aliasing 1 .. ", -+print("Testing basic block aliasing 1 .. ", end=' ') - b2 = f1.basic_blocks[0] - check(b1, b2) - --print "Testing basic block aliasing 2 .. ", -+print("Testing basic block aliasing 2 .. ", end=' ') - b3 = f1.get_entry_basic_block() - check(b1, b3) - --print "Testing basic block aliasing 3 .. ", -+print("Testing basic block aliasing 3 .. ", end=' ') - b31 = f1.entry_basic_block - check(b1, b31) - --print "Testing basic block aliasing 4 .. ", -+print("Testing basic block aliasing 4 .. ", end=' ') - bldr = Builder.new(b1) - b4 = bldr.basic_block - check(b1, b4) - --print "Testing basic block aliasing 5 .. ", -+print("Testing basic block aliasing 5 .. ", end=' ') - i1 = bldr.ret_void() - b5 = i1.basic_block - check(b1, b5) - --print "Testing instruction aliasing 1 .. ", -+print("Testing instruction aliasing 1 .. ", end=' ') - i2 = b5.instructions[0] - check(i1, i2) - -@@ -100,9 +100,9 @@ - v2 = phi.get_incoming_value(0) - b6 = phi.get_incoming_block(0) - --print "Testing PHI / basic block aliasing 5 .. ", -+print("Testing PHI / basic block aliasing 5 .. ", end=' ') - check(b1, b6) - --print "Testing PHI / value aliasing .. ", -+print("Testing PHI / value aliasing .. ", end=' ') - check(f1.args[0], v2) - ---- .\test\operands.py (original) -+++ .\test\operands.py (refactored) -@@ -28,9 +28,9 @@ - def __init__(self): pass - def read(self): return test_module - m = Module.from_assembly(strstream()) --print "-"*60 --print m --print "-"*60 -+print("-"*60) -+print(m) -+print("-"*60) - - test_func = m.get_function_named("test_func") - prod = m.get_function_named("prod") -@@ -38,16 +38,16 @@ - #===----------------------------------------------------------------------=== - # test operands - --print -+print() - i1 = test_func.basic_blocks[0].instructions[0] - i2 = test_func.basic_blocks[0].instructions[1] --print "Testing User.operand_count ..", -+print("Testing User.operand_count ..", end=' ') - if i1.operand_count == 3 and i2.operand_count == 2: -- print "OK" -+ print("OK") - else: -- print "FAIL" -+ print("FAIL") - --print "Testing User.operands ..", -+print("Testing User.operands ..", end=' ') - c1 = i1.operands[0] is prod - c2 = i1.operands[1] is test_func.args[0] - c3 = i1.operands[2] is test_func.args[1] -@@ -56,22 +56,22 @@ - c6 = len(i1.operands) == 3 - c7 = len(i2.operands) == 2 - if c1 and c2 and c3 and c5 and c6 and c7: -- print "OK" -+ print("OK") - else: -- print "FAIL" --print -+ print("FAIL") -+print() - - #===----------------------------------------------------------------------=== - # show test_function - --print "Examining test_function `test_test_func':" -+print("Examining test_function `test_test_func':") - idx = 1 - for inst in test_func.basic_blocks[0].instructions: -- print "Instruction #%d:" % (idx,) -- print " operand_count =", inst.operand_count -- print " operands:" -+ print("Instruction #%d:" % (idx,)) -+ print(" operand_count =", inst.operand_count) -+ print(" operands:") - oidx = 1 - for op in inst.operands: -- print " %d: %s" % (oidx, repr(op)) -+ print(" %d: %s" % (oidx, repr(op))) - oidx += 1 - idx += 1 ---- .\test\passes.py (original) -+++ .\test\passes.py (refactored) -@@ -36,8 +36,8 @@ - } - """ - m = Module.from_assembly(strstream(asm)) --print "-"*72 --print m -+print("-"*72) -+print(m) - - # Let's run a module-level inlining pass. First, create a pass manager. - pm = PassManager.new() -@@ -55,8 +55,8 @@ - del pm - - # Print the result. Note the change in @test2. --print "-"*72 --print m -+print("-"*72) -+print(m) - - - # Let's run a DCE pass on the the function 'test1' now. First create a -@@ -73,5 +73,5 @@ - fpm.run( m.get_function_named('test1') ) - - # Print the result. Note the change in @test1. --print "-"*72 --print m -+print("-"*72) -+print(m) ---- .\test\test.py (original) -+++ .\test\test.py (refactored) -@@ -69,7 +69,7 @@ - - # done - if gc.garbage: -- print "garbage = ", gc.garbage -+ print("garbage = ", gc.garbage) - - - main() ---- .\test\testall.py (original) -+++ .\test\testall.py (refactored) -@@ -15,12 +15,12 @@ - - - def do_llvmexception(): -- print " Testing class LLVMException" -+ print(" Testing class LLVMException") - e = LLVMException() - - - def do_ownable(): -- print " Testing class Ownable" -+ print(" Testing class Ownable") - o = Ownable(None, lambda x: None) - try: - o._own(None) -@@ -30,7 +30,7 @@ - - - def do_misc(): -- print " Testing miscellaneous functions" -+ print(" Testing miscellaneous functions") - try: - load_library_permanently("/usr/lib/libm.so") - except LLVMException: -@@ -42,14 +42,14 @@ - - - def do_llvm(): -- print " Testing module llvm" -+ print(" Testing module llvm") - do_llvmexception() - do_ownable() - do_misc() - - - def do_module(): -- print " Testing class Module" -+ print(" Testing class Module") - m = Module.new('test') - m.target = 'a' - a = m.target -@@ -101,7 +101,7 @@ - - - def do_type(): -- print " Testing class Type" -+ print(" Testing class Type") - for i in range(1,100): - Type.int(i) - Type.float() -@@ -151,14 +151,14 @@ - - - def do_typehandle(): -- print " Testing class TypeHandle" -+ print(" Testing class TypeHandle") - th = TypeHandle.new(Type.opaque()) - ts = Type.struct([ Type.int(), Type.pointer(th.type) ]) - th.type.refine(ts) - - - def do_value(): -- print " Testing class Value" -+ print(" Testing class Value") - k = Constant.int(ti, 42) - k.name = 'a' - s = k.name -@@ -186,7 +186,7 @@ - - - def do_constant(): -- print " Testing class Constant" -+ print(" Testing class Constant") - Constant.null(ti) - Constant.all_ones(ti) - Constant.undef(ti) -@@ -231,7 +231,7 @@ - - - def do_global_value(): -- print " Testing class GlobalValue" -+ print(" Testing class GlobalValue") - m = Module.new('a') - gv = GlobalVariable.new(m, Type.int(), 'b') - s = gv.is_declaration -@@ -247,7 +247,7 @@ - - - def do_global_variable(): -- print " Testing class GlobalVariable" -+ print(" Testing class GlobalVariable") - m = Module.new('a') - gv = GlobalVariable.new(m, Type.int(), 'b') - gv = GlobalVariable.get(m, 'b') -@@ -260,7 +260,7 @@ - - - def do_argument(): -- print " Testing class Argument" -+ print(" Testing class Argument") - m = Module.new('a') - ft = Type.function(ti, [ti]) - f = Function.new(m, ft, 'func') -@@ -272,7 +272,7 @@ - - - def do_function(): -- print " Testing class Function" -+ print(" Testing class Function") - ft = Type.function(ti, [ti]*20) - zz = Function.new(Module.new('z'), ft, 'foobar') - del zz -@@ -307,7 +307,7 @@ - - - def do_instruction(): -- print " Testing class Instruction" -+ print(" Testing class Instruction") - m = Module.new('a') - ft = Type.function(ti, [ti]*20) - f = Function.new(m, ft, 'func') -@@ -320,7 +320,7 @@ - - - def do_callorinvokeinstruction(): -- print " Testing class CallOrInvokeInstruction" -+ print(" Testing class CallOrInvokeInstruction") - m = Module.new('a') - ft = Type.function(ti, [ti]) - f = Function.new(m, ft, 'func') -@@ -337,7 +337,7 @@ - - - def do_phinode(): -- print " Testing class PhiNode" -+ print(" Testing class PhiNode") - m = Module.new('a') - ft = Type.function(ti, [ti]) - f = Function.new(m, ft, 'func') -@@ -354,7 +354,7 @@ - - - def do_switchinstruction(): -- print " Testing class SwitchInstruction" -+ print(" Testing class SwitchInstruction") - m = Module.new('a') - ft = Type.function(ti, [ti]) - f = Function.new(m, ft, 'func') -@@ -365,7 +365,7 @@ - - - def do_basicblock(): -- print " Testing class BasicBlock" -+ print(" Testing class BasicBlock") - m = Module.new('a') - ft = Type.function(ti, [ti]) - f = Function.new(m, ft, 'func') -@@ -395,7 +395,7 @@ - - - def do_builder(): -- print " Testing class Builder" -+ print(" Testing class Builder") - m = Module.new('a') - ft = Type.function(ti, [ti]) - f = Function.new(m, ft, 'func') -@@ -488,7 +488,7 @@ - - - def do_llvm_core(): -- print " Testing module llvm.core" -+ print(" Testing module llvm.core") - do_module() - do_type() - do_typehandle() -@@ -508,7 +508,7 @@ - - - def do_targetdata(): -- print " Testing class TargetData" -+ print(" Testing class TargetData") - t = TargetData.new('') - v = str(t) - v = t.byte_order -@@ -530,7 +530,7 @@ - - - def do_genericvalue(): -- print " Testing class GenericValue" -+ print(" Testing class GenericValue") - v = GenericValue.int(ti, 1) - v = GenericValue.int_signed(ti, 1) - v = GenericValue.real(Type.float(), 3.14) -@@ -540,7 +540,7 @@ - - - def do_executionengine(): -- print " Testing class ExecutionEngine" -+ print(" Testing class ExecutionEngine") - m = Module.new('a') - ee = ExecutionEngine.new(m, True) - ft = Type.function(ti, []) -@@ -567,14 +567,14 @@ - - - def do_llvm_ee(): -- print " Testing module llvm.ee" -+ print(" Testing module llvm.ee") - do_targetdata() - do_genericvalue() - do_executionengine() - - - def do_passmanager(): -- print " Testing class PassManager" -+ print(" Testing class PassManager") - pm = PassManager.new() - pm.add(TargetData.new('')) - for i in [getattr(llvm.passes, x) for x in \ -@@ -586,7 +586,7 @@ - - - def do_functionpassmanager(): -- print " Testing class FunctionPassManager" -+ print(" Testing class FunctionPassManager") - m = Module.new('a') - ft = Type.function(ti, []) - f = m.add_function(ft, 'func') -@@ -602,13 +602,13 @@ - - - def do_llvm_passes(): -- print " Testing module llvm.passes" -+ print(" Testing module llvm.passes") - do_passmanager() - do_functionpassmanager() - - - def main(): -- print "Testing package llvm" -+ print("Testing package llvm") - do_llvm() - do_llvm_core() - do_llvm_ee() ---- .\test\testattrs.py (original) -+++ .\test\testattrs.py (refactored) -@@ -1,7 +1,7 @@ - #!/usr/bin/env python - - from llvm.core import * --from cStringIO import StringIO -+from io import StringIO - - - def make_module(): ---- .\test\typehandle.py (original) -+++ .\test\typehandle.py (refactored) -@@ -16,4 +16,4 @@ - m.add_type_name("struct.node", th.type) - - # show what we created --print m -+print(m) ---- .\test\uses.py (original) -+++ .\test\uses.py (refactored) -@@ -13,11 +13,11 @@ - tmp3 = bld.add(tmp1, f.args[2], "tmp3") - bld.ret(tmp3) - --print "-"*60 --print m --print "-"*60 -+print("-"*60) -+print(m) -+print("-"*60) - --print "Testing use count ..", -+print("Testing use count ..", end=' ') - c1 = f.args[0].use_count == 1 - c2 = f.args[1].use_count == 1 - c3 = f.args[2].use_count == 1 -@@ -25,11 +25,11 @@ - c5 = tmp2.use_count == 0 - c6 = tmp3.use_count == 1 - if c1 and c2 and c3 and c4 and c5 and c6: -- print "OK" -+ print("OK") - else: -- print "FAIL" -+ print("FAIL") - --print "Testing uses ..", -+print("Testing uses ..", end=' ') - c1 = f.args[0].uses[0] is tmp1 - c2 = len(f.args[0].uses) == 1 - c3 = f.args[1].uses[0] is tmp2 -@@ -40,6 +40,6 @@ - c8 = len(tmp2.uses) == 0 - c9 = len(tmp3.uses) == 1 - if c1 and c2 and c3 and c4 and c5 and c6 and c7 and c8 and c9: -- print "OK" -+ print("OK") - else: -- print "FAIL" -+ print("FAIL") ---- .\tools\intrgen.py (original) -+++ .\tools\intrgen.py (refactored) -@@ -26,7 +26,7 @@ - idx = 1 - for i in intr: - s = 'INTR_' + i.upper() -- print '%s = %d' % (s.ljust(maxw), idx) -+ print('%s = %d' % (s.ljust(maxw), idx)) - idx += 1 - - gen(sys.argv[1]) ---- .\tools\intrs_for_doc.py (original) -+++ .\tools\intrs_for_doc.py (refactored) -@@ -21,5 +21,5 @@ - outf = open(OUTF, 'wt') - i = 0 - while i < len(intrs): -- print >>outf, "`" + "`,`".join(intrs[i:min(i+NCOLS,len(intrs)+1)]) + "`" -+ print("`" + "`,`".join(intrs[i:min(i+NCOLS,len(intrs)+1)]) + "`", file=outf) - i += NCOLS ---- .\www\makeweb.py (original) -+++ .\www\makeweb.py (refactored) -@@ -52,7 +52,7 @@ - - - def _rmtree_warn(fn, path, excinfo): -- print "** WARNING **: error while doing %s on %s" % (fn, path) -+ print("** WARNING **: error while doing %s on %s" % (fn, path)) - - - def _can_skip(opts, infile, outfile): -@@ -67,14 +67,14 @@ - cmd = cmdfn(opts, infile, outfile_actual) - if _can_skip(opts, infile, outfile_actual): - if opts.verbose >= 2: -- print "up to date %s -> %s" % (infile, outfile_actual) -+ print("up to date %s -> %s" % (infile, outfile_actual)) - return - if cmd: - # do cmd - if opts.verbose: -- print "process %s -> %s" % (infile, outfile_actual) -+ print("process %s -> %s" % (infile, outfile_actual)) - if opts.verbose >= 3: -- print "command is [%s]" % cmd -+ print("command is [%s]" % cmd) - if not opts.dryrun: - os.system(cmd) - # else if cmd is None, do nothing -@@ -83,7 +83,7 @@ - # nothing matched, default action is to copy - if not _can_skip(opts, infile, outfile): - if opts.verbose: -- print "copying %s -> %s" % (infile, outfile) -+ print("copying %s -> %s" % (infile, outfile)) - if not opts.dryrun: - shutil.copy(infile, outfile) - -@@ -95,14 +95,14 @@ - - # if it exists, it must be a dir! - if odexists and not os.path.isdir(outdir): -- print "** WARNING **: output dir '%s' exists but is " \ -- "not a dir, skipping" % outdir -+ print("** WARNING **: output dir '%s' exists but is " \ -+ "not a dir, skipping" % outdir) - return - - # make outdir if not existing - if not odexists: - if opts.verbose: -- print "creating %s" % outdir -+ print("creating %s" % outdir) - if not opts.dryrun: - os.mkdir(outdir) - -@@ -114,8 +114,8 @@ - # process files - if os.path.isfile(inp): - if os.path.exists(outp) and not os.path.isfile(outp): -- print "** WARNING **: output '%s' corresponding to " \ -- "input '%s' is not a file, skipping" % (outp, inp) -+ print("** WARNING **: output '%s' corresponding to " \ -+ "input '%s' is not a file, skipping" % (outp, inp)) - else: - process_file(opts, inp, outp) - -@@ -124,15 +124,15 @@ - # if dir is in skip list, silently ignore - if elem in DIR_SKIP_TBL: - if opts.verbose >= 3: -- print "skipping %s" % inp -+ print("skipping %s" % inp) - continue - # just recurse - make(opts, inp, outp) - - # neither a file nor a dir - else: -- print "** WARNING **: input '%s' is neither file nor " \ -- "dir, skipping" % inp -+ print("** WARNING **: input '%s' is neither file nor " \ -+ "dir, skipping" % inp) - - - def get_opts(): -@@ -173,14 +173,14 @@ - def main(): - opts, src, dest = get_opts() - if opts.verbose >= 3: -- print ("running with options:\nsrc = [%s]\ndest = [%s]\nverbose = [%d]\n" +\ -+ print(("running with options:\nsrc = [%s]\ndest = [%s]\nverbose = [%d]\n" +\ - "dry-run = [%d]\nclean-first = [%d]\nforce = [%d]") %\ -- (src, dest, opts.verbose, opts.dryrun, opts.clean, opts.force) -+ (src, dest, opts.verbose, opts.dryrun, opts.clean, opts.force)) - if opts.dryrun and opts.verbose == 0: - opts.verbose = 1 - if opts.clean: - if opts.dryrun or opts.verbose: -- print "removing tree %s" % dest -+ print("removing tree %s" % dest) - if not opts.dryrun: - os.rmtree(dest, True, _rmtree_warn) - make(opts, src, dest) diff --git a/llvm/py3k_update.output b/llvm/py3k_update.output deleted file mode 100644 index 4ea51a4..0000000 --- a/llvm/py3k_update.output +++ /dev/null @@ -1,62 +0,0 @@ -C:\Users\AndrewBC\src\llvm-py>python "C:\Program Files\Python27\Tools\Scripts\2to3.py" -w -f all -f idioms . > llvm/py3k_update.diff -RefactoringTool: Skipping implicit fixer: buffer -RefactoringTool: Skipping implicit fixer: set_literal -RefactoringTool: Skipping implicit fixer: ws_comma -RefactoringTool: Refactored .\setup-win32.py -RefactoringTool: Refactored .\setup.py -RefactoringTool: Refactored .\llvm\__init__.py -RefactoringTool: Refactored .\llvm\_util.py -RefactoringTool: Refactored .\llvm\core.py -RefactoringTool: Refactored .\llvm\ee.py -RefactoringTool: Refactored .\llvm\passes.py -RefactoringTool: Refactored .\test\JITTutorial1.py -RefactoringTool: Refactored .\test\JITTutorial2.py -RefactoringTool: Refactored .\test\asm.py -RefactoringTool: Refactored .\test\call-jit-ctypes.py -RefactoringTool: Refactored .\test\example-jit.py -RefactoringTool: Refactored .\test\example.py -RefactoringTool: Refactored .\test\intrinsic.py -RefactoringTool: Refactored .\test\objcache.py -RefactoringTool: Refactored .\test\operands.py -RefactoringTool: Refactored .\test\passes.py -RefactoringTool: Refactored .\test\test.py -RefactoringTool: Refactored .\test\testall.py -RefactoringTool: Refactored .\test\testattrs.py -RefactoringTool: Refactored .\test\typehandle.py -RefactoringTool: Refactored .\test\uses.py -RefactoringTool: Refactored .\tools\intrgen.py -RefactoringTool: Refactored .\tools\intrs_for_doc.py -RefactoringTool: Refactored .\www\makeweb.py -RefactoringTool: Can't parse .\www\src\examples\JITTutorial1.py: ParseError: bad input: type=17, value=u'/', context=('', (1, 2)) -RefactoringTool: Can't parse .\www\src\examples\JITTutorial2.py: ParseError: bad input: type=17, value=u'/', context=('', (1, 2)) -RefactoringTool: Files that need to be modified: -RefactoringTool: .\setup-win32.py -RefactoringTool: .\setup.py -RefactoringTool: .\llvm\__init__.py -RefactoringTool: .\llvm\_util.py -RefactoringTool: .\llvm\core.py -RefactoringTool: .\llvm\ee.py -RefactoringTool: .\llvm\passes.py -RefactoringTool: .\test\JITTutorial1.py -RefactoringTool: .\test\JITTutorial2.py -RefactoringTool: .\test\asm.py -RefactoringTool: .\test\call-jit-ctypes.py -RefactoringTool: .\test\example-jit.py -RefactoringTool: .\test\example.py -RefactoringTool: .\test\intrinsic.py -RefactoringTool: .\test\objcache.py -RefactoringTool: .\test\operands.py -RefactoringTool: .\test\passes.py -RefactoringTool: .\test\test.py -RefactoringTool: .\test\testall.py -RefactoringTool: .\test\testattrs.py -RefactoringTool: .\test\typehandle.py -RefactoringTool: .\test\uses.py -RefactoringTool: .\tools\intrgen.py -RefactoringTool: .\tools\intrs_for_doc.py -RefactoringTool: .\www\makeweb.py -RefactoringTool: There were 2 errors: -RefactoringTool: Can't parse .\www\src\examples\JITTutorial1.py: ParseError: bad input: type=17, value=u'/', context=('', (1, 2)) -RefactoringTool: Can't parse .\www\src\examples\JITTutorial2.py: ParseError: bad input: type=17, value=u'/', context=('', (1, 2)) - -C:\Users\AndrewBC\src\llvm-py> \ No newline at end of file diff --git a/llvm/test_llvmpy.py b/llvm/test_llvmpy.py index 05b7d72..3656621 100644 --- a/llvm/test_llvmpy.py +++ b/llvm/test_llvmpy.py @@ -10,13 +10,12 @@ import subprocess import tempfile import contextlib -is_py3k = bool(sys.version_info[0] == 3) BITS = tuple.__itemsize__ * 8 -if is_py3k: +try: + from StringIO import StringIO +except ImportError: from io import StringIO -else: - from cStringIO import StringIO import llvm @@ -26,6 +25,7 @@ from llvm.ee import EngineBuilder import llvm.core as lc import llvm.passes as lp import llvm.ee as le +import llvmpy tests = [] @@ -117,13 +117,13 @@ tests.append(TestAsm) class TestAttr(TestCase): def make_module(self): test_module = """ - define i32 @sum(i32, i32) { + define void @sum(i32*, i32*) { entry: - %2 = add i32 %0, %1 - ret i32 %2 + ret void } """ - return Module.from_assembly(StringIO(test_module)) + buf = StringIO(test_module) + return Module.from_assembly(buf) def test_align(self): m = self.make_module() @@ -394,6 +394,9 @@ entry: self.assertFalse(pmb.disable_unroll_loops) self.assertFalse(pmb.disable_simplify_lib_calls) + pmb.disable_unit_at_a_time = True + self.assertTrue(pmb.disable_unit_at_a_time) + # Do function pass fpm = lp.FunctionPassManager.new(m) pmb.populate(fpm) @@ -437,29 +440,18 @@ class TestEngineBuilder(TestCase): def test_enginebuilder_basic(self): module = self.make_test_module() + self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr)) ee = EngineBuilder.new(module).create() - - with self.assertRaises(llvm.LLVMException): - # Ensure the module is owned. - llvm._util.check_is_unowned(module) - + self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr)) self.run_foo(ee, module) def test_enginebuilder_with_tm(self): tm = le.TargetMachine.new() module = self.make_test_module() + self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr)) ee = EngineBuilder.new(module).create(tm) - - with self.assertRaises(llvm.LLVMException): - # Ensure the targetmachine is owned. - llvm._util.check_is_unowned(tm) - - - with self.assertRaises(llvm.LLVMException): - # Ensure the module is owned. - llvm._util.check_is_unowned(module) - + self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr)) self.run_foo(ee, module) def test_enginebuilder_force_jit(self): @@ -467,12 +459,12 @@ class TestEngineBuilder(TestCase): ee = EngineBuilder.new(module).force_jit().create() self.run_foo(ee, module) - - def test_enginebuilder_force_interpreter(self): - module = self.make_test_module() - ee = EngineBuilder.new(module).force_interpreter().create() - - self.run_foo(ee, module) +# +# def test_enginebuilder_force_interpreter(self): +# module = self.make_test_module() +# ee = EngineBuilder.new(module).force_interpreter().create() +# +# self.run_foo(ee, module) def test_enginebuilder_opt(self): module = self.make_test_module() @@ -549,6 +541,7 @@ class TestObjCache(TestCase): gv3 = None gv1.delete() + gv4 = GlobalVariable.new(m1, t, "gv") self.assert_(gv1 is not gv4) @@ -588,7 +581,7 @@ class TestObjCache(TestCase): self.assert_(b1 is b2) # Testing basic block aliasing 2 - b3 = f1.get_entry_basic_block() + b3 = f1.entry_basic_block self.assert_(b1 is b3) # Testing basic block aliasing 3 @@ -638,7 +631,7 @@ class TestTargetMachines(TestCase): self.assertTrue(tm.target_data) self.assertTrue(tm.target_short_description) self.assertTrue(tm.triple) - self.assertIn('foo', tm.emit_assembly(m).decode('utf-8')) + self.assertIn('foo', tm.emit_assembly(m)) self.assertTrue(le.get_host_cpu_name()) def test_ptx(self): @@ -648,16 +641,17 @@ class TestTargetMachines(TestCase): arch = 'nvptx64' else: return # skip this test + print(arch) m, func = self._build_module() func.calling_convention = lc.CC_PTX_KERNEL # set calling conv - ptxtm = le.TargetMachine.lookup(arch=arch, cpu='compute_20') + ptxtm = le.TargetMachine.lookup(arch=arch, cpu='sm_20') self.assertTrue(ptxtm.triple) self.assertTrue(ptxtm.cpu) - ptxasm = ptxtm.emit_assembly(m).decode('utf-8') + ptxasm = ptxtm.emit_assembly(m) self.assertIn('foo', ptxasm) if lc.HAS_NVPTX: self.assertIn('.address_size 64', ptxasm) - self.assertIn('compute_20', ptxasm) + self.assertIn('sm_20', ptxasm) def _build_module(self): m = Module.new('TestTargetMachines') @@ -947,31 +941,31 @@ class TestCPUSupport(TestCase): def test_cpu_support2(self): features = 'sse3', 'sse41', 'sse42', 'avx' mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print 'disable mattrs', mattrs + print('disable mattrs', mattrs) self._template(mattrs) def test_cpu_support3(self): features = 'sse41', 'sse42', 'avx' mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print 'disable mattrs', mattrs + print('disable mattrs', mattrs) self._template(mattrs) def test_cpu_support4(self): features = 'sse42', 'avx' mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print 'disable mattrs', mattrs + print('disable mattrs', mattrs) self._template(mattrs) def test_cpu_support5(self): features = 'avx', mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print 'disable mattrs', mattrs + print('disable mattrs', mattrs) self._template(mattrs) def test_cpu_support6(self): features = [] mattrs = ','.join(map(lambda s: '-%s' % s, features)) - print 'disable mattrs', mattrs + print('disable mattrs', mattrs) self._template(mattrs) tests.append(TestCPUSupport) @@ -1246,4 +1240,4 @@ def run(verbosity=1): if __name__ == '__main__': - run() + unittest.main() diff --git a/llvm/wrap.cpp b/llvm/wrap.cpp deleted file mode 100644 index 6702ade..0000000 --- a/llvm/wrap.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2008-10, Mahadevan R All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of this software, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "wrap.h" - -const char PYCAP_OBJECT_NAME[] = "llvm.wrap.h"; - -/*===----------------------------------------------------------------------===*/ -/* Type ctor/dtor */ -/*===----------------------------------------------------------------------===*/ - - -/*===----------------------------------------------------------------------===*/ -/* Helper functions */ -/*===----------------------------------------------------------------------===*/ - -void *get_object_arg(PyObject *args) -{ - PyObject *o; - - if (!PyArg_ParseTuple(args, "O", &o)) - throw py_exception(); - - return pycap_get(o); -} - -// must delete [] returned array -void **make_array_from_list(PyObject *list, int n) -{ - void **arr = new void*[n] ; - - int i; - for (i=0; i(e); - } - } - - return arr; -} diff --git a/llvm/wrap.h b/llvm/wrap.h deleted file mode 100644 index ce2dd88..0000000 --- a/llvm/wrap.h +++ /dev/null @@ -1,1277 +0,0 @@ -/* - * Copyright (c) 2008-10, Mahadevan R All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of this software, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Functions and macros to aid in wrapping. - */ - -#ifndef LLVM_PY_WRAP_H -#define LLVM_PY_WRAP_H - - -/* python includes */ -#include -// #include //unused? - -//// For pre-2.7 compatbility, use the following include, which provides -//// alias for PyCapsule. -//// See http://docs.python.org/py3k/howto/cporting.html -#include "capsulethunk.h" // pre-2.7 compatibility for PyCapsule - - -/* llvm includes */ -#include "llvm-c/Core.h" -#include "llvm-c/Analysis.h" -#include "llvm-c/ExecutionEngine.h" -#include "llvm-c/Target.h" - -// workaround missing bool type -#define bool int -#include "llvm-c/Transforms/PassManagerBuilder.h" -#undef bool - -#include "llvm_c_extra.h" - -#include -#include - -class py_exception: public std::exception{}; - -#define LLVMPY_TRY \ - try { - -#define LLVMPY_CATCH_ALL \ - } catch (const std::bad_alloc&) { \ - return PyErr_NoMemory(); \ - } catch (const py_exception &) { \ - return NULL; \ - } catch (const std::exception& e) { \ - PyErr_SetString(PyExc_RuntimeError, e.what()); \ - return NULL; \ - } catch (...) { \ - std::ostringstream oss; \ - oss << "Unknown exception " << __FILE__ << ":" << __LINE__; \ - PyErr_SetString(PyExc_RuntimeError, oss.str().c_str()); \ - return NULL; \ - } - -/*===----------------------------------------------------------------------===*/ -/* Typedefs */ -/*===----------------------------------------------------------------------===*/ - -typedef unsigned long long llvmwrap_ull; -typedef long long llvmwrap_ll; - -/*===----------------------------------------------------------------------===*/ -/* Type ctor/dtor */ -/*===----------------------------------------------------------------------===*/ - -extern const char PYCAP_OBJECT_NAME[] ; - -// Cast python object to aTYPE -template -aTYPE pycap_get( PyObject* obj ) -{ - void *p = PyCapsule_GetPointer(obj, PYCAP_OBJECT_NAME); - if (!p){ - throw py_exception(); - } - return static_cast (p); -} - -// Contruct python object to hold aTYPE pointer -template -PyObject* pycap_new( aTYPE p ) -{ - if (p){ - return PyCapsule_New(p, PYCAP_OBJECT_NAME, NULL); - } - Py_RETURN_NONE; -} - -/*===----------------------------------------------------------------------===*/ -/* Helper methods */ -/*===----------------------------------------------------------------------===*/ - -/** - * Accept a single object argument of type PyCObject and return the - * opaque pointer contained in it. - */ -void *get_object_arg(PyObject *args); - -template -aTYPE get_object_arg( PyObject* obj ) -{ - return static_cast ( get_object_arg(obj) ); -} - -/** - * Given a PyList object (list) having n (= PyList_Size(list)) elements, - * each list object being a PyCObject, return a new()-ed array of - * opaque pointers from the PyCObjects. The 'n' is passed explicitly - * since the caller will have to query it once anyway, and we can avoid - * a second call internally. - */ -void **make_array_from_list(PyObject *list, int n); - -template -LLTYPE make_array_from_list(PyObject *list, int n) -{ - LLTYPE p = reinterpret_cast(make_array_from_list(list, n)) ; - if ( !p ) throw py_exception(); - return p; -} - -template -PyObject* make_list( aTYPE p[], size_t n ) -{ - PyObject *list = PyList_New(n); - - if (!list) - return NULL; - - size_t i; - for (i=0; i( p[i] ); - PyList_SetItem(list, i, elem); - } - - return list; -} - -/*===----------------------------------------------------------------------===*/ -/* Wrapper macros */ -/*===----------------------------------------------------------------------===*/ - -/* The following wrapper macros define functions that wrap over LLVM-C APIs - * of various signatures. Though they look hairy, they all follow some - * conventions. - */ - - -/****************************************************************************** - ****************************************************************************** - *** PyCapsule Calls - ****************************************************************************** - *****************************************************************************/ - -#define _wrap_none2none(func) \ -static PyObject * \ -_w ## func(PyObject * self, PyObject * args) \ -{ \ - LLVMPY_TRY \ - if (!PyArg_ParseTuple(args, "")) \ - return NULL; \ - func(); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1) - */ -#define _wrap_obj2obj(func, intype1, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - intype1 arg1 = get_object_arg(args); \ - \ - return pycap_new( func( arg1 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(int arg1) - */ -#define _wrap_int2obj(func, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - int arg1; \ - \ - if (!PyArg_ParseTuple(args, "i", &arg1)) \ - return NULL; \ - \ - return pycap_new( func( arg1 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2) - */ -#define _wrap_objobj2obj(func, intype1, intype2, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - \ - if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - \ - return pycap_new( func( arg1, arg2 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, intype2 arg2) - */ -#define _wrap_objobj2none(func, intype1, intype2) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - \ - if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) \ - return NULL; \ - \ - intype1 arg1 = pycap_get< intype1 > (obj1); \ - intype2 arg2 = pycap_get< intype2 > (obj2); \ - \ - func (arg1, arg2); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, arg2) - */ -#define _wrap_objint2obj(func, intype1, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - size_t arg2; \ - \ - if (!PyArg_ParseTuple(args, "OI", &obj1, &arg2)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - \ - return pycap_new( func( arg1, arg2 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3 arg3) - */ -#define _wrap_objobjobj2obj(func, intype1, intype2, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - \ - if (!PyArg_ParseTuple(args, "OOO", &obj1, &obj2, &obj3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, intype2 arg2, intype3 arg3) - */ -#define _wrap_objobjobj2none(func, intype1, intype2, intype3) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - \ - if (!PyArg_ParseTuple(args, "OOO", &obj1, &obj2, &obj3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - func (arg1, arg2, arg3); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func( arg1, intype2 arg2, intype3 arg3) - */ -#define _wrap_intobjobj2obj(func, intype2, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - size_t arg1; \ - PyObject *obj2, *obj3; \ - \ - if (!PyArg_ParseTuple(args, "IOO", &arg1, &obj2, &obj3)) \ - return NULL; \ - \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(enum_intype1 arg1, intype2 arg2, intype3 arg3) - */ -#define _wrap_enumobjobj2obj(func, intype1, intype2, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - intype1 arg1; \ - PyObject *obj2, *obj3; \ - \ - if (!PyArg_ParseTuple(args, "IOO", &arg1, &obj2, &obj3)) \ - return NULL; \ - \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(const char *s) - */ -#define _wrap_str2obj(func, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - const char *arg1; \ - \ - if (!PyArg_ParseTuple(args, "s", &arg1)) \ - return NULL; \ - \ - return pycap_new( func( arg1 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func() - */ -#define _wrap_none2obj(func, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - if (!PyArg_ParseTuple(args, "")) \ - return NULL; \ - \ - return pycap_new( func() ); \ - LLVMPY_CATCH_ALL \ -} - - -/** - * Wrap LLVM functions of the type - * const char * func() - */ - #define _wrap_none2str(func) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - if (!PyArg_ParseTuple(args, "")) \ - return NULL; \ - return PyUnicode_FromString(func()); \ - LLVMPY_CATCH_ALL \ -} - - -/** - * Wrap LLVM functions of the type - * const char *func(intype1 arg1) - */ -#define _wrap_obj2str(func, intype1) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - const intype1 arg1 = get_object_arg(args) ; \ - return PyUnicode_FromString( func (arg1)); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1) - */ -#define _wrap_obj2none(func, intype1) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - const intype1 arg1 = get_object_arg(args) ; \ - func (arg1); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, const char *arg2) - */ -#define _wrap_objstr2none(func, intype1) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - const char *arg2; \ - \ - if (!PyArg_ParseTuple(args, "Os", &obj1, &arg2)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 >( obj1 ); \ - \ - func (arg1, arg2); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, const char *arg2) - */ -#define _wrap_objstr2obj(func, intype1, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - const char *arg2; \ - \ - if (!PyArg_ParseTuple(args, "Os", &obj1, &arg2)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - \ - return pycap_new( func( arg1, arg2 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, arg2) - */ -#define _wrap_objint2none(func, intype1) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - int arg2; \ - \ - if (!PyArg_ParseTuple(args, "Oi", &obj1, &arg2)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - \ - func (arg1, arg2); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, enum_intype2 arg2) - */ -#define _wrap_objenum2none(func, intype1, intype2) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - intype2 arg2; \ - PyObject *obj1; \ - \ - if (!PyArg_ParseTuple(args, "Oi", &obj1, &arg2)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 >( obj1 ); \ - \ - func (arg1, arg2); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, const char *arg3) - */ -#define _wrap_objobjstr2obj(func, intype1, intype2, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - const char *arg3; \ - \ - if (!PyArg_ParseTuple(args, "OOs", &obj1, &obj2, &arg3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - \ - return pycap_new ( func (arg1, arg2, arg3)); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, int arg3) - */ -#define _wrap_objobjint2obj(func, intype1, intype2, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - int arg3; \ - \ - if (!PyArg_ParseTuple(args, "OOi", &obj1, &obj2, &arg3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - \ - return pycap_new( func( arg1, arg2, arg3 ) ) ; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, unsigned long long arg3) - */ -#define _wrap_objobjull2obj(func, intype1, intype2, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - unsigned long long arg3; \ - \ - if (!PyArg_ParseTuple(args, "OOK", &obj1, &obj2, &arg3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - \ - return pycap_new( func( arg1, arg2, arg3 ) ) ; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, arg2, arg3) - */ -#define _wrap_objintint2none(func, intype1) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - int arg2, arg3; \ - \ - if (!PyArg_ParseTuple(args, "Oii", &obj1, &arg2, &arg3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - \ - func (arg1, arg2, arg3); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, arg2, enum_intype3 arg3) - */ -#define _wrap_objintenum2none(func, intype1, intype3) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - int arg2; \ - intype3 arg3; \ - \ - if (!PyArg_ParseTuple(args, "Oii", &obj1, &arg2, &arg3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 >( obj1 ); \ - \ - func (arg1, arg2, arg3); \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, const char *arg2, intype3 arg3) - */ -#define _wrap_objstrobj2obj(func, intype1, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj3; \ - const char *arg2; \ - \ - if (!PyArg_ParseTuple(args, "OsO", &obj1, &arg2, &obj3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, const char *arg2, intype3 arg3) - */ -#define _wrap_objstrobj2none(func, intype1, intype3) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj3; \ - const char *arg2; \ - \ - if (!PyArg_ParseTuple(args, "OsO", &obj1, &arg2, &obj3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - func(arg1, arg2, arg3); \ - \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, int arg3, const char *arg4) - */ -#define _wrap_objobjintstr2obj(func, intype1, intype2, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - int arg3; \ - const char *arg4; \ - \ - if (!PyArg_ParseTuple(args, "OOis", &obj1, &obj2, &arg3, &arg4)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4 ) ) ; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3, int arg3, const char *arg4) - */ -#define _wrap_objobjobjintstr2obj(func, intype1, intype2, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - int arg4; \ - const char *arg5; \ - \ - if (!PyArg_ParseTuple(args, "OOOis", &obj1, &obj2, &obj3, &arg4, \ - &arg5)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4, arg5 ) ) ; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, const char *arg4) - */ -#define _wrap_objobjobjstr2obj(func, intype1, intype2, intype3, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - const char *arg4; \ - \ - if (!PyArg_ParseTuple(args, "OOOs", &obj1, &obj2, &obj3, &arg4)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, const char *arg3, arg4) - */ -#define _wrap_objobjstrint2obj(func, intype1, intype2, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - const char *arg3; \ - int arg4; \ - \ - if (!PyArg_ParseTuple(args, "OOsi", &obj1, &obj2, &arg3, &arg4)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4 ) ); \ - LLVMPY_CATCH_ALL \ -} - - - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, arg3, const char *arg4, arg5) - */ -#define _wrap_objobjintstrint2obj(func, intype1, intype2, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - int arg3; \ - const char *arg4; \ - int arg5; \ - \ - if (!PyArg_ParseTuple(args, "OOisi", &obj1, &obj2, &arg3, &arg4, &arg5)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4, arg5 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, const char *arg2, arg3) - */ -#define _wrap_objstrint2obj(func, intype1, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - const char *arg2; \ - int arg3; \ - \ - if (!PyArg_ParseTuple(args, "Osi", &obj1, &arg2, &arg3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - \ - return pycap_new( func( arg1, arg2, arg3 ) ); \ - LLVMPY_CATCH_ALL \ -} - - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3, const char *arg4, arg5) - */ -#define _wrap_objobjobjstrint2obj(func, intype1, intype2, intype3, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - const char *arg4; \ - int arg5; \ - \ - if (!PyArg_ParseTuple(args, "OOOsi", &obj1, &obj2, &obj3, &arg4, &arg5)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4, arg5 ) ); \ - LLVMPY_CATCH_ALL \ -} - - - - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3, arg4, const char *arg5, arg6) - */ -#define _wrap_objobjobjintstrint2obj(func, intype1, intype2, intype3, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - int arg4; \ - const char *arg5; \ - int arg6; \ - \ - if (!PyArg_ParseTuple(args, "OOOisi", &obj1, &obj2, &obj3, &arg4, &arg5, &arg6)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4, arg5, arg6 ) );\ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, intype4, const char *arg5, arg6) - */ -#define _wrap_objobjobjobjstrint2obj(func, intype1, intype2, intype3, intype4, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3, *obj4; \ - const char *arg5; \ - int arg6; \ - \ - if (!PyArg_ParseTuple(args, "OOOOsi", &obj1, &obj2, &obj3, &obj4, &arg5, &arg6)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - const intype4 arg4 = pycap_get< intype4 > (obj4); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4, arg5, arg6 ) ); \ - LLVMPY_CATCH_ALL \ -} - - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, const char* arg2, intype3 arg3, intype4, const char *arg5, arg6) - */ -#define _wrap_objstrobjobjstrint2obj(func, intype1, intype3, intype4, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj3, *obj4; \ - const char *arg2; \ - const char *arg5; \ - int arg6; \ - \ - if (!PyArg_ParseTuple(args, "OsOOsi", &obj1, &arg2, &obj3, &obj4, &arg5, &arg6)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - const intype4 arg4 = pycap_get< intype4 > (obj4); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4, arg5, arg6 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, arg4) - */ -#define _wrap_objobjobjint2obj(func, intype1, intype2, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - int arg4; \ - \ - if (!PyArg_ParseTuple(args, "OOOi", &obj1, &obj2, &obj3, &arg4)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, intype arg4) - */ -#define _wrap_objobjobjobj2obj(func, intype1, intype2, intype3, \ - intype4, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3, *obj4; \ - \ - if (!PyArg_ParseTuple(args, "OOOO", &obj1, &obj2, &obj3, &obj4)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - const intype4 arg4 = pycap_get< intype4 > (obj4); \ - return pycap_new( func( arg1, arg2, arg3, arg4 ) );\ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3 arg3, intype arg4, const char *arg5) - */ -#define _wrap_objobjobjobjstr2obj(func, intype1, intype2, intype3, \ - intype4, outtype)\ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3, *obj4; \ - const char *arg5; \ - \ - if (!PyArg_ParseTuple(args, "OOOOs", &obj1, &obj2, &obj3, &obj4, &arg5)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - const intype4 arg4 = pycap_get< intype4 > (obj4); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4, arg5 ) );\ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, enum_intype2 arg2, intype3 arg3, intype4 arg4, const char *arg5) - */ -#define _wrap_objenumobjobjstr2obj(func, intype1, intype2, intype3, \ - intype4, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj3, *obj4; \ - intype2 arg2 ; \ - const char *arg5; \ - \ - if (!PyArg_ParseTuple(args, "OiOOs", &obj1, &arg2, &obj3, &obj4, &arg5)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype3 arg3 = pycap_get< intype3 > (obj3); \ - const intype4 arg4 = pycap_get< intype4 > (obj4); \ - \ - return pycap_new( func( arg1, arg2, arg3, arg4, arg5 ) ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 *arg2v, unsigned arg2n) - * where arg2v is an array of intype2 elements, arg2n in length. - */ -#define _wrap_objlist2obj(func, intype1, intype2, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - \ - if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 >( obj1 ); \ - const size_t arg2n = PyList_Size(obj2); \ - intype2 *arg2v = make_array_from_list< intype2 *>(obj2, arg2n); \ - \ - outtype ret = func (arg1, arg2v, arg2n); \ - delete [] arg2v ; \ - return pycap_new( ret ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 *arg1v, unsigned arg1n, int arg2) - * where arg1v is an array of intype1 elements, arg1n in length. - */ -#define _wrap_listint2obj(func, intype1, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - int arg2; \ - \ - if (!PyArg_ParseTuple(args, "Oi", &obj1, &arg2)) \ - return NULL; \ - \ - const size_t arg1n = PyList_Size(obj1); \ - intype1 *arg1v = make_array_from_list< intype1 *>(obj1, arg1n); \ - \ - outtype ret = func (arg1v, arg1n, arg2); \ - delete [] arg1v; \ - return pycap_new( ret ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 *arg1v, unsigned arg1n) - * where arg1v is an array of intype1 elements, arg1n in length. - */ -#define _wrap_list2obj(func, intype1, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1; \ - \ - if (!PyArg_ParseTuple(args, "O", &obj1)) \ - return NULL; \ - \ - const size_t arg1n = PyList_Size(obj1); \ - intype1 *arg1v = make_array_from_list< intype1 *>(obj1, arg1n); \ - \ - outtype ret = func (arg1v, arg1n); \ - delete [] arg1v; \ - return pycap_new( ret ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 *arg2v, unsigned arg2n, int arg3) - * where arg2v is an array of intype2 elements, arg2n in length. - */ -#define _wrap_objlistint2obj(func, intype1, intype2, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - int arg3; \ - \ - if (!PyArg_ParseTuple(args, "OOi", &obj1, &obj2, &arg3)) \ - return NULL; \ - \ - intype1 arg1 = pycap_get< intype1 >( obj1 ); \ - const size_t arg2n = PyList_Size(obj2); \ - intype2 *arg2v = make_array_from_list< intype2 *>(obj2, arg2n); \ - \ - outtype ret = func (arg1, arg2v, arg2n, arg3); \ - delete [] arg2v ; \ - return pycap_new( ret ); \ - LLVMPY_CATCH_ALL \ -} - - -/** - * Wrap LLVM functions of the type - * void func(intype1 arg1, intype2 *arg2v, unsigned arg2n, int arg3) - * where arg2v is an array of intype2 elements, arg2n in length. - */ -#define _wrap_objlistint2none(func, intype1, intype2) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2; \ - int arg3; \ - \ - if (!PyArg_ParseTuple(args, "OOi", &obj1, &obj2, &arg3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 >( obj1 ); \ - const size_t arg2n = PyList_Size(obj2); \ - intype2 *arg2v = make_array_from_list< intype2 *>(obj2, arg2n); \ - \ - func (arg1, arg2v, arg2n, arg3); \ - delete [] arg2v ; \ - Py_RETURN_NONE; \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, int arg2, intype3 *arg3v, unsigned arg3n) - * where arg3v is an array of intype3 elements, arg3n in length. - */ -#define _wrap_objintlist2obj(func, intype1, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj3; \ - int arg2; \ - \ - if (!PyArg_ParseTuple(args, "OiO", &obj1, &arg2, &obj3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 >( obj1 ); \ - const size_t arg3n = PyList_Size(obj3); \ - intype3 *arg3v = make_array_from_list< intype3 *>(obj3, arg3n); \ - \ - outtype ret = func (arg1, arg2, arg3v, arg3n); \ - delete [] arg3v ; \ - return pycap_new( ret ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3 *arg3v, unsigned arg3n) - * where arg3v is an array of intype3 elements, arg3n in length. - */ -#define _wrap_objobjlist2obj(func, intype1, intype2, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - \ - if (!PyArg_ParseTuple(args, "OOO", &obj1, &obj2, &obj3)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const size_t arg3n = PyList_Size(obj3); \ - intype3 *arg3v = make_array_from_list< intype3 *>(obj3, arg3n); \ - \ - outtype ret = func (arg1, arg2, arg3v, arg3n); \ - delete [] arg3v ; \ - return pycap_new( ret ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM functions of the type - * outtype func(intype1 arg1, intype2 arg2, intype3 *arg3v, unsigned arg3n, const char *arg4) - * where arg3v is an array of intype3 elements, arg3n in length. - */ -#define _wrap_objobjliststr2obj(func, intype1, intype2, intype3, outtype) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - PyObject *obj1, *obj2, *obj3; \ - const char *arg4; \ - \ - if (!PyArg_ParseTuple(args, "OOOs", &obj1, &obj2, &obj3, &arg4)) \ - return NULL; \ - \ - const intype1 arg1 = pycap_get< intype1 > (obj1); \ - const intype2 arg2 = pycap_get< intype2 > (obj2); \ - const size_t arg3n = PyList_Size(obj3); \ - intype3 *arg3v = make_array_from_list< intype3 *>(obj3, arg3n); \ - \ - outtype ret = func (arg1, arg2, arg3v, arg3n, arg4); \ - delete [] arg3v ; \ - return pycap_new( ret ); \ - LLVMPY_CATCH_ALL \ -} - -/** - * Wrap LLVM dump-to-string functions of the type - * char *func(intype1) - * where the return value has to be disposed after use by calling - * LLVMDisposeMessage. - */ -#define _wrap_dumper(func, intype1) \ -static PyObject * \ -_w ## func (PyObject *self, PyObject *args) \ -{ \ - LLVMPY_TRY \ - intype1 arg1 = get_object_arg(args); \ - \ - const char *val = func (arg1); \ - PyObject *ret = PyUnicode_FromString(val); \ - LLVMDisposeMessage(const_cast(val)); \ - return ret; \ - LLVMPY_CATCH_ALL \ -} - - -#endif /* LLVM_PY_WRAP_H */ diff --git a/llvmpy/.gitignore b/llvmpy/.gitignore new file mode 100644 index 0000000..ab608aa --- /dev/null +++ b/llvmpy/.gitignore @@ -0,0 +1,4 @@ +api.cpp +api/*.py +api/*/*.py + diff --git a/llvmpy/Makefile b/llvmpy/Makefile new file mode 100644 index 0000000..e9cc1c3 --- /dev/null +++ b/llvmpy/Makefile @@ -0,0 +1,21 @@ +PYTHON = python + +all: _api.so _capsule.so + +_api.so _capsule.so: api.cpp capsule.cpp + $(PYTHON) setup.py build_ext --inplace + +api.cpp api/__init__.py: src/*.py include/llvm_binding/*.h gen/gen.py gen/binding.py + $(PYTHON) gen/gen.py api src + +clean: cleantemp + rm -f _api.so _capsule.so + rm -rf api + +cleantemp: + rm -f api.cpp + +check: _api.so api/__init__.py + $(PYTHON) test_binding.py + +@PHONY: all clean check diff --git a/llvmpy/README b/llvmpy/README new file mode 100644 index 0000000..2bfabcd --- /dev/null +++ b/llvmpy/README @@ -0,0 +1,5 @@ +# README + +This is a reimplementation of the LLVM binding, aiming to provide a more familiar interface to the C++ API whenever possible. + +The implementation uses a custom DSL in python to describe the interface (under binding directory). The DSL serves as input to *gen.py* for generation of the .cpp and .py files for the actual binding. diff --git a/llvmpy/__init__.py b/llvmpy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/llvmpy/capsule.cpp b/llvmpy/capsule.cpp new file mode 100644 index 0000000..561b28a --- /dev/null +++ b/llvmpy/capsule.cpp @@ -0,0 +1,117 @@ +#include +#include +#include +#include + +static +PyObject* getName(PyObject* self, PyObject* args) { + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)){ + return NULL; + } + const char* name = PyCapsule_GetName(obj); + if (!name) return NULL; + + return PyString_FromString(name); +} + +static +PyObject* getPointer(PyObject* self, PyObject* args) { + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)){ + return NULL; + } + void* pointer = PyCapsule_GetPointer(obj, PyCapsule_GetName(obj)); + if (!pointer) return NULL; + + return PyLong_FromVoidPtr(pointer); +} + +static +PyObject* check(PyObject* self, PyObject* args) { + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)){ + return NULL; + } + if (PyCapsule_CheckExact(obj)) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +// ------------------ +// PyCapsule Context +// ------------------ + +static +CapsuleContext* getContext(PyObject* self, PyObject* args) { + PyObject* obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + void* context = PyCapsule_GetContext(obj); + if (!context) { + PyErr_SetString(PyExc_TypeError, "PyCapsule has no context."); + return NULL; + } + return static_cast(context); +} + +static +PyObject* getClassName(PyObject* self, PyObject* args) { + CapsuleContext* context = getContext(self, args); + //Assert(context->_magic == 0xdead); + if (!context) { + return NULL; + } else { + return PyString_FromString(context->className); + } +} + + +static PyMethodDef core_methods[] = { +#define declmethod(func) { #func , ( PyCFunction )func , METH_VARARGS , NULL } + declmethod(getName), + declmethod(getPointer), + declmethod(check), + declmethod(getClassName), + { NULL }, +#undef declmethod +}; + +// Module main function, hairy because of py3k port +extern "C" { + +#if (PY_MAJOR_VERSION >= 3) + struct PyModuleDef module_def = { + PyModuleDef_HEAD_INIT, + "_capsule", + NULL, + -1, + core_methods, + NULL, NULL, NULL, NULL + }; +#define INITERROR return NULL + PyObject * + PyInit__capsule(void) +#else +#define INITERROR return + PyMODINIT_FUNC + init_capsule(void) +#endif + { +#if PY_MAJOR_VERSION >= 3 + PyObject *module = PyModule_Create( &module_def ); +#else + PyObject *module = Py_InitModule("_capsule", core_methods); +#endif + if (module == NULL) + INITERROR; +#if PY_MAJOR_VERSION >= 3 + + return module; +#endif + } + +} // end extern C diff --git a/llvmpy/capsule.py b/llvmpy/capsule.py new file mode 100644 index 0000000..ec6fdde --- /dev/null +++ b/llvmpy/capsule.py @@ -0,0 +1,213 @@ +from weakref import WeakKeyDictionary, WeakValueDictionary, ref +from collections import defaultdict +import logging +logger = logging.getLogger(__name__) + +def set_debug(enabled): + ''' + Side-effect: configure logger with it is not configured. + ''' + if enabled: + # If no handlers are configured for the root logger, + # build a default handler for debugging. + # Can we do better? + if not logger.root.handlers: + logging.basicConfig() + logger.setLevel(logging.DEBUG) + else: + logger.setLevel(logging.WARNING) + +def _capsule_weakref_dtor(item): + addr = item.pointer + name = item.name + _addr2refct[addr] -= 1 + refct = _addr2refct[addr] + assert refct >= 0, "RefCt drop below 0" + if refct == 0: + dtor = _addr2dtor.pop((name, addr), None) + if dtor is not None: + logger.debug('Destroy %s %s', name, hex(addr)) + dtor(item.capsule) + +class Capsule(object): + "Wraps PyCapsule so that we can build weakref of it." + + from ._capsule import check, getClassName, getName, getPointer + + def __init__(self, capsule): + assert Capsule.valid(capsule) + self.capsule = capsule + + weak = WeakRef(self, _capsule_weakref_dtor) + weak.pointer = self.pointer + weak.capsule = capsule + weak.name = self.name + _capsule2weak[self] = weak + _addr2refct[self.pointer] += 1 + + @property + def classname(self): + return Capsule.getClassName(self.capsule) + + @property + def name(self): + return Capsule.getName(self.capsule) + + @property + def pointer(self): + return Capsule.getPointer(self.capsule) + + @staticmethod + def valid(capsule): + return Capsule.check(capsule) + + def get_class(self): + return _pyclasses[self.classname] + + def instantiate(self): + cls = self.get_class() + return cls(self) + + def __eq__(self, other): + if self.pointer == other.pointer: + assert self.name == other.name + return True + else: + return False + + def __hash__(self): + return super(Capsule, self).__hash__() + + def __ne__(self, other): + return not (self == other) + +class WeakRef(ref): + pass + +_addr2refct = defaultdict(lambda: 0) +_capsule2weak = WeakKeyDictionary() +_addr2dtor = {} +_pyclasses = {} + +# Cache {cls: {addr: obj}} +# NOTE: The same 'addr' may appear in multiple class bins. +_cache = defaultdict(WeakValueDictionary) + +def release_ownership(old): + logger.debug('Release %s', old) + addr = Capsule.getPointer(old) + name = Capsule.getName(old) + if _addr2dtor.get((name, addr)) is None: + clsname = Capsule.getClassName(old) + if not _pyclasses[clsname]._has_dtor(): + return + # Guard duplicated release + raise Exception("Already released") + _addr2dtor[(name, addr)] = None + + +def obtain_ownership(cap): + cls = cap.get_class() + if cls._has_dtor(): + addr = cap.pointer + name = cap.name + assert _addr2dtor[addr] is None + _addr2dtor[(name, addr)] = cls._delete_ + +def has_ownership(cap): + addr = Capsule.getPointer(cap) + name = Capsule.getName(cap) + return _addr2dtor.get((name, addr)) is not None + +def wrap(cap, owned=False): + '''Wrap a PyCapsule with the corresponding Wrapper class. + If `cap` is not a PyCapsule, returns `cap` + ''' + if not Capsule.valid(cap): + if isinstance(cap, list): + return list(map(wrap, cap)) + return cap # bypass if cap is not a PyCapsule and not a list + + cap = Capsule(cap) + cls = cap.get_class() + addr = cap.pointer + name = cap.name + try: # lookup cached object + return _cache[cls][addr] + except KeyError: + if not owned and cls._has_dtor(): + _addr2dtor[(name, addr)] = cls._delete_ + obj = cap.instantiate() + _cache[cls][addr] = obj # cache it + return obj + +def unwrap(obj): + '''Unwrap a Wrapper instance into the underlying PyCapsule. + If `obj` is not a Wrapper instance, returns `obj`. + ''' + if isinstance(obj, Wrapper): + return obj._ptr + else: + return obj + + +def register_class(clsname): + def _wrapped(cls): + _pyclasses[clsname] = cls + return cls + return _wrapped + + +class Wrapper(object): + + __slots__ = '__capsule' + + def __init__(self, capsule): + self.__capsule = capsule + + @property + def _capsule(self): + return self.__capsule + + @property + def _ptr(self): + return self._capsule.capsule + + def __hash__(self): + return super(Wrapper, self).__hash__() + + def __eq__(self, other): + return self._capsule == other._capsule + + def __ne__(self, other): + return self._capsule != other._capsule + + def _downcast(self, newcls): + return downcast(self, newcls) + + @classmethod + def _has_dtor(cls): + return hasattr(cls, '_delete_') + +def downcast(obj, cls): + from . import _api + if type(obj) is cls: + return obj + fromty = obj._llvm_type_ + toty = cls._llvm_type_ + logger.debug("Downcast %s to %s" , fromty, toty) + fname = 'downcast_%s_to_%s' % (fromty, toty) + fname = fname.replace('::', '_') + try: + caster = getattr(_api.downcast, fname) + except AttributeError: + fmt = "Downcast from %s to %s is not supported" + raise TypeError(fmt % (fromty, toty)) + old = unwrap(obj) + new = caster(old) + used_to_own = has_ownership(old) + res = wrap(new, owned=not used_to_own) + if not res: + raise ValueError("Downcast failed") + return res + diff --git a/llvmpy/extra.py b/llvmpy/extra.py new file mode 100644 index 0000000..99035a7 --- /dev/null +++ b/llvmpy/extra.py @@ -0,0 +1,25 @@ +''' +Wrapped the extra functions in _api.so +''' + +from llvmpy import capsule +from llvmpy import _api +# +# Re-export the native API from the _api.extra and wrap the functions +# + +def _wrapper(func): + "Wrap the re-exported functions" + def _core(*args): + unwrapped = list(map(capsule.unwrap, args)) + ret = func(*unwrapped) + return capsule.wrap(ret) + return _core + +def _init(glob): + for k, v in _api.extra.__dict__.items(): + glob[k] = _wrapper(v) + +_init(globals()) + + diff --git a/llvmpy/gen/binding.py b/llvmpy/gen/binding.py new file mode 100644 index 0000000..0f5c4fd --- /dev/null +++ b/llvmpy/gen/binding.py @@ -0,0 +1,840 @@ +import inspect, textwrap +import functools +import codegen as cg +import os + +_rank = 0 +namespaces = {} + +RESERVED = frozenset(['None']) + +def makedir(directory): + if not os.path.exists(directory): + os.makedirs(directory) + +class SubModule(object): + def __init__(self): + self.methods = [] + self.enums = [] + self.classes = [] + self.namespaces = [] + self.attrs = [] + self.includes = set() + + def aggregate_includes(self): + includes = set(self.includes) + for unit in self.iter_all(): + if isinstance(unit, SubModule): + includes |= unit.aggregate_includes() + else: + includes |= unit.includes + return includes + + def aggregate_downcast(self): + dclist = [] + for cls in self.classes: + for bcls in cls.downcastables: + from_to = bcls.fullname, cls.fullname + name = 'downcast_%s_to_%s' % tuple(map(cg.mangle, from_to)) + fn = Function(namespaces[''], name, ptr(cls), ptr(bcls)) + dclist.append((from_to, fn)) + for ns in self.namespaces: + dclist.extend(ns.aggregate_downcast()) + return dclist + + def iter_all(self): + for fn in self.methods: + yield fn + for cls in self.classes: + yield cls + for enum in self.enums: + yield enum + for attr in self.attrs: + yield attr + for ns in self.namespaces: + yield ns + + + def generate_method_table(self, println): + writer = cg.CppCodeWriter(println) + writer.println('static') + writer.println('PyMethodDef meth_%s[] = {' % cg.mangle(self.fullname)) + with writer.indent(): + fmt = '{ "%(name)s", (PyCFunction)%(func)s, METH_VARARGS, NULL },' + for meth in self.methods: + name = meth.name + func = meth.c_name + writer.println(fmt % locals()) + for enumkind in self.enums: + for enum in enumkind.value_names: + name = enum + func = enumkind.c_name(enum) + writer.println(fmt % locals()) + for attr in self.attrs: + # getter + name = attr.getter_name + func = attr.getter_c_name + writer.println(fmt % locals()) + # setter + name = attr.setter_name + func = attr.setter_c_name + writer.println(fmt % locals()) + writer.println('{ NULL },') + writer.println('};') + writer.println() + +# def generate_downcasts(self, println): +# for ((fromty, toty), fn) in self.downcastlist: +# name = fn.name +# fmt = ''' +#static +#%(toty)s* %(name)s(%(fromty)s* arg) +#{ +# return typecast< %(toty)s >::from(arg); +#} +# ''' +# println(fmt % locals()) +# +# fn.generate_cpp(println) + + def generate_cpp(self, println, extras=()): + for unit in self.iter_all(): + unit.generate_cpp(println) + self.generate_method_table(println) + self.generate_submodule_table(println, extras=extras) + + def generate_submodule_table(self, println, extras=()): + writer = cg.CppCodeWriter(println) + writer.println('static') + name = cg.mangle(self.fullname) + writer.println('SubModuleEntry submodule_%(name)s[] = {' % locals()) + with writer.indent(): + for cls in self.classes: + name = cls.name + table = cg.mangle(cls.fullname) + writer.println('{ "%(name)s", meth_%(table)s, NULL },' % + locals()) + for ns in self.namespaces: + name = ns.localname + table = cg.mangle(ns.fullname) + fmt = '{ "%(name)s", meth_%(table)s, submodule_%(table)s },' + writer.println(fmt % locals()) + for name, table in extras: + writer.println('{ "%(name)s", %(table)s, NULL },' % locals()) + writer.println('{ NULL }') + writer.println('};') + writer.println('') + + def generate_py(self, rootdir='.', name=''): + name = name or self.localname + if self.namespaces: # should make new directory + path = os.path.join(rootdir, name) + makedir(path) + filepath = os.path.join(path, '__init__.py') + else: + filepath = os.path.join(rootdir, '%s.py' % name) + with open(filepath, 'w') as pyfile: + println = cg.wrap_println_from_file(pyfile) + println('from llvmpy import _api, capsule') + for ns in self.namespaces: + println('from . import %s' % ns.localname) + println() + for unit in self.iter_all(): + if not isinstance(unit, Namespace): + writer = cg.PyCodeWriter(println) + unit.compile_py(writer) + + for ns in self.namespaces: + ns.generate_py(rootdir=path) + + +class Namespace(SubModule): + def __init__(self, name): + SubModule.__init__(self) + self.name = name = name.lstrip(':') + namespaces[name] = self + + def Class(self, *bases): + cls = Class(self, *bases) + self.classes.append(cls) + return cls + + def Function(self, *args): + fn = Function(self, *args) + self.methods.append(fn) + return fn + + def CustomFunction(self, *args): + fn = CustomFunction(self, *args) + self.methods.append(fn) + return fn + + def Enum(self, name, *value_names): + enum = Enum(*value_names) + enum.parent = self + enum.name = name + self.enums.append(enum) + assert name not in vars(self), 'Duplicated' + setattr(self, name, enum) + return enum + + def Namespace(self, name): + ns = Namespace('::'.join([self.name, name])) + self.namespaces.append(ns) + return ns + + @property + def fullname(self): + return self.name + + @property + def py_name(self): + return self.name.replace('::', '.') + + @property + def localname(self): + return self.name.rsplit('::', 1)[-1] + + def __str__(self): + return self.name + +class _Type(object): + pass + +class BuiltinTypes(_Type): + def __init__(self, name): + self.name = name + + @property + def fullname(self): + return self.name + + def wrap(self, writer, var): + return var + + def unwrap(self, writer, var): + return var + +Void = BuiltinTypes('void') +Unsigned = BuiltinTypes('unsigned') +UnsignedLongLong = BuiltinTypes('unsigned long long') # used in llvm-3.2 +LongLong = BuiltinTypes('long long') +Float = BuiltinTypes('float') +Double = BuiltinTypes('double') +Uint64 = BuiltinTypes('uint64_t') +Int64 = BuiltinTypes('int64_t') +Int = BuiltinTypes('int') +Size_t = BuiltinTypes('size_t') +VoidPtr = BuiltinTypes('void*') +Bool = BuiltinTypes('bool') +StdString = BuiltinTypes('std::string') +ConstStdString = BuiltinTypes('const std::string') +ConstCharPtr = BuiltinTypes('const char*') +PyObjectPtr = BuiltinTypes('PyObject*') +PyObjectPtr.format='O' + +class Class(SubModule, _Type): + format = 'O' + + def __init__(self, ns, *bases): + SubModule.__init__(self) + self.ns = ns + self.bases = bases + self._is_defined = False + self.pymethods = [] + self.downcastables = set() + + def __call__(self, defn): + assert not self._is_defined + # process the definition in "defn" + self.name = defn.__name__ + for k, v in defn.__dict__.items(): + if isinstance(v, Method): + self.methods.append(v) + if isinstance(v, Constructor): + for sig in v.signatures: + sig[0] = ptr(self) + v.name = k + v.parent = self + elif isinstance(v, Enum): + self.enums.append(v) + v.name = k + v.parent = self + assert k not in vars(self), "Duplicated: %s" % k + setattr(self, k, v) + elif isinstance(v, Attr): + self.attrs.append(v) + v.name = k + v.parent = self + elif isinstance(v, CustomPythonMethod): + self.pymethods.append(v) + elif k == '_include_': + if isinstance(v, str): + self.includes.add(v) + else: + for i in v: + self.includes.add(i) + elif k == '_realname_': + self.realname = v + elif k == '_downcast_': + if isinstance(v, Class): + self.downcastables.add(v) + else: + for i in v: + self.downcastables.add(i) + return self + + def compile_py(self, writer): + clsname = self.name + bases = 'capsule.Wrapper' + if self.bases: + bases = ', '.join(x.name for x in self.bases) + writer.println('@capsule.register_class("%s")' % self.fullname) + with writer.block('class %(clsname)s(%(bases)s):' % locals()): + writer.println('_llvm_type_ = "%s"' % self.fullname) + for enum in self.enums: + enum.compile_py(writer) + for meth in self.methods: + meth.compile_py(writer) + for meth in self.pymethods: + meth.compile_py(writer) + for attr in self.attrs: + attr.compile_py(writer) + writer.println() + + @property + def capsule_name(self): + if self.bases: + return self.bases[-1].capsule_name + else: + return self.fullname + + @property + def fullname(self): + try: + name = self.realname + except AttributeError: + name = self.name + return '::'.join([self.ns.fullname, name]) + + @property + def py_name(self): + ns = self.ns.name.split('::') + return '.'.join(ns + [self.name]) + + def __str__(self): + return self.fullname + + def unwrap(self, writer, val): + fmt = 'PyCapsule_GetPointer(%(val)s, "%(name)s")' + name = self.capsule_name + raw = writer.declare('void*', fmt % locals()) + writer.die_if_false(raw, verbose=name) + ptrty = ptr(self).fullname + ty = self.fullname + fmt = 'typecast< %(ty)s >::from(%(raw)s)' + casted = writer.declare(ptrty, fmt % locals()) + writer.die_if_false(casted) + return casted + + def wrap(self, writer, val): + copy = 'new %s(%s)' % (self.fullname, val) + return writer.pycapsule_new(copy, self.capsule_name, self.fullname) + + +class Enum(object): + format = 'O' + + def __init__(self, *value_names): + self.parent = None + if len(value_names) == 1: + value_names = list(filter(bool, value_names[0].replace(',', ' ').split())) + self.value_names = value_names + self.includes = set() + + @property + def fullname(self): + try: + name = self.realname + except AttributeError: + name = self.name + return '::'.join([self.parent.fullname, name]) + + def __str__(self): + return self.fullname + + def wrap(self, writer, val): + ret = writer.declare('PyObject*', 'PyInt_FromLong(%s)' % val) + return ret + + def unwrap(self, writer, val): + convert_long_to_enum = '(%s)PyInt_AsLong(%s)' % (self.fullname, val) + ret = writer.declare(self.fullname, convert_long_to_enum) + return ret + + def c_name(self, enum): + return cg.mangle("%s_%s_%s" % (self.parent, self.name, enum)) + + def generate_cpp(self, println): + self.compile_cpp(cg.CppCodeWriter(println)) + + def compile_cpp(self, writer): + for enum in self.value_names: + with writer.py_function(self.c_name(enum)): + ret = self.wrap(writer, '::'.join([self.parent.fullname, enum])) + writer.return_value(ret) + + def compile_py(self, writer): + with writer.block('class %s:' % self.name): + writer.println('_llvm_type_ = "%s"' % self.fullname) + for v in self.value_names: + if v in RESERVED: + k = '%s_' % v + fmt = '%(k)s = getattr(%(p)s, "%(v)s")()' + else: + k = v + fmt = '%(k)s = %(p)s.%(v)s()' + p = '.'.join(['_api'] + self.parent.fullname.split('::')) + writer.println(fmt % locals()) + writer.println() + +class Method(object): + _kind_ = 'meth' + + def __init__(self, return_type=Void, *args): + self.parent = None + self.signatures = [] + self.includes = set() + self._add_signature(return_type, *args) + self.disowning = False + + def _add_signature(self, return_type, *args): + prev_lens = set(map(len, self.signatures)) + cur_len = len(args) + 1 + if cur_len in prev_lens: + raise Exception('Only support overloading with different number' + ' of arguments') + self.signatures.append([return_type] + list(args)) + + def __ior__(self, method): + assert type(self) is type(method) + for sig in method.signatures: + self._add_signature(sig[0], *sig[1:]) + return self + + @property + def fullname(self): + return '::'.join([self.parent.fullname, self.realname]).lstrip(':') + + @property + def realname(self): + try: + return self.__realname + except AttributeError: + return self.name + + @realname.setter + def realname(self, v): + self.__realname = v + + @property + def c_name(self): + return cg.mangle("%s_%s" % (self.parent, self.name)) + + def __str__(self): + return self.fullname + + def generate_cpp(self, println): + self.compile_cpp(cg.CppCodeWriter(println)) + + def compile_cpp(self, writer): + with writer.py_function(self.c_name): + if len(self.signatures) == 1: + sig = self.signatures[0] + retty = sig[0] + argtys = sig[1:] + self.compile_cpp_body(writer, retty, argtys) + else: + nargs = writer.declare('Py_ssize_t', 'PyTuple_Size(args)') + for sig in self.signatures: + retty = sig[0] + argtys = sig[1:] + expect = len(argtys) + if (not isinstance(self, StaticMethod) and + isinstance(self.parent, Class)): + # Is a instance method, add 1 for "this". + expect += 1 + with writer.block('if (%(expect)d == %(nargs)s)' % locals()): + self.compile_cpp_body(writer, retty, argtys) + writer.raises(TypeError, 'Invalid number of args') + + def compile_cpp_body(self, writer, retty, argtys): + args = writer.parse_arguments('args', ptr(self.parent), *argtys) + ret = writer.method_call(self.realname, retty.fullname, *args) + writer.return_value(retty.wrap(writer, ret)) + + def compile_py(self, writer): + decl = writer.function(self.name, args=('self',), varargs='args') + with decl as (this, varargs): + unwrap_this = writer.unwrap(this) + if self.disowning: + writer.release_ownership(unwrap_this) + unwrapped = writer.unwrap_many(varargs) + self.process_ownedptr_args(writer, unwrapped) + func = '.'.join([self.parent.py_name, self.name]) + ret = writer.call('_api.%s' % func, + args=(unwrap_this,), varargs=unwrapped) + + wrapped = writer.wrap(ret, self.is_return_ownedptr()) + + writer.return_value(wrapped) + writer.println() + + def require_only(self, num): + '''Require only "num" of argument. + ''' + assert len(self.signatures) == 1 + sig = self.signatures[0] + ret = sig[0] + args = sig[1:] + arg_ct = len(args) + + for i in range(num, arg_ct): + self._add_signature(ret, *args[:i]) + + return self + + def is_return_ownedptr(self): + retty = self.signatures[0][0] + return isinstance(retty, ownedptr) + + def process_ownedptr_args(self, writer, unwrapped): + argtys = self.signatures[0][1:] + for i, ty in enumerate(argtys): + if isinstance(ty, ownedptr): + with writer.block('if len(%s) > %d:' % (unwrapped, i)): + writer.release_ownership('%s[%d]' % (unwrapped, i)) + +class CustomMethod(Method): + def __init__(self, methodname, retty, *argtys): + super(CustomMethod, self).__init__(retty, *argtys) + self.methodname = methodname + + def compile_cpp_body(self, writer, retty, argtys): + args = writer.parse_arguments('args', ptr(self.parent), *argtys) + ret = writer.call(self.methodname, retty.fullname, *args) + writer.return_value(retty.wrap(writer, ret)) + + +class StaticMethod(Method): + + def compile_cpp_body(self, writer, retty, argtys): + assert isinstance(self.parent, Class) + args = writer.parse_arguments('args', *argtys) + ret = self.compile_cpp_call(writer, retty, args) + writer.return_value(retty.wrap(writer, ret)) + + def compile_cpp_call(self, writer, retty, args): + ret = writer.call(self.fullname, retty.fullname, *args) + return ret + + def compile_py(self, writer): + writer.println('@staticmethod') + decl = writer.function(self.name, varargs='args') + with decl as varargs: + unwrapped = writer.unwrap_many(varargs) + self.process_ownedptr_args(writer, unwrapped) + + func = '.'.join([self.parent.py_name, self.name]) + ret = writer.call('_api.%s' % func, varargs=unwrapped) + wrapped = writer.wrap(ret, self.is_return_ownedptr()) + writer.return_value(wrapped) + writer.println() + +class CustomStaticMethod(StaticMethod): + def __init__(self, methodname, retty, *argtys): + super(CustomStaticMethod, self).__init__(retty, *argtys) + self.methodname = methodname + + def compile_cpp_body(self, writer, retty, argtys): + args = writer.parse_arguments('args', *argtys) + ret = writer.call(self.methodname, retty.fullname, *args) + writer.return_value(retty.wrap(writer, ret)) + +class Function(Method): + _kind_ = 'func' + + def __init__(self, parent, name, return_type=Void, *args): + super(Function, self).__init__(return_type, *args) + self.parent = parent + self.name = name + + def compile_cpp_body(self, writer, retty, argtys): + args = writer.parse_arguments('args', *argtys) + ret = writer.call(self.fullname, retty.fullname, *args) + writer.return_value(retty.wrap(writer, ret)) + + def compile_py(self, writer): + with writer.function(self.name, varargs='args') as varargs: + unwrapped = writer.unwrap_many(varargs) + self.process_ownedptr_args(writer, unwrapped) + func = '.'.join([self.parent.py_name, self.name]).lstrip('.') + ret = writer.call('_api.%s' % func, varargs=unwrapped) + wrapped = writer.wrap(ret, self.is_return_ownedptr()) + writer.return_value(wrapped) + writer.println() + +class CustomFunction(Function): + def __init__(self, parent, name, realname, return_type=Void, *args): + super(CustomFunction, self).__init__(parent, name, return_type, *args) + self.realname = realname + + @property + def fullname(self): + return self.realname + +class Destructor(Method): + _kind_ = 'dtor' + + def __init__(self): + super(Destructor, self).__init__() + + def compile_cpp_body(self, writer, retty, argtys): + assert isinstance(self.parent, Class) + assert not argtys + args = writer.parse_arguments('args', ptr(self.parent), *argtys) + writer.println('delete %s;' % args[0]) + writer.return_value(None) + + def compile_py(self, writer): + func = '.'.join([self.parent.py_name, self.name]) + writer.println('_delete_ = _api.%s' % func) + + +class Constructor(StaticMethod): + _kind_ = 'ctor' + + def __init__(self, *args): + super(Constructor, self).__init__(Void, *args) + + def compile_cpp_call(self, writer, retty, args): + alloctype = retty.fullname.rstrip(' *') + arglist = ', '.join(args) + stmt = 'new %(alloctype)s(%(arglist)s)' % locals() + ret = writer.declare(retty.fullname, stmt) + return ret + +class ref(_Type): + def __init__(self, element): + assert isinstance(element, Class), type(element) + self.element = element + self.const = False + + def __str__(self): + return self.fullname + + @property + def fullname(self): + if self.const: + return 'const %s&' % self.element.fullname + else: + return '%s&' % self.element.fullname + + @property + def capsule_name(self): + return self.element.capsule_name + + @property + def format(self): + return self.element.format + + def wrap(self, writer, val): + p = writer.declare(const(ptr(self.element)).fullname, '&%s' % val) + return writer.pycapsule_new(p, self.capsule_name, self.element.fullname) + + def unwrap(self, writer, val): + p = self.element.unwrap(writer, val) + return writer.declare(self.fullname, '*%s' % p) + + +class ptr(_Type): + def __init__(self, element): + assert isinstance(element, Class) + self.element = element + self.const = False + + @property + def fullname(self): + if self.const: + return 'const %s*' % self.element + else: + return '%s*' % self.element + + @property + def format(self): + return self.element.format + + def unwrap(self, writer, val): + ret = writer.declare(self.fullname, 'NULL') + with writer.block('if (%(val)s != Py_None)' % locals()): + val = self.element.unwrap(writer, val) + writer.println('%(ret)s = %(val)s;' % locals()) + return ret + + def wrap(self, writer, val): + return writer.pycapsule_new(val, self.element.capsule_name, + self.element.fullname) + +class ownedptr(ptr): + pass + +def const(ptr_or_ref): + ptr_or_ref.const = True + return ptr_or_ref + +class cast(_Type): + format = 'O' + + def __init__(self, original, target): + self.original = original + self.target = target + + @property + def fullname(self): + return self.binding_type.fullname + + @property + def python_type(self): + if not isinstance(self.target, _Type): + return self.target + else: + return self.original + + @property + def binding_type(self): + if isinstance(self.target, _Type): + return self.target + else: + return self.original + + def wrap(self, writer, val): + dst = self.python_type.__name__ + if dst == 'int': + unsigned = set([Unsigned, UnsignedLongLong, Uint64, + Size_t, VoidPtr]) + signed = set([LongLong, Int64, Int]) + assert self.binding_type in unsigned|signed + if self.binding_type in signed: + signflag = 'signed' + else: + signflag = 'unsigned' + fn = 'py_%(dst)s_from_%(signflag)s' % locals() + else: + fn = 'py_%(dst)s_from' % locals() + return writer.call(fn, 'PyObject*', val) + + def unwrap(self, writer, val): + src = self.python_type.__name__ + dst = self.binding_type.fullname + ret = writer.declare(dst) + fn = 'py_%(src)s_to' % locals() + status = writer.call(fn, 'int', val, ret) + writer.die_if_false(status) + return ret + + +class CustomPythonMethod(object): + def __init__(self, fn): + src = inspect.getsource(fn) + lines = textwrap.dedent(src).splitlines() + for i, line in enumerate(lines): + if not line.startswith('@'): + break + self.sourcelines = lines[i:] + + def compile_py(self, writer): + for line in self.sourcelines: + writer.println(line) + +class CustomPythonStaticMethod(CustomPythonMethod): + def compile_py(self, writer): + writer.println('@staticmethod') + super(CustomPythonStaticMethod, self).compile_py(writer) + + +class Attr(object): + def __init__(self, getter, setter): + self.getter = getter + self.setter = setter + self.includes = set() + + @property + def fullname(self): + try: + name = self.realname + except AttributeError: + name = self.name + return '::'.join([self.parent.fullname, name]) + + def __str__(self): + return self.fullname + + @property + def getter_name(self): + return '%s_get' % self.name + + @property + def setter_name(self): + return '%s_set' % self.name + + @property + def getter_c_name(self): + return cg.mangle('%s_get' % self.fullname) + + @property + def setter_c_name(self): + return cg.mangle('%s_set' % self.fullname) + + def generate_cpp(self, println): + self.compile_cpp(cg.CppCodeWriter(println)) + + def compile_cpp(self, writer): + # getter + with writer.py_function(self.getter_c_name): + (this,) = writer.parse_arguments('args', ptr(self.parent)) + attr = self.name + ret = writer.declare(self.getter.fullname, + '%(this)s->%(attr)s' % locals()) + writer.return_value(self.getter.wrap(writer, ret)) + # setter + with writer.py_function(self.setter_c_name): + (this, value) = writer.parse_arguments('args', ptr(self.parent), + self.setter) + attr = self.name + writer.println('%(this)s->%(attr)s = %(value)s;' % locals()) + writer.return_value(None) + + def compile_py(self, writer): + name = self.name + parent = '.'.join(self.parent.fullname.split('::')) + getter = '.'.join([parent, self.getter_name]) + setter = '.'.join([parent, self.setter_name]) + writer.println('@property') + with writer.block('def %(name)s(self):' % locals()): + unself = writer.unwrap('self') + ret = writer.new_symbol('ret') + writer.println('%(ret)s = _api.%(getter)s(%(unself)s)' % locals()) + is_ownedptr = isinstance(self.getter, ownedptr) + writer.return_value(writer.wrap(ret, is_ownedptr)) + writer.println() + writer.println('@%(name)s.setter' % locals()) + with writer.block('def %(name)s(self, value):' % locals()): + unself = writer.unwrap('self') + unvalue = writer.unwrap('value') + if isinstance(self.setter, ownedptr): + writer.release_ownership(unvalue) + writer.println('return _api.%(setter)s(%(unself)s, %(unvalue)s)' % + locals()) + writer.println() + + diff --git a/llvmpy/gen/codegen.py b/llvmpy/gen/codegen.py new file mode 100644 index 0000000..f9585fd --- /dev/null +++ b/llvmpy/gen/codegen.py @@ -0,0 +1,289 @@ +import re, contextlib + +NULL = 'NULL' + +_symbols = set() + +def wrap_println_from_file(file): + def println(s=''): + file.write(s) + file.write('\n') + return println + +def indent(println): + def _println(s=''): + println("%s%s" % (' '* 4, s)) + return _println + +def quote(txt): + return '"%s"' % txt + +def new_symbol(name): + if name in _symbols: + ct = 1 + orig = name + while name in _symbols: + name = '%s%d' % (orig, ct) + ct += 1 + _symbols.add(name) + return name + +def parse_arguments(println, var, *args): + typecodes = [] + holders = [] + argvals = [] + for arg in args: + typecodes.append(arg.format) + val = declare(println, 'PyObject*') + argvals.append(val) + holders.append('&' + val) + + items = [var, '"%s"' % (''.join(typecodes))] + holders + println('if(!PyArg_ParseTuple(%s)) return NULL;' % ', '.join(items)) + + # unwrap + unwrapped = [] + for arg, val in zip(args, argvals): + unwrapped.append(arg.unwrap(println, val)) + + return unwrapped + +_re_mangle_pattern = re.compile(r'[ _<>\*&,]') + +def mangle(name): + def repl(m): + s = m.group(0) + if s in '<>*&': + return '' + elif s in ' ,': + return '_' + elif s in '_': + return '__' + else: + assert False + name = _re_mangle_pattern.sub(repl, name) + return name.replace('::', '_') + +def pycapsule_new(println, ptr, name, clsname): + # build capsule + name_soften = mangle(name) + var = new_symbol('pycap_%s' % name_soften) + fmt = 'PyObject* %(var)s = pycapsule_new(%(ptr)s, "%(name)s", "%(clsname)s");' + println(fmt % locals()) + println('if (!%(var)s) return NULL;' % locals()) + return var + + +def declare(println, typ, init=None): + typ_soften = mangle(typ) + var = new_symbol('var_%s' % typ_soften) + if init is None: + println('%(typ)s %(var)s;' % locals()) + else: + println('%(typ)s %(var)s = %(init)s;' % locals()) + return var + + +def return_value(println, var): + println('return %(var)s;' % locals()) + + +def return_none(println): + println('Py_RETURN_NONE;') + + +def die_if_null(println, var): + println('if (!%(var)s) return NULL;' % locals()) + + +class CodeWriterBase(object): + def __init__(self, println): + self.println = println + self.used_symbols = set() + + @contextlib.contextmanager + def indent(self): + old = self.println + self.println = indent(self.println) + yield + self.println = old + + @contextlib.contextmanager + def py_function(self, name): + self.println('static') + self.println('PyObject*') + with self.block('%(name)s(PyObject* self, PyObject* args)' % locals()): + self.used_symbols.add('self') + self.used_symbols.add('args') + yield + self.println() + + def new_symbol(self, name): + if name in self.used_symbols: + ct = 1 + orig = name + while name in self.used_symbols: + name = '%s%d' % (orig, ct) + ct += 1 + self.used_symbols.add(name) + return name + +class CppCodeWriter(CodeWriterBase): + @contextlib.contextmanager + def block(self, lead): + self.println(lead) + self.println('{') + with self.indent(): + yield + self.println('}') + + def declare(self, typ, init=None): + typ_soften = mangle(typ) + var = self.new_symbol('var_%s' % typ_soften) + if init is None: + self.println('%(typ)s %(var)s;' % locals()) + else: + self.println('%(typ)s %(var)s = %(init)s;' % locals()) + return var + + def return_value(self, val): + if val is None: + self.println('Py_RETURN_NONE;') + else: + self.println('return %s;' % val) + + def return_null(self): + self.return_value(NULL) + + def parse_arguments(self, var, *args): + typecodes = [] + holders = [] + argvals = [] + for arg in args: + typecodes.append(arg.format) + val = self.declare('PyObject*') + argvals.append(val) + holders.append('&' + val) + + items = [var, '"%s"' % (''.join(typecodes))] + holders + with self.block('if(!PyArg_ParseTuple(%s))' % ', '.join(items)): + self.return_null() + + # unwrap + unwrapped = [] + for arg, val in zip(args, argvals): + unwrapped.append(arg.unwrap(self, val)) + + return unwrapped + + def call(self, func, retty, *args): + arglist = ', '.join(args) + stmt = '%(func)s(%(arglist)s)' % locals() + if retty == 'void': + self.println(stmt + ';') + else: + return self.declare(retty, stmt) + + def method_call(self, func, retty, *args): + this = args[0] + arglist = ', '.join(args[1:]) + if func == 'delete': + assert not arglist + stmt = 'delete %(this)s' % locals() + elif func == 'new': + alloctype = retty.rstrip(' *') + stmt = 'new %(alloctype)s(%(arglist)s)' % locals() + else: + stmt = '%(this)s->%(func)s(%(arglist)s)' % locals() + if retty == 'void': + self.println('%s;' % stmt) + else: + return self.declare(retty, stmt) + + def pycapsule_new(self, ptr, name, clsname): + name_soften = mangle(name) + ret = self.call('pycapsule_new', 'PyObject*', ptr, quote(name), + quote(clsname)) + with self.block('if (!%(ret)s)' % locals()): + self.return_null() + return ret + + def die_if_false(self, val, verbose=None): + with self.block('if(!%(val)s)' % locals()): + if verbose: + self.println('puts("Error: %s");' % verbose) + self.return_null() + + def raises(self, exccls, msg): + exc = 'PyExc_%s' % exccls.__name__ + self.println('PyErr_SetString(%s, "%s");' % (exc, msg)) + self.return_null() + + +class PyCodeWriter(CodeWriterBase): + @contextlib.contextmanager + def block(self, lead): + self.println(lead) + with self.indent(): + yield + + @contextlib.contextmanager + def function(self, func, args=(), varargs=None): + with self.scope(): + arguments = [] + for arg in args: + arguments.append(self.new_symbol(arg)) + if varargs: + varargs = self.new_symbol(varargs) + arguments.append('*%s' % varargs) + arglist = ', '.join(arguments) + with self.block('def %(func)s(%(arglist)s):' % locals()): + if arguments: + arguments[-1] = arguments[-1].lstrip('*') + if len(arguments) > 1: + yield arguments + else: + yield arguments[0] + else: + yield + + @contextlib.contextmanager + def scope(self): + self.old = self.used_symbols + self.used_symbols = set() + yield + self.used_symbols = self.old + + def release_ownership(self, val): + self.println('capsule.release_ownership(%(val)s)' % locals()) + + def unwrap_many(self, args): + unwrapped = self.new_symbol('unwrapped') + self.println('%(unwrapped)s = list(map(capsule.unwrap, %(args)s))' % locals()) + return unwrapped + + def unwrap(self, val): + return self.call('capsule.unwrap', args=(val,), ret='unwrapped') + + def wrap(self, val, owned): + wrapped = self.new_symbol('wrapped') + self.println('%(wrapped)s = capsule.wrap(%(val)s, %(owned)s)' % locals()) + return wrapped + + def call(self, func, args=(), varargs=None, ret='ret'): + arguments = [] + for arg in args: + arguments.append(arg) + if varargs: + arguments.append('*%s' % varargs) + arglist = ', '.join(arguments) + ret = self.new_symbol(ret) + self.println('%(ret)s = %(func)s(%(arglist)s)' % locals()) + return ret + + def return_value(self, val=None): + if val is None: + val = '' + self.println('return %s' % val) + + diff --git a/llvmpy/gen/gen.py b/llvmpy/gen/gen.py new file mode 100644 index 0000000..263c289 --- /dev/null +++ b/llvmpy/gen/gen.py @@ -0,0 +1,107 @@ +import sys, os +from binding import * +import codegen + + +extension_entry = ''' + +extern "C" { + +#if (PY_MAJOR_VERSION >= 3) + +PyObject * +PyInit_%(module)s(void) +{ +PyObject *module = create_python_module("%(module)s", meth_%(ns)s); +if (module) { +if (populate_submodules(module, submodule_%(ns)s)) +return module; +} +return NULL; +} + +#else + +PyMODINIT_FUNC +init%(module)s(void) +{ +PyObject *module = create_python_module("%(module)s", meth_%(ns)s); +if (module) { +populate_submodules(module, submodule_%(ns)s); +} +} +#endif + +} // end extern C + +''' + + +def populate_headers(println): + includes = [ + 'cstring', + 'Python.h', + 'python3adapt.h', + 'capsulethunk.h', + 'llvm_binding/conversion.h', + 'llvm_binding/binding.h', + 'llvm_binding/capsule_context.h', + 'llvm_binding/extra.h', # extra submodule to add + ] + for inc in includes: + println('#include "%s"' % inc) + println() + +def main(): + outputfilename = sys.argv[1] + entry_modname = sys.argv[2] + sys.path += [os.path.dirname(os.curdir)] + entry_module = __import__(entry_modname) + + rootns = namespaces[''] + + # Generate C++ source + with open('%s.cpp' % outputfilename, 'w') as cppfile: + println = codegen.wrap_println_from_file(cppfile) + populate_headers(println) # extra headers + # print all includes + for inc in rootns.aggregate_includes(): + println('#include "%s"' % inc) + println() + # print all downcast + downcast_fns = rootns.aggregate_downcast() + for ((fromty, toty), fn) in downcast_fns: + name = fn.name + fmt = ''' +static +%(toty)s* %(name)s(%(fromty)s* arg) +{ + return typecast< %(toty)s >::from(arg); +} +''' + println(fmt % locals()) + + fn.generate_cpp(println) + + println('static') + println('PyMethodDef downcast_methodtable[] = {') + fmt = '{ "%(name)s", (PyCFunction)%(func)s, METH_VARARGS, NULL },' + for _, fn in downcast_fns: + name = fn.name + func = fn.c_name + println(fmt % locals()) + println('{ NULL }') + println('};') + println() + # generate submodule + rootns.generate_cpp(println, extras=[('extra', 'extra_methodtable'), + ('downcast', 'downcast_methodtable')]) + println(extension_entry % {'module' : '_api', + 'ns' : ''}) + + # Generate Python source + rootns.generate_py(rootdir='.', name='api') + + +if __name__ == '__main__': + main() diff --git a/llvmpy/include/capsulethunk.h b/llvmpy/include/capsulethunk.h new file mode 100644 index 0000000..9061782 --- /dev/null +++ b/llvmpy/include/capsulethunk.h @@ -0,0 +1,108 @@ +/** + + This is a modified version of capsulethunk.h for use in llvmpy + +**/ + +#ifndef __CAPSULETHUNK_H +#define __CAPSULETHUNK_H + +//#define Assert(X) do_assert(!!(X), #X, __FILE__, __LINE__) +#define Assert(X) + +static +void do_assert(int cond, const char * msg, const char *file, unsigned line){ + if (not cond) { + fprintf(stderr, "Assertion failed %s:%d\n%s\n", file, line, msg); + exit(1); + } +} + +#if ( (PY_VERSION_HEX < 0x02070000) \ + || ((PY_VERSION_HEX >= 0x03000000) \ + && (PY_VERSION_HEX < 0x03010000)) ) + +typedef void (*PyCapsule_Destructor)(PyObject *); + +struct FakePyCapsule_Desc { + const char *name; + void *context; + PyCapsule_Destructor dtor; + PyObject *parent; + + FakePyCapsule_Desc() : name(0), context(0), dtor(0) {} +}; + +static +FakePyCapsule_Desc* get_pycobj_desc(PyObject *p){ + void *desc = ((PyCObject*)p)->desc; + Assert(desc && "No desc in PyCObject"); + return static_cast(desc); +} + +static +void pycobject_pycapsule_dtor(void *p, void *desc){ + Assert(desc); + Assert(p); + FakePyCapsule_Desc *fpc_desc = static_cast(desc); + Assert(fpc_desc->parent); + Assert(PyCObject_Check(fpc_desc->parent)); + fpc_desc->dtor(static_cast(fpc_desc->parent)); + delete fpc_desc; +} + +static +PyObject* PyCapsule_New(void* ptr, const char *name, PyCapsule_Destructor dtor) +{ + FakePyCapsule_Desc *desc = new FakePyCapsule_Desc; + desc->name = name; + desc->context = NULL; + desc->dtor = dtor; + PyObject *p = PyCObject_FromVoidPtrAndDesc(ptr, desc, + pycobject_pycapsule_dtor); + desc->parent = p; + return p; +} + +static +int PyCapsule_CheckExact(PyObject *p) +{ + return PyCObject_Check(p); +} + +static +void* PyCapsule_GetPointer(PyObject *p, const char *name) +{ + Assert(PyCapsule_CheckExact(p)); + if (strcmp(get_pycobj_desc(p)->name, name) != 0) { + PyErr_SetString(PyExc_ValueError, "Invalid PyCapsule object"); + } + return PyCObject_AsVoidPtr(p); +} + +static +void* PyCapsule_GetContext(PyObject *p) +{ + Assert(p); + Assert(PyCapsule_CheckExact(p)); + return get_pycobj_desc(p)->context; +} + +static +int PyCapsule_SetContext(PyObject *p, void *context) +{ + Assert(PyCapsule_CheckExact(p)); + get_pycobj_desc(p)->context = context; + return 0; +} + +static +const char * PyCapsule_GetName(PyObject *p) +{ +// Assert(PyCapsule_CheckExact(p)); + return get_pycobj_desc(p)->name; +} + +#endif /* #if PY_VERSION_HEX < 0x02070000 */ + +#endif /* __CAPSULETHUNK_H */ diff --git a/llvmpy/include/llvm_binding/auto_pyobject.h b/llvmpy/include/llvm_binding/auto_pyobject.h new file mode 100644 index 0000000..368e64f --- /dev/null +++ b/llvmpy/include/llvm_binding/auto_pyobject.h @@ -0,0 +1,37 @@ +#ifndef AUTO_PYOBJECT_H_ +#define AUTO_PYOBJECT_H_ + +#include + +class auto_pyobject{ + mutable PyObject* PO; +public: + auto_pyobject(): PO(NULL) { } + + auto_pyobject(PyObject* po) : PO(po) { } + + auto_pyobject(const auto_pyobject& other) : PO(*other){ + other.PO = NULL; + } + + ~auto_pyobject() { + Py_XDECREF(PO); + } + + bool operator ! () const { + return !PO; + } + + PyObject* operator * () const { + return PO; + } + + PyObject* get() const { + return PO; + } +private: + // disable assign + void operator = (const auto_pyobject&); +}; + +#endif // AUTO_PYOBJECT_H_ diff --git a/llvmpy/include/llvm_binding/binding.h b/llvmpy/include/llvm_binding/binding.h new file mode 100644 index 0000000..b5c5b48 --- /dev/null +++ b/llvmpy/include/llvm_binding/binding.h @@ -0,0 +1,87 @@ +#include +#include + +#if (PY_MAJOR_VERSION >= 3) + +static +PyObject* +create_python_module(const char *name, PyMethodDef* methtable){ + PyModuleDef module_def_tmp = { + PyModuleDef_HEAD_INIT, + name, + NULL, + -1, + methtable, + NULL, NULL, NULL, NULL + }; + + PyModuleDef* module_def = new PyModuleDef(module_def_tmp); // will leak?? + PyObject* module = PyModule_Create(module_def); + if (module == NULL){ + delete module_def; + return NULL; + } + return module; +} + +#else + +static +PyObject* +create_python_module(const char *name, PyMethodDef* methtable){ + PyObject* module = Py_InitModule(name, methtable); + if (module == NULL) return NULL; + return module; +} + +#endif + +static +PyObject* +create_python_submodule(PyObject* parent, const char* name, + PyMethodDef* methtable) +{ + const char* parentname = PyModule_GetName(parent); + const unsigned len_parent = strlen(parentname); + const unsigned len_sub = strlen(name); + const unsigned len = len_parent + 1 + len_sub; + char* fullname = new char[len + 1]; + strcpy(fullname, parentname); + fullname[len_parent] = '.'; + strcpy(fullname + len_parent + 1, name); + PyObject* submod = create_python_module(fullname, methtable); + delete [] fullname; + if (!submod){ + return NULL; + } + if (-1 == PyModule_AddObject(parent, name, submod)) { + return NULL; + } + Py_INCREF(submod); // otherwise, it would segfault on exit + return submod; +} + +struct SubModuleEntry{ + const char* name; + PyMethodDef* methtable; + SubModuleEntry* submodule; +}; + +static +int populate_submodules(PyObject* parent, SubModuleEntry* entries){ + for(SubModuleEntry* iter = entries; iter->name; ++iter){ + PyObject* submodule = create_python_submodule(parent, + iter->name, + iter->methtable); + if (!submodule){ + return 0; + } else if (iter->submodule){ + // Recursively populate submodules + if (!populate_submodules(submodule, iter->submodule)) { + return 0; + } + } + } + return 1; +} + diff --git a/llvmpy/include/llvm_binding/capsule_context.h b/llvmpy/include/llvm_binding/capsule_context.h new file mode 100644 index 0000000..0256088 --- /dev/null +++ b/llvmpy/include/llvm_binding/capsule_context.h @@ -0,0 +1,66 @@ +#ifndef LLVMPY_CAPSULE_CONTEXT_H_ +#define LLVMPY_CAPSULE_CONTEXT_H_ + +#include +#include +#include "capsulethunk.h" + +struct CapsuleContext { + //const unsigned _magic; + const char* className; + + CapsuleContext(const char* cn) + : className(cn) + { } +}; + +static +void pycapsule_dtor_free_context(PyObject *pycap) +{ + void * context = PyCapsule_GetContext(pycap); + Assert(context); + CapsuleContext* cc = static_cast(context); + //Assert(cc->_magic == 0xdead); + delete cc; +} + + + +static +PyObject* pycapsule_new(void* ptr, + const char* basename, + const char* classname=NULL) +{ + if (!classname) { + classname = basename; + } + if (!ptr) { + Py_RETURN_NONE; + } + PyObject* cap = PyCapsule_New(ptr, basename, pycapsule_dtor_free_context); + if (!cap) { + PyErr_SetString(PyExc_TypeError, "Error creating new PyCapsule"); + return NULL; + } + CapsuleContext* context = new CapsuleContext(classname); + if (0 != PyCapsule_SetContext(cap, context)) { + return NULL; + } + //Assert(context->_magic == 0xdead); + return cap; +} + + +static +PyObject* pycapsule_new(const void* ptr, + const char* basename, + const char* classname=NULL) +{ + // Use const_cast to strip the constantness. + // Let the user take the responsibility. + return pycapsule_new(const_cast(ptr), basename, classname); +} + + +#endif //LLVMPY_CAPSULE_CONTEXT_H_ + diff --git a/llvmpy/include/llvm_binding/conversion.h b/llvmpy/include/llvm_binding/conversion.h new file mode 100644 index 0000000..5395a3f --- /dev/null +++ b/llvmpy/include/llvm_binding/conversion.h @@ -0,0 +1,261 @@ +#include +#include +#include + +// python object unwrapper + +static +int py_bytes_to(PyObject *bytesobj, llvm::StringRef &strref){ + // type check + if (!PyBytes_Check(bytesobj)) { + // raises TypeError + PyErr_SetString(PyExc_TypeError, "Expecting a bytes"); + return 0; + } + // get len and buffer + const Py_ssize_t len = PyBytes_Size(bytesobj); + const char * buf = PyBytes_AsString(bytesobj); + if (!buf) { + // raises TypeError + return 0; + } + // set output + strref = llvm::StringRef(buf, len); + // success + return 1; +} + + + +static +int py_str_to(PyObject *strobj, llvm::StringRef &strref){ + // type check + if (!PyString_Check(strobj)) { + // raises TypeError + PyErr_SetString(PyExc_TypeError, "Expecting a str"); + return 0; + } + // get len and buffer + const Py_ssize_t len = PyString_Size(strobj); + const char * buf = PyString_AsString(strobj); + if (!buf) { + // raises TypeError + return 0; + } + // set output + strref = llvm::StringRef(buf, len); + // success + return 1; +} + +static +int py_str_to(PyObject *strobj, std::string &strref){ + // type check + if (!PyString_Check(strobj)) { + // raises TypeError + PyErr_SetString(PyExc_TypeError, "Expecting a str"); + return 0; + } + // get len and buffer + const char * buf = PyString_AsString(strobj); + if (!buf) { + // raises TypeError + return 0; + } + // set output + strref = std::string(buf); + // success + return 1; +} + + +static +int py_str_to(PyObject *strobj, const char* &strref){ + // type check + if (!PyString_Check(strobj)) { + // raises TypeError + PyErr_SetString(PyExc_TypeError, "Expecting a str"); + return 0; + } + // get buffer + strref = PyString_AsString(strobj); + if (!strref) { + // raises TypeError + return 0; + } + // success + return 1; +} + + +static +int py_int_to(PyObject *intobj, int64_t & val){ + if (!PyInt_Check(intobj) and !PyLong_Check(intobj)) { + // raise TypeError + PyErr_SetString(PyExc_TypeError, "Expecting an int"); + return 0; + } + if (PyLong_Check(intobj)) { + val = PyLong_AsLongLong(intobj); + } else { + val = PyInt_AsLong(intobj); + } + if (PyErr_Occurred()){ + return NULL; + } + // success + return 1; +} + + + +static +int py_int_to(PyObject *intobj, unsigned & val){ + if (!PyInt_Check(intobj) and !PyLong_Check(intobj)) { + // raise TypeError + PyErr_SetString(PyExc_TypeError, "Expecting an int"); + return 0; + } + val = PyInt_AsUnsignedLongMask(intobj); + // success + return 1; +} + +static +int py_int_to(PyObject *intobj, unsigned long long & val){ + if (!PyInt_Check(intobj) and !PyLong_Check(intobj)) { + // raise TypeError; + PyErr_SetString(PyExc_TypeError, "Expecting an int"); + return 0; + } + val = PyInt_AsUnsignedLongLongMask(intobj); + // success + return 1; + +} + +static +int py_int_to(PyObject *intobj, size_t & val){ + unsigned long long ull; + if (py_int_to(intobj, ull)) { + val = (size_t)ull; + return 1; + } else { + return 0; + } +} + + +static +int py_int_to(PyObject *intobj, void* & val){ + if (!PyInt_Check(intobj) and !PyLong_Check(intobj)) { + // raise TypeError + PyErr_SetString(PyExc_TypeError, "Expecting an int"); + return 0; + } + val = PyLong_AsVoidPtr(intobj); + // success + return 1; +} + +static +int py_float_to(PyObject *floatobj, double & val){ + if (!PyFloat_Check(floatobj)) { + // raise TypeError + PyErr_SetString(PyExc_TypeError, "Expecting a float"); + return 0; + } + val = PyFloat_AsDouble(floatobj); + if (PyErr_Occurred()){ + return 0; + } + // success + return 1; +} + + +static +int py_float_to(PyObject *floatobj, float & val){ + double db; + int status = py_float_to(floatobj, db); + if (status) + val = db; + return status; +} + + +static +int py_bool_to(PyObject *boolobj, bool & val){ + if (!PyBool_Check(boolobj)) { + // raise TypeError + PyErr_SetString(PyExc_TypeError, "Expecting a bool"); + return 0; + } + if (boolobj == Py_True) { + val = true; + } else if (boolobj == Py_False) { + val = false; + } else { + PyErr_SetString(PyExc_TypeError, "Invalid boolean object"); + return 0; + } + // success + return 1; +} + +// python object wrapper + +static +PyObject* py_str_from(const std::string &str){ + return PyString_FromStringAndSize(str.c_str(), str.size()); +} +// +//static +//PyObject* py_str_from(const llvm::StringRef *str){ +// return py_str_from(str->str()); +//} + +static +PyObject* py_bool_from(bool val){ + if (val) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + + +static +PyObject* py_int_from_signed(const long long & val){ + return PyLong_FromLongLong(val); +} + +static +PyObject* py_int_from_unsigned(const unsigned long long & val){ + return PyLong_FromUnsignedLongLong(val); +} + +static +PyObject* py_int_from_unsigned(void * addr){ + return PyLong_FromVoidPtr(addr); +} + +static +PyObject* py_float_from(const double& val) { + return PyFloat_FromDouble(val); +} + +// casting +template +struct typecast { + template static + Td* from(Ts* src) { + return llvm::dyn_cast(src); + } + + static + Td* from(void* src) { + return static_cast(src); + } +}; + diff --git a/llvmpy/include/llvm_binding/extra.h b/llvmpy/include/llvm_binding/extra.h new file mode 100644 index 0000000..b33a8a0 --- /dev/null +++ b/llvmpy/include/llvm_binding/extra.h @@ -0,0 +1,904 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "auto_pyobject.h" + +namespace extra{ + using namespace llvm; + + class raw_svector_ostream_helper: public raw_svector_ostream { + SmallVectorImpl *SV; + public: + static + raw_svector_ostream_helper* create() + { + SmallVectorImpl* sv = new SmallVector(); + return new raw_svector_ostream_helper(sv); + } + + ~raw_svector_ostream_helper() + { + delete SV; + } + + protected: + + explicit + raw_svector_ostream_helper(SmallVectorImpl* sv) + : raw_svector_ostream(*sv), SV(sv) {} + + private: + // no copy + raw_svector_ostream_helper(const raw_svector_ostream_helper&); + // no assign + void operator = (const raw_svector_ostream_helper&); + }; + +} + +static +PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) +{ + using extra::raw_svector_ostream_helper; + using llvm::raw_svector_ostream; + + if (!PyArg_ParseTuple(args, "")) { + return NULL; + } + raw_svector_ostream* RSOH = raw_svector_ostream_helper::create(); + return pycapsule_new(RSOH, "llvm::raw_ostream", + "llvm::raw_svector_ostream"); +} + +static +PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) +{ + using llvm::Type; + typedef llvm::SmallVector SmallVector_Type; + + SmallVector_Type* SV = new SmallVector_Type; + Py_ssize_t size = PyTuple_Size(args); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject* cap = PyTuple_GetItem(args, i); + if (!cap) { + return NULL; + } + Type* type = (Type*)PyCapsule_GetPointer(cap, "llvm::Type"); + if (!type) { + return NULL; + } + SV->push_back(type); + } + return pycapsule_new(SV, "llvm::SmallVector"); +} + +static +PyObject* make_small_vector_from_values(PyObject* self, PyObject* args) +{ + using llvm::Value; + typedef llvm::SmallVector SmallVector_Value; + + SmallVector_Value* SV = new SmallVector_Value; + Py_ssize_t size = PyTuple_Size(args); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject* cap = PyTuple_GetItem(args, i); + if (!cap) { + return NULL; + } + Value* value = (Value*)PyCapsule_GetPointer(cap, "llvm::Value"); + if (!value) { + return NULL; + } + SV->push_back(value); + } + return pycapsule_new(SV, "llvm::SmallVector"); +} + + +static +PyObject* make_small_vector_from_unsigned(PyObject* self, PyObject* args) +{ + using llvm::Value; + typedef llvm::SmallVector SmallVector_Unsigned; + + SmallVector_Unsigned* SV = new SmallVector_Unsigned; + Py_ssize_t size = PyTuple_Size(args); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject* item = PyTuple_GetItem(args, i); + if (!item) { + return NULL; + } + unsigned value = PyLong_AsUnsignedLong(item); + if (PyErr_Occurred()){ + return NULL; + } + SV->push_back(value); + } + return pycapsule_new(SV, "llvm::SmallVector"); +} + +static +PyObject* get_llvm_version(PyObject* self, PyObject* args) +{ + return Py_BuildValue("(ii)", LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR); +} + +static PyMethodDef extra_methodtable[] = { + #define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL } + method( make_raw_ostream_for_printing ), + method( make_small_vector_from_types ), + method( make_small_vector_from_values ), + method( make_small_vector_from_unsigned ), + method( get_llvm_version ), + #undef method + { NULL } +}; + + +//////////// +template +PyObject* iterator_to_pylist_deref(iterator begin, iterator end, + const char *capsuleName, const char *className) +{ + PyObject* list = PyList_New(0); + for(; begin != end; ++begin) { + PyObject* cap = pycapsule_new(&*begin, capsuleName, className); + PyList_Append(list, cap); + } + return list; +} + +template +PyObject* iterator_to_pylist(iterator begin, iterator end, + const char *capsuleName, const char *className) +{ + PyObject* list = PyList_New(0); + for(; begin != end; ++begin) { + PyObject* cap = pycapsule_new(*begin, capsuleName, className); + PyList_Append(list, cap); + } + return list; +} + +template +PyObject* iplist_to_pylist(iplist &IPL, const char * capsuleName, + const char* className){ + return iterator_to_pylist_deref(IPL.begin(), IPL.end(), capsuleName, + className); +} + +template +struct extract { + + template + static + bool from_py_sequence(VecTy& vec, PyObject* seq, const char *capsuleName, + bool accept_null=false) + { + Py_ssize_t N = PySequence_Size(seq); + for (Py_ssize_t i = 0; i < N; ++i) { + auto_pyobject item = PySequence_GetItem(seq, i); + if (!item) { + return false; + } + if (accept_null and Py_None == *item) { + vec.push_back(NULL); + } else { + auto_pyobject capsule = PyObject_GetAttrString(*item, "_ptr"); + if (!capsule) { + return false; + } + void* ptr = PyCapsule_GetPointer(*capsule, capsuleName); + if (!ptr) { + return false; + } + ElemTy* res = typecast::from(ptr); + if (!res) { + return false; + } + vec.push_back(res); + } + } + return true; + } + +}; +//static +//bool string_equal(const char *A, const char *B){ +// for (; *A and *B; ++A, ++B) { +// if (*A != *B) return false; +// } +// return true; +//} + +//////////// +static +PyObject* Value_use_iterator_to_list(llvm::Value* val) +{ + return iterator_to_pylist(val->use_begin(), val->use_end(), + "llvm::Value", "llvm::User"); +} + +static +PyObject* Function_getArgumentList(llvm::Function* fn) +{ + return iplist_to_pylist(fn->getArgumentList(), "llvm::Value", + "llvm::Argument"); +} + +static +PyObject* Function_getBasicBlockList(llvm::Function* fn) +{ + return iplist_to_pylist(fn->getBasicBlockList(), "llvm::Value", + "llvm::BasicBlock"); +} + +/* + * errout --- can be any file object + * + */ +static +llvm::ExecutionEngine* ExecutionEngine_create( + llvm::Module* M, + bool ForceInterpreter = false, + PyObject* errout = 0, + llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default, + bool GVsWithCode = true) +{ + using namespace llvm; + std::string ErrorStr; + ExecutionEngine *ee = ExecutionEngine::create(M, ForceInterpreter, + &ErrorStr, OptLevel, + GVsWithCode); + PyFile_WriteString(ErrorStr.c_str(), errout); + return ee; +} + +/* + * errout --- can be any file object + * + */ +static +llvm::ExecutionEngine* ExecutionEngine_createJIT( + llvm::Module* M, + PyObject* errout = 0, + llvm::JITMemoryManager* JMM = 0, + llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default, + bool GCsWithCode = true, + llvm::Reloc::Model RM = llvm::Reloc::Default, + llvm::CodeModel::Model CMM = llvm::CodeModel::JITDefault) +{ + using namespace llvm; + std::string ErrorStr; + ExecutionEngine *ee = ExecutionEngine::createJIT(M, &ErrorStr, JMM, OL, + GCsWithCode, RM, CMM); + PyFile_WriteString(ErrorStr.c_str(), errout); + return ee; +} + +static +llvm::GenericValue* GenericValue_CreateInt(llvm::Type* Ty, unsigned long long N, + bool IsSigned) +{ + // Shamelessly copied from LLVM + llvm::GenericValue *GenVal = new llvm::GenericValue(); + GenVal->IntVal = llvm::APInt(Ty->getIntegerBitWidth(), N, IsSigned); + return GenVal; +} + +static +llvm::GenericValue* GenericValue_CreateFloat(float Val) +{ + llvm::GenericValue *GenVal = new llvm::GenericValue(); + GenVal->FloatVal = Val; + return GenVal; +} + +static +llvm::GenericValue* GenericValue_CreateDouble(double Val) +{ + llvm::GenericValue *GenVal = new llvm::GenericValue(); + GenVal->DoubleVal = Val; + return GenVal; +} + +static +llvm::GenericValue* GenericValue_CreatePointer(void * Ptr) +{ + llvm::GenericValue *GenVal = new llvm::GenericValue(); + GenVal->PointerVal = Ptr; + return GenVal; +} + +static +unsigned GenericValue_ValueIntWidth(llvm::GenericValue *GenValRef) +{ + return GenValRef->IntVal.getBitWidth(); +} + +static +unsigned long long GenericValue_ToUnsignedInt(llvm::GenericValue* GenVal) +{ + return GenVal->IntVal.getZExtValue(); +} + + +static +long long GenericValue_ToSignedInt(llvm::GenericValue* GenVal) +{ + return GenVal->IntVal.getSExtValue(); +} + +static +void* GenericValue_ToPointer(llvm::GenericValue* GenVal) +{ + return GenVal->PointerVal; +} + +static +double GenericValue_ToFloat(llvm::GenericValue* GenVal, llvm::Type* Ty) +{ + switch (Ty->getTypeID()) { + case llvm::Type::FloatTyID: + return GenVal->FloatVal; + default: + // Behavior undefined if type is not a float or a double + return GenVal->DoubleVal; + } +} + +static +PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE, + llvm::Function* Fn, PyObject* Args) +{ + using namespace llvm; + const char * GVN = "llvm::GenericValue"; + if (!PyTuple_Check(Args)) { + PyErr_SetString(PyExc_TypeError, "Expect a tuple of args."); + return NULL; + } + std::vector vec_args; + + Py_ssize_t nargs = PyTuple_Size(Args); + vec_args.reserve(nargs); + for (Py_ssize_t i = 0; i < nargs; ++i) { + PyObject* obj = PyTuple_GetItem(Args, i); + if (!obj) { + PyErr_SetString(PyExc_RuntimeError, "Failed to index into args?"); + return NULL; + } + + GenericValue* gv = static_cast( + PyCapsule_GetPointer(obj, GVN)); + + if (!gv) { + return NULL; + } + vec_args.push_back(*gv); + } + + GenericValue ret = EE->runFunction(Fn, vec_args); + return pycapsule_new(new GenericValue(ret), GVN); +} + +static +PyObject* EngineBuilder_setErrorStr(llvm::EngineBuilder* eb, PyObject* fileobj) +{ + + if (!PyFile_Check(fileobj)) { + PyErr_SetString(PyExc_TypeError, "Expecting a file object."); + return NULL; + } + + std::string buffer; + eb->setErrorStr(&buffer); + + if (-1 == PyFile_WriteString(buffer.c_str(), fileobj)) { + return NULL; + } + + return pycapsule_new(eb, "llvm::EngineBuilder"); +} + +static +PyObject* EngineBuilder_setMAttrs(llvm::EngineBuilder* eb, + PyObject* strlist) +{ + if (!PyList_Check(strlist)) { + PyErr_SetString(PyExc_TypeError, "Expecting a list of string."); + return NULL; + } + std::vector tmp; + const Py_ssize_t N = PyList_Size(strlist); + tmp.reserve(N); + for (Py_ssize_t i = 0; i < N; ++i) { + const char * elem = PyString_AsString(PyList_GetItem(strlist, i)); + if (!elem) { + return NULL; + } + tmp.push_back(elem); + } + eb->setMAttrs(tmp); + return pycapsule_new(eb, "llvm::EngineBuilder"); +} + +static +PyObject* EngineBuilder_selectTarget(llvm::EngineBuilder* eb, + const llvm::Triple& TargetTriple, + llvm::StringRef MArch, + llvm::StringRef MCPU, + PyObject* strlist) +{ + const Py_ssize_t N = PySequence_Size(strlist); + llvm::SmallVector MAttrs; + MAttrs.reserve(N); + for (Py_ssize_t i = 0; i < N; ++i) { + PyObject* str = PySequence_GetItem(strlist, i); + const char * cp = PyString_AsString(str); + if (!cp) { + Py_DECREF(str); + return NULL; + } + MAttrs.push_back(cp); + Py_DECREF(str); + } + eb->selectTarget(TargetTriple, MArch, MCPU, MAttrs); + return pycapsule_new(eb, "llvm::EngineBuilder"); +} + + +static +PyObject* llvm_ParseBitCodeFile(llvm::StringRef Buf, llvm::LLVMContext& Ctx, + PyObject* FObj=NULL) +{ + using namespace llvm; + MemoryBuffer* MB = MemoryBuffer::getMemBuffer(Buf); + Module* M; + if (FObj) { + std::string ErrStr; + M = ParseBitcodeFile(MB, Ctx, &ErrStr); + auto_pyobject buf = PyBytes_FromString(ErrStr.c_str()); + if (NULL == PyObject_CallMethod(FObj, "write", "O", *buf)){ + return NULL; + } +// if (-1 == PyFile_WriteString(ErrStr.c_str(), FObj)) { +// return NULL; +// } + } else { + M = ParseBitcodeFile(MB, Ctx); + } + delete MB; + return pycapsule_new(M, "llvm::Module"); +} + + +static +PyObject* llvm_WriteBitcodeToFile(const llvm::Module *M, PyObject* FObj) +{ + using namespace llvm; + llvm::SmallVector sv; + llvm::raw_svector_ostream rso(sv); + llvm::WriteBitcodeToFile(M, rso); + rso.flush(); + StringRef ref = rso.str(); + auto_pyobject buf = PyBytes_FromStringAndSize(ref.data(), ref.size()); + return PyObject_CallMethod(FObj, "write", "O", *buf); +} + +static +PyObject* llvm_getBitcodeTargetTriple(llvm::StringRef Buf, + llvm::LLVMContext& Ctx, + PyObject* FObj = NULL) +{ + using namespace llvm; + MemoryBuffer* MB = MemoryBuffer::getMemBuffer(Buf); + std::string Triple; + if (FObj) { + std::string ErrStr; + Triple = getBitcodeTargetTriple(MB, Ctx, &ErrStr); + if (-1 == PyFile_WriteString(ErrStr.c_str(), FObj)) { + return NULL; + } + } else { + Triple = getBitcodeTargetTriple(MB, Ctx); + } + delete MB; + return PyString_FromString(Triple.c_str()); +} + +static +PyObject* TargetMachine_addPassesToEmitFile( + llvm::TargetMachine *TM, + llvm::PassManagerBase & PM, + PyObject* Out, + llvm::TargetMachine::CodeGenFileType FTy, + bool disableVerify=true) +{ + using namespace llvm; + llvm::SmallVector sv; + raw_svector_ostream rso(sv); + formatted_raw_ostream fso(rso); + fso.flush(); + bool status = TM->addPassesToEmitFile(PM, fso, FTy, disableVerify); + if (status) { + StringRef sr = rso.str(); + PyObject* buf = PyString_FromStringAndSize(sr.data(), sr.size()); + if (!buf) { + return NULL; + } + if (-1 == PyFile_WriteObject(buf, Out, Py_PRINT_RAW)){ + return NULL; + } + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +static +PyObject* Constant_getIntegerValue(llvm::Type* Ty, PyObject* pyint) +{ + using namespace llvm; + if (!Ty->isIntegerTy()) { + PyErr_SetString(PyExc_ValueError, "Type should be of integer type."); + return NULL; + } + unsigned width = Ty->getIntegerBitWidth(); + if (width > sizeof(unsigned long long)*8) { + PyErr_SetString(PyExc_ValueError, "Integer value is too large."); + } + Constant* K; + if (PyLong_Check(pyint)){ + APInt apint(width, PyLong_AsLongLong(pyint), true); + K = Constant::getIntegerValue(Ty, apint); + } else { + APInt apint(width, PyInt_AsLong(pyint), true); + K = Constant::getIntegerValue(Ty, apint); + } + return pycapsule_new(K, "llvm::Value", "llvm::Constant"); +} + + +static +PyObject* Linker_LinkInModule(llvm::Linker* Linker, + llvm::Module* Mod, + PyObject* ErrMsg) +{ + std::string errmsg; + bool failed = Linker->LinkInModule(Mod, &errmsg); + if (not failed) { + Py_RETURN_FALSE; + } else { + if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) { + return NULL; + } + Py_RETURN_TRUE; + } +} + +static +PyObject* Linker_LinkModules(llvm::Module* Dest, + llvm::Module* Src, + unsigned Mode, + PyObject* ErrMsg) +{ + std::string errmsg; + bool failed = llvm::Linker::LinkModules(Dest, Src, Mode, &errmsg); + if (not failed) { + Py_RETURN_FALSE; + } else { + if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) { + return NULL; + } + Py_RETURN_TRUE; + } +} + +static +PyObject* StructType_setBody(llvm::StructType* Self, + PyObject* Elems, + bool isPacked=false) +{ + using namespace llvm; + std::vector elements; + extract::from_py_sequence(elements, Elems, "llvm::Type"); + Self->setBody(elements, isPacked); + Py_RETURN_NONE; +} + +static +PyObject* StructType_get(llvm::LLVMContext& Cxt, + PyObject* Elems, + bool isPacked=false) +{ + using namespace llvm; + std::vector elements; + extract::from_py_sequence(elements, Elems, "llvm::Type"); + StructType *sty = StructType::get(Cxt, elements, isPacked); + return pycapsule_new(sty, "llvm::Type", "llvm::StructType"); +} + +static +PyObject* Module_list_globals(llvm::Module* Mod) +{ + return iplist_to_pylist(Mod->getGlobalList(), + "llvm::Value", "llvm::GlobalVariable"); +} + +static +PyObject* Module_list_functions(llvm::Module* Mod) +{ + return iplist_to_pylist(Mod->getFunctionList(), + "llvm::Value", "llvm::Function"); +} + +static +PyObject* Module_list_named_metadata(llvm::Module* Mod) +{ + return iplist_to_pylist(Mod->getFunctionList(), + "llvm::NamedMDNode", "llvm::NamedMDNode"); + +} + +static +PyObject* llvm_verifyModule(const llvm::Module& Fn, + llvm::VerifierFailureAction Action, + PyObject* ErrMsg) +{ + std::string errmsg; + bool failed = llvm::verifyModule(Fn, Action, &errmsg); + + if (failed) { + if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) { + return NULL; + } + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +static +PyObject* ConstantArray_get(llvm::ArrayType* Ty, PyObject* Consts) +{ + using namespace llvm; + + std::vector vec_consts; + bool ok = extract::from_py_sequence(vec_consts, Consts, + "llvm::Value"); + if (not ok) return NULL; + Constant* ary = ConstantArray::get(Ty, vec_consts); + return pycapsule_new(ary, "llvm::Value", "llvm::Constant"); +} + +static +PyObject* ConstantStruct_get(llvm::StructType* Ty, PyObject* Elems) +{ + using namespace llvm; + + std::vector vec_consts; + bool ok = extract::from_py_sequence(vec_consts, Elems, + "llvm::Value"); + if (not ok) return NULL; + Constant* ary = ConstantStruct::get(Ty, vec_consts); + return pycapsule_new(ary, "llvm::Value", "llvm::Constant"); +} + +static +PyObject* ConstantStruct_getAnon(PyObject* Elems, + bool isPacked=false) +{ + using namespace llvm; + + std::vector vec_consts; + bool ok = extract::from_py_sequence(vec_consts, Elems, + "llvm::Value"); + if (not ok) return NULL; + Constant* ary = ConstantStruct::getAnon(vec_consts, isPacked); + return pycapsule_new(ary, "llvm::Value", "llvm::Constant"); +} + +static +PyObject* ConstantVector_get(PyObject* Elems) +{ + using namespace llvm; + + std::vector vec_consts; + bool ok = extract::from_py_sequence(vec_consts, Elems, + "llvm::Value"); + if (not ok) return NULL; + Constant* ary = ConstantVector::get(vec_consts); + return pycapsule_new(ary, "llvm::Value", "llvm::Constant"); +} + +static +PyObject* Intrinsic_getDeclaration(llvm::Module* Mod, + unsigned ID, + PyObject* Types=NULL) +{ + using namespace llvm; + Function* Fn = NULL; + if (Types) { + std::vector types; + bool ok = extract::from_py_sequence(types, Types, "llvm::Type"); + if (!ok) return NULL; + Fn = Intrinsic::getDeclaration(Mod, (Intrinsic::ID)ID, types); + } else { + Fn = Intrinsic::getDeclaration(Mod, (Intrinsic::ID)ID); + } + return pycapsule_new(Fn, "llvm::Value", "llvm::Function"); +} + +static +PyObject* MDNode_get(llvm::LLVMContext &Cxt, PyObject* Vals) +{ + std::vector vals; + bool accept_null = true; + bool ok = extract::from_py_sequence(vals, Vals, "llvm::Value", + accept_null); + if (not ok) return NULL; + llvm::MDNode* md = llvm::MDNode::get(Cxt, vals); + return pycapsule_new(md, "llvm::Value", "llvm::MDNode"); +} + + +static +PyObject* BasicBlock_getInstList(llvm::BasicBlock* BB) +{ + return iplist_to_pylist(BB->getInstList(), + "llvm::Value", + "llvm::Instruction"); +} + +static +PyObject* IRBuilder_CreateAggregateRet(llvm::IRBuilder<>* builder, + PyObject* Vals, + unsigned N) +{ + using namespace llvm; + std::vector vec_values; + bool ok = extract::from_py_sequence(vec_values, Vals, "llvm::Value"); + if (not ok) return NULL; + Value** ptr_values = &vec_values[0]; + ReturnInst* inst = builder->CreateAggregateRet(ptr_values, N); + return pycapsule_new(inst, "llvm::Value", "llvm::ReturnInst"); +} + +static +PyObject* DynamicLibrary_LoadLibraryPermanently(const char * Filename, + PyObject* ErrMsg = 0) +{ + using namespace llvm::sys; + bool failed; + if (ErrMsg) { + std::string errmsg; + failed = DynamicLibrary::LoadLibraryPermanently(Filename, &errmsg); + if (failed) { + if (-1 == PyFile_WriteString(errmsg.c_str(), ErrMsg)) { + return NULL; + } + } + } else { + failed = DynamicLibrary::LoadLibraryPermanently(Filename); + } + + if (failed) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +class PassRegistryEnumerator : public llvm::PassRegistrationListener{ +public: + PyObject* List; +public: + PassRegistryEnumerator(PyObject* list) : List(list) { } + + inline virtual void passEnumerate(const llvm::PassInfo * pass_info){ + PyObject* passArg = PyString_FromString(pass_info->getPassArgument()); + PyObject* passName = PyString_FromString(pass_info->getPassName()); + PyList_Append(List, Py_BuildValue("(OO)", passArg, passName)); + } +}; + +static +PyObject* PassRegistry_enumerate(llvm::PassRegistry* PR) +{ + using namespace llvm; + PassRegistryEnumerator PRE(PyList_New(0)); + PR->enumerateWith(&PRE); + return PRE.List; +} + +static +PyObject* TargetRegistry_lookupTarget(const std::string &Triple, + PyObject* Error) +{ + using namespace llvm; + std::string error; + const Target* target = TargetRegistry::lookupTarget(Triple, error); + if (!target) { + PyFile_WriteString(error.c_str(), Error); + Py_RETURN_NONE; + } else { + return pycapsule_new(const_cast(target), "llvm::Target"); + } +} + + +static +PyObject* TargetRegistry_lookupTarget(const std::string &Arch, + llvm::Triple &Triple, + PyObject* Error) +{ + using namespace llvm; + std::string error; + const Target* target = TargetRegistry::lookupTarget(Arch, Triple, error); + if (!target) { + PyFile_WriteString(error.c_str(), Error); + Py_RETURN_NONE; + } else { + return pycapsule_new(const_cast(target), "llvm::Target"); + } +} + + +static +PyObject* TargetRegistry_getClosestTargetForJIT(PyObject* Error) +{ + using namespace llvm; + std::string error; + const Target* target = TargetRegistry::getClosestTargetForJIT(error); + if (!target) { + PyFile_WriteString(error.c_str(), Error); + Py_RETURN_NONE; + } else { + return pycapsule_new(const_cast(target), "llvm::Target"); + } + +} + +static +PyObject* llvm_sys_getHostCPUFeatures(PyObject* Features) +{ + using namespace llvm::sys; + using namespace llvm; + typedef StringMap::iterator iterator; + StringMap features; + bool ok = getHostCPUFeatures(features); + if (ok) { + for (iterator it = features.begin(); it != features.end(); ++it) { + const char *key = it->getKey().data(); + PyObject *val = it->getValue() ? Py_True : Py_False; + Py_INCREF(val); + if (-1 == PyDict_SetItemString(Features, key, val)) { + return NULL; + } + } + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + diff --git a/llvmpy/include/python3adapt.h b/llvmpy/include/python3adapt.h new file mode 100644 index 0000000..5b19ebe --- /dev/null +++ b/llvmpy/include/python3adapt.h @@ -0,0 +1,32 @@ +#ifndef PYTHON3ADAPT_H +#define PYTHON3ADAPT_H + +#if (PY_VERSION_HEX < 0x03000000) + +#define PyBytes_Check PyString_Check +#define PyBytes_Size PyString_Size +#define PyBytes_AsString PyString_AsString +#define PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PyBytes_FromString PyString_FromString + +#endif + +#if (PY_VERSION_HEX >= 0x03000000) + +#define PyString_Check PyUnicode_Check +#define PyString_Size PyUnicode_GET_SIZE +#define PyString_AsString PyUnicode_AsUTF8 +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize +#define PyString_FromString PyUnicode_FromString + +#define PyInt_Check PyLong_Check +#define PyInt_FromLong PyLong_FromLong +#define PyInt_AsLong PyLong_AsLong +#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask +#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + +#define PyFile_Check(x) (1) + +#endif + +#endif //PYTHON3ADAPT_H \ No newline at end of file diff --git a/llvmpy/setup.py b/llvmpy/setup.py new file mode 100644 index 0000000..bb23c32 --- /dev/null +++ b/llvmpy/setup.py @@ -0,0 +1,64 @@ +import sys, os +from distutils.core import setup, Extension + +llvm_config = os.environ.get('LLVM_CONFIG_PATH') + +def run_llvm_config(args): + cmd = llvm_config + ' ' + ' '.join(args) + return os.popen(cmd).read().rstrip() + +def get_libs_and_objs(components): + parts = run_llvm_config(['--libs'] + components).split() + libs = [] + objs = [] + for part in parts: + if part.startswith('-l'): + libs.append(part[2:]) + elif part.endswith('.o'): + objs.append(part) + return libs, objs + +incdir = run_llvm_config(['--includedir']) +libdir = run_llvm_config(['--libdir']) +ldflags = run_llvm_config(['--ldflags']) +macros = [('__STDC_CONSTANT_MACROS', None), + ('__STDC_LIMIT_MACROS', None)] + +extra_link_args = ldflags.split() + +components = ['core', 'analysis', 'scalaropts', + 'executionengine', 'jit', 'native', + 'interpreter', 'bitreader', + 'bitwriter', 'instrumentation', 'ipa', + 'ipo', 'transformutils', 'asmparser', + 'linker', 'support', 'vectorize', + ] + +nvptx = ['nvptx', + 'nvptxasmprinter', + 'nvptxcodegen', + 'nvptxdesc', + 'nvptxinfo'] + +libs_core, objs_core = get_libs_and_objs(components + nvptx) + + +ext_modules = [Extension(name='_api', + sources=['api.cpp'], + include_dirs = ['include', incdir], + library_dirs = [libdir], + libraries = libs_core, + define_macros = macros, + extra_objects = objs_core, + extra_link_args = extra_link_args), + Extension(name='_capsule', + sources=['capsule.cpp'], + include_dirs = ['include'],), + ] + + +setup(name = 'llvmpy2', + description = 'Python bindings for LLVM', + author = 'Siu Kwan Lam', + ext_modules = ext_modules, + license = "BSD") diff --git a/llvmpy/src/ADT/SmallVector.py b/llvmpy/src/ADT/SmallVector.py new file mode 100644 index 0000000..f52ff60 --- /dev/null +++ b/llvmpy/src/ADT/SmallVector.py @@ -0,0 +1,17 @@ +from binding import * +from ..namespace import llvm + +@llvm.Class() +class SmallVector_Type: + _realname_ = 'SmallVector' + delete = Destructor() + +@llvm.Class() +class SmallVector_Value: + _realname_ = 'SmallVector' + delete = Destructor() + +@llvm.Class() +class SmallVector_Unsigned: + _realname_ = 'SmallVector' + delete = Destructor() diff --git a/llvmpy/src/ADT/StringRef.py b/llvmpy/src/ADT/StringRef.py new file mode 100644 index 0000000..e6fc8f2 --- /dev/null +++ b/llvmpy/src/ADT/StringRef.py @@ -0,0 +1,7 @@ +from binding import * +from ..namespace import llvm + +@llvm.Class() +class StringRef: + _include_ = "llvm/ADT/StringRef.h" + diff --git a/llvmpy/src/ADT/Triple.py b/llvmpy/src/ADT/Triple.py new file mode 100644 index 0000000..1615c1c --- /dev/null +++ b/llvmpy/src/ADT/Triple.py @@ -0,0 +1,55 @@ +from binding import * +from ..namespace import llvm +from .StringRef import StringRef + +Triple = llvm.Class() + +@Triple +class Triple: + _include_ = 'llvm/ADT/Triple.h' + + new = Constructor() + new |= Constructor(cast(str, StringRef)) + new |= Constructor(cast(str, StringRef), + cast(str, StringRef), cast(str, StringRef)) + + def _return_str(): + return Method(cast(StringRef, str)) + + getTriple = _return_str() + getArchName = _return_str() + getVendorName = _return_str() + getOSName = _return_str() + getEnvironmentName = _return_str() + getOSAndEnvironmentName = _return_str() + + @CustomPythonMethod + def __str__(self): + return self.getTriple() + + def _return_bool(*args): + return Method(cast(bool, Bool), *args) + + isArch64Bit = _return_bool() + isArch32Bit = _return_bool() + isArch16Bit = _return_bool() + isOSVersionLT = _return_bool(cast(int, Unsigned), + cast(int, Unsigned), + cast(int, Unsigned)).require_only(1) + + isMacOSXVersionLT = _return_bool(cast(int, Unsigned), + cast(int, Unsigned), + cast(int, Unsigned)).require_only(1) + + isMacOSX = _return_bool() + isOSDarwin = _return_bool() + isOSCygMing = _return_bool() + isOSWindows = _return_bool() + # isOSNaCl = _return_bool() + isOSBinFormatELF = _return_bool() + isOSBinFormatCOFF = _return_bool() + isEnvironmentMachO = _return_bool() + + get32BitArchVariant = Method(Triple) + get64BitArchVariant = Method(Triple) + diff --git a/llvmpy/src/ADT/__init__.py b/llvmpy/src/ADT/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/ADT/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/Analysis/Verifier.py b/llvmpy/src/Analysis/Verifier.py new file mode 100644 index 0000000..3afa075 --- /dev/null +++ b/llvmpy/src/Analysis/Verifier.py @@ -0,0 +1,25 @@ +from binding import * +from ..namespace import llvm +from ..Module import Module +from ..Value import Function + +llvm.includes.add('llvm/Analysis/Verifier.h') + +VerifierFailureAction = llvm.Enum('VerifierFailureAction', + '''AbortProcessAction + PrintMessageAction + ReturnStatusAction''') + +verifyModule = llvm.CustomFunction('verifyModule', + 'llvm_verifyModule', + PyObjectPtr, # boolean -- failed? + ref(Module), + VerifierFailureAction, + PyObjectPtr, # errmsg + ) + +verifyFunction = llvm.Function('verifyFunction', + cast(Bool, bool), # failed? + ref(Function), + VerifierFailureAction) + diff --git a/llvmpy/src/Analysis/__init__.py b/llvmpy/src/Analysis/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/Analysis/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/Argument.py b/llvmpy/src/Argument.py new file mode 100644 index 0000000..4f0b7a4 --- /dev/null +++ b/llvmpy/src/Argument.py @@ -0,0 +1,15 @@ +from binding import * +from .namespace import llvm +from .Value import Argument, Value +from .Attributes import Attributes + +@Argument +class Argument: + _include_ = 'llvm/Argument.h' + + _downcast_ = Value + + addAttr = Method(Void, ref(Attributes)) + removeAttr = Method(Void, ref(Attributes)) + getParamAlignment = Method(cast(Unsigned, int)) + diff --git a/llvmpy/src/Assembly/AssemblyAnnotationWriter.py b/llvmpy/src/Assembly/AssemblyAnnotationWriter.py new file mode 100644 index 0000000..6b4d694 --- /dev/null +++ b/llvmpy/src/Assembly/AssemblyAnnotationWriter.py @@ -0,0 +1,7 @@ +from binding import * +from ..namespace import llvm + +@llvm.Class() +class AssemblyAnnotationWriter: + _include_ = "llvm/Assembly/AssemblyAnnotationWriter.h" + diff --git a/llvmpy/src/Assembly/Parser.py b/llvmpy/src/Assembly/Parser.py new file mode 100644 index 0000000..1858bcd --- /dev/null +++ b/llvmpy/src/Assembly/Parser.py @@ -0,0 +1,14 @@ +from binding import * +from ..namespace import llvm +from ..Module import Module +from ..LLVMContext import LLVMContext +from ..Support.SourceMgr import SMDiagnostic + +llvm.includes.add('llvm/Assembly/Parser.h') + +ParseAssemblyString = llvm.Function('ParseAssemblyString', + ptr(Module), + cast(str, ConstCharPtr), + ptr(Module), # can be None + ref(SMDiagnostic), + ref(LLVMContext)) diff --git a/llvmpy/src/Assembly/__init__.py b/llvmpy/src/Assembly/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/Assembly/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/Attributes.py b/llvmpy/src/Attributes.py new file mode 100644 index 0000000..4fe7651 --- /dev/null +++ b/llvmpy/src/Attributes.py @@ -0,0 +1,39 @@ +from binding import * +from .namespace import llvm +from .LLVMContext import LLVMContext + +llvm.includes.add('llvm/Attributes.h') + +Attributes = llvm.Class() +AttrBuilder = llvm.Class() + + +@Attributes +class Attributes: + AttrVal = Enum('''None, AddressSafety, Alignment, AlwaysInline, + ByVal, InlineHint, InReg, MinSize, + Naked, Nest, NoAlias, NoCapture, + NoImplicitFloat, NoInline, NonLazyBind, NoRedZone, + NoReturn, NoUnwind, OptimizeForSize, ReadNone, + ReadOnly, ReturnsTwice, SExt, StackAlignment, + StackProtect, StackProtectReq, StructRet, UWTable, ZExt''') + + delete = Destructor() + + get = StaticMethod(Attributes, ref(LLVMContext), ref(AttrBuilder)) + + +@AttrBuilder +class AttrBuilder: + + new = Constructor() + delete = Destructor() + + clear = Method() + + addAttribute = Method(ref(AttrBuilder), Attributes.AttrVal) + removeAttribute = Method(ref(AttrBuilder), Attributes.AttrVal) + + addAlignmentAttr = Method(ref(AttrBuilder), cast(int, Unsigned)) + + diff --git a/llvmpy/src/BasicBlock.py b/llvmpy/src/BasicBlock.py new file mode 100644 index 0000000..77eaf01 --- /dev/null +++ b/llvmpy/src/BasicBlock.py @@ -0,0 +1,26 @@ +from binding import * +from .namespace import llvm +from .Value import Function, BasicBlock +from .Instruction import Instruction, TerminatorInst +from .LLVMContext import LLVMContext +from .ADT.StringRef import StringRef + +@BasicBlock +class BasicBlock: + Create = StaticMethod(ptr(BasicBlock), ref(LLVMContext), + cast(str, StringRef), + ptr(Function), + ptr(BasicBlock)) + + getParent = Method(ptr(Function)) + getTerminator = Method(ptr(TerminatorInst)) + + empty = Method(cast(Bool, bool)) + dropAllReferences = Method() + isLandingPad = Method(cast(Bool, bool)) + removePredecessor = Method(Void, ptr(BasicBlock), cast(bool, Bool)) + removePredecessor |= Method(Void, ptr(BasicBlock)) + + getInstList = CustomMethod('BasicBlock_getInstList', PyObjectPtr) + + eraseFromParent = Method() diff --git a/llvmpy/src/Bitcode/ReaderWriter.py b/llvmpy/src/Bitcode/ReaderWriter.py new file mode 100644 index 0000000..b950ba4 --- /dev/null +++ b/llvmpy/src/Bitcode/ReaderWriter.py @@ -0,0 +1,30 @@ +from binding import * +from ..namespace import llvm +from ..ADT.StringRef import StringRef +from ..Module import Module +from ..LLVMContext import LLVMContext + +llvm.includes.add('llvm/Bitcode/ReaderWriter.h') + +ParseBitCodeFile = llvm.CustomFunction('ParseBitCodeFile', + 'llvm_ParseBitCodeFile', + PyObjectPtr, # returns Module* + cast(bytes, StringRef), + ref(LLVMContext), + PyObjectPtr, # file-like object + ).require_only(2) + +WriteBitcodeToFile = llvm.CustomFunction('WriteBitcodeToFile', + 'llvm_WriteBitcodeToFile', + PyObjectPtr, # return None + ptr(Module), + PyObjectPtr, # file-like object + ) + +getBitcodeTargetTriple = llvm.CustomFunction('getBitcodeTargetTriple', + 'llvm_getBitcodeTargetTriple', + PyObjectPtr, # return str + cast(str, StringRef), + ref(LLVMContext), + PyObjectPtr, # file-like object + ).require_only(2) diff --git a/llvmpy/src/Bitcode/__init__.py b/llvmpy/src/Bitcode/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/Bitcode/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/CallingConv.py b/llvmpy/src/CallingConv.py new file mode 100644 index 0000000..efca1fc --- /dev/null +++ b/llvmpy/src/CallingConv.py @@ -0,0 +1,10 @@ +from binding import * +from .namespace import llvm + +CallingConv = llvm.Namespace('CallingConv') +ID = CallingConv.Enum('ID', ''' + C, Fast, Cold, GHC, FirstTargetCC, X86_StdCall, X86_FastCall, + ARM_APCS, ARM_AAPCS, ARM_AAPCS_VFP, MSP430_INTR, X86_ThisCall, + PTX_Kernel, PTX_Device, MBLAZE_INTR, MBLAZE_SVOL, SPIR_FUNC, + SPIR_KERNEL, Intel_OCL_BI + ''') # HiPE diff --git a/llvmpy/src/CodeGen/MachineCodeInfo.py b/llvmpy/src/CodeGen/MachineCodeInfo.py new file mode 100644 index 0000000..fc3a1b6 --- /dev/null +++ b/llvmpy/src/CodeGen/MachineCodeInfo.py @@ -0,0 +1,13 @@ +from binding import * +from ..namespace import llvm + +MachineCodeInfo = llvm.Class() + +@MachineCodeInfo +class MachineCodeInfo: + _include_ = 'llvm/CodeGen/MachineCodeInfo.h' + setSize = Method(Void, cast(int, Size_t)) + setAddress = Method(Void, cast(int, VoidPtr)) + size = Method(cast(Size_t, int)) + address = Method(cast(VoidPtr, int)) + diff --git a/llvmpy/src/CodeGen/__init__.py b/llvmpy/src/CodeGen/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/CodeGen/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/Constant.py b/llvmpy/src/Constant.py new file mode 100644 index 0000000..70dc3bf --- /dev/null +++ b/llvmpy/src/Constant.py @@ -0,0 +1,274 @@ +from binding import * +from .namespace import llvm +from .Value import Value +from .Value import Constant, UndefValue, ConstantInt, ConstantFP, ConstantArray +from .Value import ConstantStruct, ConstantVector, ConstantVector +from .Value import ConstantDataSequential, ConstantDataArray, ConstantExpr +from .LLVMContext import LLVMContext +from .ADT.StringRef import StringRef +from .ADT.SmallVector import SmallVector_Value, SmallVector_Unsigned +from .Type import Type, IntegerType, ArrayType, StructType +from .Instruction import CmpInst + +@Constant +class Constant: + _downcast_ = Value + + isNullValue = Method(cast(bool, Bool)) + isAllOnesValue = Method(cast(bool, Bool)) + isNegativeZeroValue = Method(cast(bool, Bool)) + #isZeroValue = Method(cast(bool, Bool)) + canTrap = Method(cast(bool, Bool)) + isThreadDependent = Method(cast(bool, Bool)) + isConstantUsed = Method(cast(bool, Bool)) + + _getAggregateElement_by_int = Method(ptr(Constant), cast(int, Unsigned)) + _getAggregateElement_by_int.realname = 'getAggregateElement' + _getAggregateElement_by_const = Method(ptr(Constant), ptr(Constant)) + _getAggregateElement_by_const.realname = 'getAggregateElement' + + @CustomPythonMethod + def getAggregateElement(self, elt): + if isinstance(elt, Constant): + return self._getAggregateElement_by_const(elt) + else: + return self._getAggregateElement_by_int(elt) + + + removeDeadConstantUsers = Method() + + getNullValue = StaticMethod(ptr(Constant), ptr(Type)) + getAllOnesValue = StaticMethod(ptr(Constant), ptr(Type)) + getIntegerValue = CustomStaticMethod('Constant_getIntegerValue', + PyObjectPtr, # ptr(Constant), + ptr(Type), + PyObjectPtr) + + + +@UndefValue +class UndefValue: + getSequentialElement = Method(ptr(UndefValue)) + getStructElement = Method(ptr(UndefValue), cast(int, Unsigned)) + + _getElementValue_by_const = Method(ptr(UndefValue), ptr(Constant)) + _getElementValue_by_const.realname = 'getElementValue' + + _getElementValue_by_int = Method(ptr(UndefValue), cast(int, Unsigned)) + _getElementValue_by_int.realname = 'getElementValue' + + @CustomPythonMethod + def getElementValue(self, idx): + if isinstance(idx, Constant): + return self._getElementValue_by_const(idx) + else: + return self._getElementValue_by_int(idx) + + destroyConstant = Method() + + get = StaticMethod(ptr(UndefValue), ptr(Type)) + + + +@ConstantInt +class ConstantInt: + _downcast_ = Constant, Value + + get = StaticMethod(ptr(ConstantInt), + ptr(IntegerType), + cast(int, Uint64), + cast(bool, Bool), + ).require_only(2) + isValueValidForType = StaticMethod(cast(Bool, bool), + ptr(Type), + cast(int, Int64)) + getZExtValue = Method(cast(Uint64, int)) + getSExtValue = Method(cast(Int64, int)) + + +@ConstantFP +class ConstantFP: + _downcast_ = Constant, Value + + get = StaticMethod(ptr(Constant), ptr(Type), cast(float, Double)) + getNegativeZero = StaticMethod(ptr(ConstantFP), ptr(Type)) + getInfinity = StaticMethod(ptr(ConstantFP), ptr(Type), cast(bool, Bool)) + + isZero = Method(cast(Bool, bool)) + isNegative = Method(cast(Bool, bool)) + isNaN = Method(cast(Bool, bool)) + + + +@ConstantArray +class ConstantArray: + _downcast_ = Constant, Value + + get = CustomStaticMethod('ConstantArray_get', + PyObjectPtr, # ptr(Constant), + ptr(ArrayType), + PyObjectPtr, # Constants + ) + + +@ConstantStruct +class ConstantStruct: + _downcast_ = Constant, Value + + get = CustomStaticMethod('ConstantStruct_get', + PyObjectPtr, # ptr(Constant) + ptr(StructType), + PyObjectPtr, # Constants + ) + getAnon = CustomStaticMethod('ConstantStruct_getAnon', + PyObjectPtr, # ptr(Constant) + PyObjectPtr, # constants + cast(bool, Bool), # packed + ).require_only(1) + + +@ConstantVector +class ConstantVector: + _downcast_ = Constant, Value + + get = CustomStaticMethod('ConstantVector_get', + PyObjectPtr, # ptr(Constant) + PyObjectPtr, # constants + ) + + +@ConstantDataSequential +class ConstantDataSequential: + _downcast_ = Constant, Value + + +@ConstantDataArray +class ConstantDataArray: + _downcast_ = Constant, Value + + getString = StaticMethod(ptr(Constant), + ref(LLVMContext), + cast(str, StringRef), + cast(bool, Bool) + ).require_only(2) + + + +def _factory(*args): + return StaticMethod(ptr(Constant), *args) + +def _factory_const(*args): + return _factory(ptr(Constant), *args) + +def _factory_const2(*args): + return _factory(ptr(Constant), ptr(Constant), *args) + +def _factory_const_nuw_nsw(): + return _factory_const(cast(bool, Bool), cast(bool, Bool)).require_only(1) + +def _factory_const2_nuw_nsw(): + return _factory_const2(cast(bool, Bool), cast(bool, Bool)).require_only(2) + +def _factory_const2_exact(): + return _factory_const2(cast(bool, Bool)).require_only(2) + +def _factory_const_type(): + return _factory_const(ptr(Type)) + +@ConstantExpr +class ConstantExpr: + _downcast_ = Constant, Value + + getAlignOf = _factory(ptr(Type)) + getSizeOf = _factory(ptr(Type)) + getOffsetOf = _factory(ptr(Type), ptr(Constant)) + getNeg = _factory_const_nuw_nsw() + getFNeg = _factory_const() + getNot = _factory_const() + getAdd = _factory_const2_nuw_nsw() + getFAdd = _factory_const2() + getSub = _factory_const2_nuw_nsw() + getFSub = _factory_const2() + getMul = _factory_const2_nuw_nsw() + getFMul = _factory_const2() + getUDiv = _factory_const2_exact() + getSDiv = _factory_const2_exact() + getFDiv = _factory_const2() + getURem = _factory_const2() + getSRem = _factory_const2() + getFRem = _factory_const2() + getAnd = _factory_const2() + getOr = _factory_const2() + getXor = _factory_const2() + getShl = _factory_const2_nuw_nsw() + getLShr = _factory_const2_exact() + getAShr = _factory_const2_exact() + getTrunc = _factory_const_type() + getSExt = _factory_const_type() + getZExt = _factory_const_type() + getFPTrunc = _factory_const_type() + getFPExtend = _factory_const_type() + getUIToFP = _factory_const_type() + getSIToFP = _factory_const_type() + getFPToUI = _factory_const_type() + getFPToSI = _factory_const_type() + getPtrToInt = _factory_const_type() + getIntToPtr = _factory_const_type() + getBitCast = _factory_const_type() + + getCompare = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant)) + getICmp = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant)) + getFCmp = _factory(CmpInst.Predicate, ptr(Constant), ptr(Constant)) + + getPointerCast = _factory_const_type() + getIntegerCast = _factory_const(ptr(Type), cast(bool, Bool)) + getFPCast = _factory_const_type() + getSelect = _factory(ptr(Constant), ptr(Constant), ptr(Constant)) + + + _getGEP = _factory(ptr(Constant), ref(SmallVector_Value), cast(bool, Bool)) + _getGEP.require_only(2) + _getGEP.realname = 'getGetElementPtr' + + @CustomPythonStaticMethod + def getGetElementPtr(*args): + from llvmpy import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_values(*valuelist) + return ConstantExpr._getGEP(*args) + + getExtractElement = _factory_const2() + getInsertElement = _factory_const2(ptr(Constant)) + getShuffleVector = _factory_const2(ptr(Constant)) + + _getExtractValue = _factory(ptr(Constant), ref(SmallVector_Unsigned)) + _getExtractValue.realname = 'getExtractValue' + + @CustomPythonStaticMethod + def getExtractValue(*args): + from llvmpy import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_unsigned(*valuelist) + return ConstantExpr._getExtractValue(*args) + + _getInsertValue = _factory(ptr(Constant), ptr(Constant), + ref(SmallVector_Unsigned)) + _getInsertValue.realname = 'getInsertValue' + + @CustomPythonStaticMethod + def getInsertValue(*args): + from llvmpy import extra + args = list(args) + valuelist = args[2] + args[1] = extra.make_small_vector_from_unsigned(*valuelist) + return ConstantExpr._getInsertValue(*args) + + getOpcode = Method(cast(Unsigned, int)) + getOpcodeName = Method(cast(ConstCharPtr, str)) + isCast = Method(cast(Bool, bool)) + isCompare = Method(cast(Bool, bool)) + hasIndices = Method(cast(Bool, bool)) + isGEPWithNoNotionalOverIndexing = Method(cast(Bool, bool)) + diff --git a/llvmpy/src/DataLayout.py b/llvmpy/src/DataLayout.py new file mode 100644 index 0000000..7085f52 --- /dev/null +++ b/llvmpy/src/DataLayout.py @@ -0,0 +1,103 @@ +from binding import * +from .namespace import llvm +from .Pass import ImmutablePass + +DataLayout = llvm.Class(ImmutablePass) +StructLayout = llvm.Class() + +from .LLVMContext import LLVMContext +from .ADT.StringRef import StringRef +from .Module import Module +from .Type import Type, IntegerType, StructType +from .ADT.SmallVector import SmallVector_Value +from .GlobalVariable import GlobalVariable + + +@DataLayout +class DataLayout: + _include_ = 'llvm/DataLayout.h' + + _new_string = Constructor(cast(str, StringRef)) + _new_module = Constructor(ptr(Module)) + + @CustomPythonStaticMethod + def new(arg): + if isinstance(arg, Module): + return DataLayout._new_module(arg) + else: + return DataLayout._new_string(arg) + + isLittleEndian = Method(cast(Bool, bool)) + isBigEndian = Method(cast(Bool, bool)) + + getStringRepresentation = Method(cast(StringRef, str)) + + @CustomPythonMethod + def __str__(self): + return self.getStringRepresentation() + + isLegalInteger = Method(cast(Bool, bool), cast(int, Unsigned)) + isIllegalInteger = Method(cast(Bool, bool), cast(int, Unsigned)) + exceedsNaturalStackAlignment = Method(cast(Bool, bool), cast(int, Unsigned)) + fitsInLegalInteger = Method(cast(Bool, bool), cast(int, Unsigned)) + + getPointerABIAlignment = Method(cast(Unsigned, int), + cast(int, Unsigned)).require_only(0) + getPointerPrefAlignment = Method(cast(Unsigned, int), + cast(int, Unsigned)).require_only(0) + getPointerSize = Method(cast(Unsigned, int), + cast(int, Unsigned)).require_only(0) + getPointerSizeInBits = Method(cast(Unsigned, int), + cast(int, Unsigned)).require_only(0) + + getTypeSizeInBits = Method(cast(Uint64, int), ptr(Type)) + getTypeStoreSize = Method(cast(Uint64, int), ptr(Type)) + getTypeStoreSizeInBits = Method(cast(Uint64, int), ptr(Type)) + getTypeAllocSize = Method(cast(Uint64, int), ptr(Type)) + getTypeAllocSizeInBits = Method(cast(Uint64, int), ptr(Type)) + + getABITypeAlignment = Method(cast(Unsigned, int), ptr(Type)) + getABIIntegerTypeAlignment = Method(cast(Unsigned, int), cast(int, Unsigned)) + getCallFrameTypeAlignment = Method(cast(Unsigned, int), ptr(Type)) + getPrefTypeAlignment = Method(cast(Unsigned, int), ptr(Type)) + getPreferredTypeAlignmentShift = Method(cast(Unsigned, int), ptr(Type)) + + _getIntPtrType = Method(ptr(IntegerType), + ref(LLVMContext), cast(int, Unsigned)) + _getIntPtrType.require_only(1) + _getIntPtrType.realname = 'getIntPtrType' + + _getIntPtrType2 = Method(ptr(Type), ptr(Type)) + _getIntPtrType2.realname = 'getIntPtrType' + + @CustomPythonMethod + def getIntPtrType(self, *args): + if isinstance(args[0], LLVMContext): + return self._getIntPtrType(*args) + else: + return self._getIntPtrType(*args) + + _getIndexedOffset = Method(cast(Uint64, int), ptr(Type), + ref(SmallVector_Value)) + _getIndexedOffset.realname = 'getIndexedOffset' + + @CustomPythonMethod + def getIndexedOffset(self, *args): + from llvmpy import extra + args = list(args) + args[1] = extra.make_small_vector_from_values(args[1]) + return self.getIndexedOffset(*args) + + getStructLayout = Method(const(ptr(StructLayout)), ptr(StructType)) + + getPreferredAlignment = Method(cast(Unsigned, int), ptr(GlobalVariable)) + getPreferredAlignmentLog = Method(cast(Unsigned, int), ptr(GlobalVariable)) + +@StructLayout +class StructLayout: + getSizeInBytes = Method(cast(Uint64, int)) + getSizeInBits = Method(cast(Uint64, int)) + getAlignment = Method(cast(Unsigned, int)) + getElementContainingOffset = Method(cast(Unsigned, int), cast(int, Uint64)) + getElementOffset = Method(cast(Uint64, int), cast(int, Unsigned)) + getElementOffsetInBits = Method(cast(Uint64, int), cast(int, Unsigned)) diff --git a/llvmpy/src/DerivedTypes.py b/llvmpy/src/DerivedTypes.py new file mode 100644 index 0000000..02eec8c --- /dev/null +++ b/llvmpy/src/DerivedTypes.py @@ -0,0 +1,33 @@ +from binding import * +from .namespace import llvm +from .LLVMContext import LLVMContext +from .Type import Type +from .ADT.SmallVector import SmallVector_Type + +FunctionType = llvm.Class(Type) + +@FunctionType +class FunctionType: + _include_ = 'llvm/DerivedTypes.h' + _downcast_ = Type + + _get = StaticMethod(ptr(FunctionType), ptr(Type), cast(bool, Bool)) + _get |= StaticMethod(ptr(FunctionType), ptr(Type), ref(SmallVector_Type), + cast(bool, Bool)) + _get.realname = 'get' + + @CustomPythonStaticMethod + def get(*args): + from llvmpy import extra + if len(args) == 3: + typelist = args[1] + sv = extra.make_small_vector_from_types(*typelist) + return FunctionType._get(args[0], sv, args[2]) + else: + return FunctionType._get(*args) + + isVarArg = Method(cast(Bool, bool)) + getReturnType = Method(ptr(Type)) + getParamType = Method(ptr(Type), cast(int, Unsigned)) + getNumParams = Method(cast(Unsigned, int)) + diff --git a/llvmpy/src/EngineBuilder.py b/llvmpy/src/EngineBuilder.py new file mode 100644 index 0000000..4e8ed12 --- /dev/null +++ b/llvmpy/src/EngineBuilder.py @@ -0,0 +1,62 @@ +from binding import * +from .namespace import llvm +from .Module import Module +from .JITMemoryManager import JITMemoryManager +from .Support.CodeGen import CodeGenOpt, Reloc, CodeModel +from .ADT.StringRef import StringRef +from .ExecutionEngine.ExecutionEngine import ExecutionEngine +from .Target.TargetMachine import TargetMachine +from .ADT.Triple import Triple + +EngineBuilder = llvm.Class() + +EngineKind = llvm.Namespace('EngineKind') +Kind = EngineKind.Enum('Kind', 'JIT', 'Interpreter') + +@EngineBuilder +class EngineBuilder: + new = Constructor(ownedptr(Module)) + delete = Destructor() + + def _setter(*args): + return Method(ref(EngineBuilder), *args) + + setEngineKind = _setter(Kind) + setJITMemoryManager = _setter(ptr(JITMemoryManager)) + + setErrorStr = CustomMethod('EngineBuilder_setErrorStr', + PyObjectPtr, PyObjectPtr) + + setOptLevel = _setter(CodeGenOpt.Level) + #setTargetOptions = + setRelocationModel = _setter(Reloc.Model) + setCodeModel = _setter(CodeModel.Model) + setAllocateGVsWithCode = _setter(cast(bool, Bool)) + setMArch = _setter(cast(str, StringRef)) + setMCPU = _setter(cast(str, StringRef)) + setUseMCJIT = _setter(cast(bool, Bool)) + _setMAttrs = CustomMethod('EngineBuilder_setMAttrs', + PyObjectPtr, PyObjectPtr) + @CustomPythonMethod + def setMAttrs(self, attrs): + attrlist = list(str(a) for a in attrs) + return self._setMAttrs(attrlist) + + create = Method(ptr(ExecutionEngine), + ownedptr(TargetMachine)).require_only(0) + + _selectTarget0 = Method(ptr(TargetMachine)) + _selectTarget0.realname = 'selectTarget' + + _selectTarget1 = CustomMethod('EngineBuilder_selectTarget', + PyObjectPtr, + const(ref(Triple)), cast(str, StringRef), + cast(str, StringRef), PyObjectPtr) + + @CustomPythonMethod + def selectTarget(self, *args): + if not args: + return self._selectTarget0() + else: + return self._selectTarget1(*args) + diff --git a/llvmpy/src/ExecutionEngine/ExecutionEngine.py b/llvmpy/src/ExecutionEngine/ExecutionEngine.py new file mode 100644 index 0000000..038d344 --- /dev/null +++ b/llvmpy/src/ExecutionEngine/ExecutionEngine.py @@ -0,0 +1,103 @@ +from binding import * +from ..namespace import llvm +from ..Module import Module +from ..JITMemoryManager import JITMemoryManager +from ..Support.CodeGen import CodeGenOpt, Reloc, CodeModel +from ..DataLayout import DataLayout +from ..Value import Function, GlobalValue, BasicBlock, Constant +from ..GlobalVariable import GlobalVariable +from ..CodeGen.MachineCodeInfo import MachineCodeInfo +from ..GenericValue import GenericValue +from ..Type import Type + +ExecutionEngine = llvm.Class() + +@ExecutionEngine +class ExecutionEngine: + _include_ = ('llvm/ExecutionEngine/ExecutionEngine.h', + 'llvm/ExecutionEngine/JIT.h') # force linking of jit + + delete = Destructor() + + create = CustomStaticMethod('ExecutionEngine_create', + ptr(ExecutionEngine), + ownedptr(Module), cast(bool, Bool), + PyObjectPtr, CodeGenOpt.Level, + cast(bool, Bool)).require_only(1) + + createJIT = CustomStaticMethod('ExecutionEngine_createJIT', + ptr(ExecutionEngine), + ownedptr(Module), PyObjectPtr, + ptr(JITMemoryManager), + CodeGenOpt.Level, + cast(bool, Bool), + Reloc.Model, + CodeModel.Model).require_only(1) + + addModule = Method(Void, ownedptr(Module)) + getDataLayout = Method(const(ownedptr(DataLayout))) + _removeModule = Method(cast(Bool, bool), ptr(Module)) + _removeModule.realname = 'removeModule' + @CustomPythonMethod + def removeModule(self, module): + if self._removeModule(module): + capsule.obtain_ownership(module._capsule) + return True + return False + + FindFunctionNamed = Method(ptr(Function), cast(str, ConstCharPtr)) + getPointerToNamedFunction = Method(cast(VoidPtr, int), + cast(str, StdString), + cast(bool, Bool)).require_only(1) + + runStaticConstructorsDestructors = Method(Void, + cast(Bool, bool), # is dtor + ) + runStaticConstructorsDestructors |= Method(Void, ptr(Module), + cast(Bool, bool)) + + addGlobalMapping = Method(Void, ptr(GlobalValue), cast(int, VoidPtr)) + clearAllGlobalMappings = Method() + clearGlobalMappingsFromModule = Method(Void, ptr(Module)) + updateGlobalMapping = Method(cast(VoidPtr, int), + ptr(GlobalValue), cast(int, VoidPtr)) + + getPointerToGlobalIfAvailable = Method(cast(VoidPtr, int), ptr(GlobalValue)) + getPointerToGlobal = Method(cast(VoidPtr, int), ptr(GlobalValue)) + getPointerToFunction = Method(cast(VoidPtr, int), ptr(Function)) + getPointerToBasicBlock = Method(cast(VoidPtr, int), ptr(BasicBlock)) + getPointerToFunctionOrStub = Method(cast(VoidPtr, int), ptr(Function)) + + runJITOnFunction = Method(Void, ptr(Function), ptr(MachineCodeInfo)) + runJITOnFunction.require_only(1) + + getGlobalValueAtAddress = Method(const(ptr(GlobalValue)), cast(int, VoidPtr)) + + StoreValueToMemory = Method(Void, ref(GenericValue), ptr(GenericValue), + ptr(Type)) + + InitializeMemory = Method(Void, ptr(Constant), cast(int, VoidPtr)) + + recompileAndRelinkFunction = Method(cast(int, VoidPtr), ptr(Function)) + + freeMachineCodeForFunction = Method(Void, ptr(Function)) + getOrEmitGlobalVariable = Method(cast(int, VoidPtr), ptr(GlobalVariable)) + + DisableLazyCompilation = Method(Void, cast(bool, Bool)) + isCompilingLazily = Method(cast(Bool, bool)) + isLazyCompilationDisabled = Method(cast(Bool, bool)) + DisableGVCompilation = Method(Void, cast(bool, Bool)) + isSymbolSearchingDisabled = Method(cast(Bool, bool)) + RegisterTable = Method(Void, ptr(Function), cast(int, VoidPtr)) + DeregisterTable = Method(Void, ptr(Function)) + DeregisterAllTables = Method() + + _runFunction = CustomMethod('ExecutionEngine_RunFunction', + PyObjectPtr, ptr(Function), PyObjectPtr) + + @CustomPythonMethod + def runFunction(self, fn, args): + from llvmpy import capsule + unwrapped = list(map(capsule.unwrap, args)) + return self._runFunction(fn, tuple(unwrapped)) + diff --git a/llvmpy/src/ExecutionEngine/__init__.py b/llvmpy/src/ExecutionEngine/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/ExecutionEngine/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/Function.py b/llvmpy/src/Function.py new file mode 100644 index 0000000..55a50d9 --- /dev/null +++ b/llvmpy/src/Function.py @@ -0,0 +1,55 @@ +from binding import * +from .namespace import llvm +from .Value import GlobalValue, Constant, Function, Argument, Value +from .BasicBlock import BasicBlock +from .Attributes import Attributes +from .Type import Type +from .DerivedTypes import FunctionType +from .LLVMContext import LLVMContext +from .CallingConv import CallingConv + +@Function +class Function: + _include_ = 'llvm/Function.h' + _downcast_ = GlobalValue, Constant, Value + + getReturnType = Method(ptr(Type)) + getFunctionType = Method(ptr(FunctionType)) + getContext = Method(ref(LLVMContext)) + isVarArg = Method(cast(Bool, bool)) + getIntrinsicID = Method(cast(Unsigned, int)) + isIntrinsic = Method(cast(Bool, bool)) + + getCallingConv = Method(CallingConv.ID) + setCallingConv = Method(Void, CallingConv.ID) + + hasGC = Method(cast(bool, Bool)) + getGC = Method(cast(ConstCharPtr, str)) + setGC = Method(Void, cast(str, ConstCharPtr)) + + + getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr) + getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr) + getEntryBlock = Method(ref(BasicBlock)) + + copyAttributesFrom = Method(Void, ptr(GlobalValue)) + + setDoesNotThrow = Method() + doesNotThrow = Method(cast(Bool, bool)) + setDoesNotReturn = Method() + doesNotReturn = Method(cast(Bool, bool)) + setOnlyReadsMemory = Method() + onlyReadsMemory = Method(cast(Bool, bool)) + setDoesNotAccessMemory = Method() + doesNotAccessMemory = Method(cast(Bool, bool)) + + deleteBody = Method() + viewCFG = Method() + viewCFGOnly = Method() + + addFnAttr = Method(Void, Attributes.AttrVal) + removeFnAttr = Method(Void, ref(Attributes)) + + eraseFromParent = Method() + eraseFromParent.disowning = True + diff --git a/llvmpy/src/GenericValue.py b/llvmpy/src/GenericValue.py new file mode 100644 index 0000000..e587b5f --- /dev/null +++ b/llvmpy/src/GenericValue.py @@ -0,0 +1,34 @@ +from binding import * +from .namespace import llvm +from .Type import Type + +GenericValue = llvm.Class() + +@GenericValue +class GenericValue: + delete = Destructor() + + def _factory(name, *argtys): + return CustomStaticMethod('GenericValue_' + name, + ptr(GenericValue), *argtys) + + CreateFloat = _factory('CreateFloat', cast(float, Float)) + + CreateDouble = _factory('CreateDouble', cast(float, Float)) + + CreateInt = _factory('CreateInt', ptr(Type), + cast(int, UnsignedLongLong), cast(bool, Bool)) + + CreatePointer = _factory('CreatePointer', cast(int, VoidPtr)) + + def _accessor(name, *argtys): + return CustomMethod('GenericValue_' + name, *argtys) + + valueIntWidth = _accessor('ValueIntWidth', cast(Unsigned, int)) + + toSignedInt = _accessor('ToSignedInt', cast(LongLong, int)) + toUnsignedInt = _accessor('ToUnsignedInt', cast(UnsignedLongLong, int)) + + toFloat = _accessor('ToFloat', cast(Double, float), ptr(Type)) + + toPointer = _accessor('ToPointer', cast(VoidPtr, int)) \ No newline at end of file diff --git a/llvmpy/src/GlobalValue.py b/llvmpy/src/GlobalValue.py new file mode 100644 index 0000000..2583c6a --- /dev/null +++ b/llvmpy/src/GlobalValue.py @@ -0,0 +1,49 @@ +from binding import * +from .namespace import llvm +from .Value import GlobalValue +from .Module import Module +from .ADT.StringRef import StringRef + +@GlobalValue +class GlobalValue: + _include_ = 'llvm/GlobalValue.h' + + LinkageTypes = Enum(''' + ExternalLinkage, AvailableExternallyLinkage, LinkOnceAnyLinkage, + LinkOnceODRLinkage, LinkOnceODRAutoHideLinkage, WeakAnyLinkage, + WeakODRLinkage, AppendingLinkage, InternalLinkage, PrivateLinkage, + LinkerPrivateLinkage, LinkerPrivateWeakLinkage, DLLImportLinkage, + DLLExportLinkage, ExternalWeakLinkage, CommonLinkage + ''') + + VisibilityTypes = Enum('''DefaultVisibility, + HiddenVisibility, + ProtectedVisibility''') + + setLinkage = Method(Void, LinkageTypes) + getLinkage = Method(LinkageTypes) + + setVisibility = Method(Void, VisibilityTypes) + getVisibility = Method(VisibilityTypes) + + setLinkage = Method(Void, LinkageTypes) + getLinkage = Method(LinkageTypes) + + getAlignment = Method(cast(Unsigned, int)) + setAlignment = Method(Void, cast(int, Unsigned)) + + hasSection = Method(cast(Bool, bool)) + getSection = Method(cast(ConstStdString, str)) + setSection = Method(Void, cast(str, StringRef)) + + isDiscardableIfUnused = Method(cast(Bool, bool)) + mayBeOverridden = Method(cast(Bool, bool)) + isWeakForLinker = Method(cast(Bool, bool)) + copyAttributesFrom = Method(Void, ptr(GlobalValue)) + destroyConstant = Method() + isDeclaration = Method(cast(Bool, bool)) + removeFromParent = Method() + eraseFromParent = Method() + eraseFromParent.disowning = True + + getParent = Method(ptr(Module)) diff --git a/llvmpy/src/GlobalVariable.py b/llvmpy/src/GlobalVariable.py new file mode 100644 index 0000000..c38df27 --- /dev/null +++ b/llvmpy/src/GlobalVariable.py @@ -0,0 +1,49 @@ +from binding import * +from .namespace import llvm + +from .GlobalValue import GlobalValue +GlobalVariable = llvm.Class(GlobalValue) + +from .Module import Module +from .Type import Type +from .ADT.StringRef import StringRef +from .Value import Constant + +@GlobalVariable +class GlobalVariable: + ThreadLocalMode = Enum('''NotThreadLocal, GeneralDynamicTLSModel, + LocalDynamicTLSModel, InitialExecTLSModel, + LocalExecTLSModel + ''') + + new = Constructor(ref(Module), + ptr(Type), + cast(bool, Bool), # is constant + GlobalValue.LinkageTypes, + ptr(Constant), # initializer -- can be None + cast(str, StringRef), # name + ptr(GlobalVariable), # insert before + ThreadLocalMode, + cast(int, Unsigned), # address-space + # cast(bool, Bool), # externally initialized + ).require_only(5) + + setThreadLocal = Method(Void, cast(bool, Bool)) + setThreadLocalMode = Method(Void, ThreadLocalMode) + isThreadLocal = Method(cast(Bool, bool)) + + isConstant = Method(cast(Bool, bool)) + setConstant = Method(Void, cast(bool, Bool)) + + setInitializer = Method(Void, ptr(Constant)) + getInitializer = Method(ptr(Constant)) + hasInitializer = Method(cast(Bool, bool)) + + hasUniqueInitializer = Method(cast(Bool, bool)) + hasDefinitiveInitializer = Method(cast(Bool, bool)) + +# isExternallyInitialized = Method(cast(Bool, bool)) +# setExternallyinitialized = Method(Void, cast(bool, Bool)) + + + \ No newline at end of file diff --git a/llvmpy/src/IRBuilder.py b/llvmpy/src/IRBuilder.py new file mode 100644 index 0000000..afd78a0 --- /dev/null +++ b/llvmpy/src/IRBuilder.py @@ -0,0 +1,326 @@ +from binding import * +from .namespace import llvm +from .LLVMContext import LLVMContext +from .BasicBlock import BasicBlock +from .Instruction import Instruction +from .Instruction import ReturnInst, CallInst, BranchInst, SwitchInst +from .Instruction import IndirectBrInst, InvokeInst, ResumeInst, PHINode +from .Instruction import UnreachableInst, AllocaInst, LoadInst, StoreInst +from .Instruction import FenceInst, AtomicCmpXchgInst, AtomicRMWInst, CmpInst +from .Instruction import LandingPadInst, VAArgInst +from .Instruction import AtomicOrdering, SynchronizationScope +from .ADT.SmallVector import SmallVector_Value, SmallVector_Unsigned +from .ADT.StringRef import StringRef +from .Value import Value, MDNode +from .Type import Type, IntegerType + +IRBuilder = llvm.Class() + +@IRBuilder +class IRBuilder: + _include_ = 'llvm/IRBuilder.h' + _realname_ = 'IRBuilder<>' + + new = Constructor(ref(LLVMContext)) + delete = Destructor() + + GetInsertBlock = Method(ptr(BasicBlock)) + + _SetInsertPoint_end_of_bb = Method(Void, ptr(BasicBlock)) + _SetInsertPoint_end_of_bb.realname = 'SetInsertPoint' + _SetInsertPoint_before_instr = Method(Void, ptr(Instruction)) + _SetInsertPoint_before_instr.realname = 'SetInsertPoint' + + @CustomPythonMethod + def SetInsertPoint(self, pt): + if isinstance(pt, Instruction): + return self._SetInsertPoint_before_instr(pt) + elif isinstance(pt, BasicBlock): + return self._SetInsertPoint_end_of_bb(pt) + else: + raise ValueError("Expected either an Instruction or a BasicBlock") + + isNamePreserving = Method(cast(Bool, bool)) + + CreateRetVoid = Method(ptr(ReturnInst)) + CreateRet = Method(ptr(ReturnInst), ptr(Value)) + CreateAggregateRet = CustomMethod('IRBuilder_CreateAggregateRet', + PyObjectPtr, # ptr(ReturnInst), + PyObjectPtr, # list of Value + cast(int, Unsigned)) + + CreateBr = Method(ptr(BranchInst), ptr(BasicBlock)) + + + CreateCondBr = Method(ptr(BranchInst), ptr(Value), ptr(BasicBlock), + ptr(BasicBlock), ptr(MDNode)).require_only(3) + + CreateSwitch = Method(ptr(SwitchInst), ptr(Value), ptr(BasicBlock), + cast(int, Unsigned), ptr(MDNode)).require_only(2) + + CreateIndirectBr = Method(ptr(IndirectBrInst), ptr(Value), + cast(int, Unsigned)).require_only(1) + + _CreateInvoke = Method(ptr(InvokeInst), ptr(Value), ptr(BasicBlock), + ptr(BasicBlock), ref(SmallVector_Value), + cast(str, StringRef)).require_only(4) + _CreateInvoke.realname = 'CreateInvoke' + + @CustomPythonMethod + def CreateInvoke(self, *args): + from llvmpy import extra + args = list(args) + valuelist = args[3] + args[3] = extra.make_small_vector_from_values(*valuelist) + return self._CreateInvoke(*args) + + CreateResume = Method(ptr(ResumeInst), ptr(Value)) + + CreateUnreachable = Method(ptr(UnreachableInst)) + + def _binop_has_nsw_nuw(): + sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef), + cast(bool, Bool), cast(bool, Bool)] + op = Method(*sig).require_only(2) + return op + + CreateAdd = _binop_has_nsw_nuw() + CreateSub = _binop_has_nsw_nuw() + CreateMul = _binop_has_nsw_nuw() + CreateShl = _binop_has_nsw_nuw() + + def _binop_is_exact(): + sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef), + cast(bool, Bool)] + op = Method(*sig).require_only(2) + return op + + CreateUDiv = _binop_is_exact() + CreateSDiv = _binop_is_exact() + CreateLShr = _binop_is_exact() + CreateAShr = _binop_is_exact() + + def _binop_basic(): + sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef)] + op = Method(*sig).require_only(2) + return op + + CreateURem = _binop_basic() + CreateSRem = _binop_basic() + CreateAnd = _binop_basic() + CreateOr = _binop_basic() + CreateXor = _binop_basic() + + def _float_binop(): + sig = [ptr(Value), ptr(Value), ptr(Value), cast(str, StringRef), + ptr(MDNode)] + op = Method(*sig).require_only(2) + return op + + CreateFAdd = _float_binop() + CreateFSub = _float_binop() + CreateFMul = _float_binop() + CreateFDiv = _float_binop() + CreateFRem = _float_binop() + + def _unop_has_nsw_nuw(): + sig = [ptr(Value), ptr(Value), cast(str, StringRef), + cast(bool, Bool), cast(bool, Bool)] + op = Method(*sig).require_only(1) + return op + + CreateNeg = _unop_has_nsw_nuw() + + def _float_unop(): + sig = [ptr(Value), ptr(Value), cast(str, StringRef), ptr(MDNode)] + op = Method(*sig).require_only(1) + return op + + CreateFNeg = _float_unop() + + CreateNot = Method(ptr(Value), + ptr(Value), cast(str, StringRef)).require_only(1) + + + CreateAlloca = Method(ptr(AllocaInst), + ptr(Type), # ty + ptr(Value), # arysize = 0 + cast(str, StringRef), # name = '' + ).require_only(1) + + CreateLoad = Method(ptr(LoadInst), + ptr(Value), cast(str, StringRef)).require_only(1) + + CreateStore = Method(ptr(StoreInst), ptr(Value), ptr(Value), + cast(bool, Bool)).require_only(2) + + CreateAlignedLoad = Method(ptr(LoadInst), ptr(Value), cast(int, Unsigned), + cast(bool, Bool), cast(str, StringRef)) + CreateAlignedLoad.require_only(2) + + CreateAlignedStore = Method(ptr(StoreInst), ptr(Value), ptr(Value), + cast(int, Unsigned), cast(bool, Bool)) + CreateAlignedStore.require_only(3) + + CreateFence = Method(ptr(FenceInst), + AtomicOrdering, SynchronizationScope).require_only(1) + + CreateAtomicCmpXchg = Method(ptr(AtomicCmpXchgInst), ptr(Value), ptr(Value), + ptr(Value), AtomicOrdering, SynchronizationScope) + CreateAtomicCmpXchg.require_only(4) + + CreateAtomicRMW = Method(ptr(AtomicRMWInst), AtomicRMWInst.BinOp, + ptr(Value), ptr(Value), AtomicOrdering, + SynchronizationScope) + CreateAtomicRMW.require_only(4) + + _CreateGEP = Method(ptr(Value), ptr(Value), ref(SmallVector_Value), + cast(str, StringRef)) + _CreateGEP.require_only(2) + _CreateGEP.realname = 'CreateGEP' + + @CustomPythonMethod + def CreateGEP(self, *args): + from llvmpy import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_values(*valuelist) + return self._CreateGEP(*args) + + _CreateInBoundsGEP = Method(ptr(Value), ptr(Value), ref(SmallVector_Value), + cast(str, StringRef)) + _CreateInBoundsGEP.require_only(2) + _CreateInBoundsGEP.realname = 'CreateInBoundsGEP' + + @CustomPythonMethod + def CreateInBoundsGEP(self, *args): + from llvmpy import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_values(*valuelist) + return self._CreateInBoundsGEP(*args) + + CreateStructGEP = Method(ptr(Value), ptr(Value), cast(int, Unsigned), + cast(str, StringRef)).require_only(2) + + CreateGlobalStringPtr = Method(ptr(Value), cast(str, StringRef), + cast(str, StringRef)).require_only(1) + + def _value_type(): + sig = [ptr(Value), ptr(Value), ptr(Type), cast(str, StringRef)] + op = Method(*sig).require_only(2) + return op + + CreateTrunc = _value_type() + CreateZExt = _value_type() + CreateSExt = _value_type() + CreateZExtOrTrunc = Method(ptr(Value), ptr(Value), ptr(IntegerType), + cast(str, StringRef)).require_only(2) + CreateSExtOrTrunc = Method(ptr(Value), ptr(Value), ptr(IntegerType), + cast(str, StringRef)).require_only(2) + CreateFPToUI = _value_type() + CreateFPToSI = _value_type() + CreateUIToFP = _value_type() + CreateSIToFP = _value_type() + CreateFPTrunc = _value_type() + CreateFPExt = _value_type() + CreatePtrToInt = _value_type() + CreateIntToPtr = _value_type() + CreateBitCast = _value_type() + CreateZExtOrBitCast = _value_type() + CreateSExtOrBitCast = _value_type() + # Skip CreateCast + CreateTruncOrBitCast = _value_type() + CreateIntCast = Method(ptr(Value), ptr(Value), ptr(Type), cast(bool, Bool), + cast(str, StringRef)).require_only(3) + CreateFPCast = _value_type() + + _CreateCall = Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value), + cast(str, StringRef)).require_only(2) + _CreateCall.realname = 'CreateCall' + + @CustomPythonMethod + def CreateCall(self, *args): + from llvmpy import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_values(*valuelist) + return self._CreateCall(*args) + + # Skip specialized CreateICmp* and CreateFCmp* + + CreateICmp = Method(ptr(Value), CmpInst.Predicate, ptr(Value), ptr(Value), + cast(str, StringRef)).require_only(3) + + CreateFCmp = Method(ptr(Value), CmpInst.Predicate, ptr(Value), ptr(Value), + cast(str, StringRef)).require_only(3) + + CreatePHI = Method(ptr(PHINode), ptr(Type), cast(int, Unsigned), + cast(str, StringRef)).require_only(2) + + + CreateSelect = Method(ptr(Value), ptr(Value), ptr(Value), ptr(Value), + cast(str, StringRef)).require_only(3) + + CreateVAArg = Method(ptr(VAArgInst), ptr(Value), ptr(Type), + cast(str, StringRef)).require_only(2) + + CreateExtractElement = _binop_basic() + + CreateInsertElement = Method(ptr(Value), ptr(Value), ptr(Value), ptr(Value), + cast(str, StringRef)).require_only(3) + + CreateShuffleVector = Method(ptr(Value), ptr(Value), ptr(Value), + ptr(Value), cast(str, StringRef)) + CreateShuffleVector.require_only(3) + + _CreateExtractValue = Method(ptr(Value), ptr(Value), + ref(SmallVector_Unsigned), + cast(str, StringRef)) + _CreateExtractValue.require_only(2) + _CreateExtractValue.realname = 'CreateExtractValue' + + @CustomPythonMethod + def CreateExtractValue(self, *args): + from llvmpy import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_unsigned(*valuelist) + return self._CreateExtractValue(*args) + + _CreateInsertValue = Method(ptr(Value), + ptr(Value), # Agg + ptr(Value), # Val + ref(SmallVector_Unsigned), # ArrayRef + cast(str, StringRef), # name + ).require_only(3) + _CreateInsertValue.realname = 'CreateInsertValue' + + @CustomPythonMethod + def CreateInsertValue(self, *args): + from llvmpy import extra + args = list(args) + valuelist = args[2] + args[2] = extra.make_small_vector_from_unsigned(*valuelist) + return self._CreateInsertValue(*args) + + CreateLandingPad = Method(ptr(LandingPadInst), ptr(Type), ptr(Value), + cast(int, Unsigned), cast(str, StringRef)) + CreateLandingPad.require_only(3) + + CreateIsNull = Method(ptr(Value), ptr(Value), cast(str, StringRef)) + CreateIsNull.require_only(1) + + CreateIsNotNull = Method(ptr(Value), ptr(Value), cast(str, StringRef)) + CreateIsNotNull.require_only(1) + + CreatePtrDiff = _binop_basic() + + # New in llvm 3.3 + #CreateVectorSplat = Method(ptr(Value), cast(int, Unsigned), ptr(Value), + # cast(str, StringRef)) + + + Insert = Method(ptr(Instruction), + ptr(Instruction), + cast(str, StringRef)).require_only(1) diff --git a/llvmpy/src/InlineAsm.py b/llvmpy/src/InlineAsm.py new file mode 100644 index 0000000..8793343 --- /dev/null +++ b/llvmpy/src/InlineAsm.py @@ -0,0 +1,24 @@ +from binding import * +from .namespace import llvm +from .Value import Value +from .DerivedTypes import FunctionType +from .ADT.StringRef import StringRef + +llvm.includes.add('llvm/InlineAsm.h') + +InlineAsm = llvm.Class(Value) + +@InlineAsm +class InlineAsm: + AsmDialect = Enum('AD_ATT', 'AD_Intel') + ConstraintPrefix = Enum('''isInput, isOutput, isClobber''') + + get = StaticMethod(ptr(InlineAsm), + ptr(FunctionType), + cast(str, StringRef), # AsmString + cast(str, StringRef), # Constrains + cast(bool, Bool), # hasSideEffects + cast(bool, Bool), # isAlignStack + AsmDialect, # default = AD_ATT + ).require_only(4) + diff --git a/llvmpy/src/Instruction.py b/llvmpy/src/Instruction.py new file mode 100644 index 0000000..beb94f1 --- /dev/null +++ b/llvmpy/src/Instruction.py @@ -0,0 +1,390 @@ +from binding import * +from .namespace import llvm +from .Value import Value, MDNode, User, BasicBlock, Function, ConstantInt + + +Instruction = llvm.Class(User) +AtomicCmpXchgInst = llvm.Class(Instruction) +AtomicRMWInst = llvm.Class(Instruction) +BinaryOperator = llvm.Class(Instruction) +CallInst = llvm.Class(Instruction) +CmpInst = llvm.Class(Instruction) +ExtractElementInst = llvm.Class(Instruction) +FenceInst = llvm.Class(Instruction) +GetElementPtrInst = llvm.Class(Instruction) +InsertElementInst = llvm.Class(Instruction) +InsertValueInst = llvm.Class(Instruction) +LandingPadInst = llvm.Class(Instruction) +PHINode = llvm.Class(Instruction) +SelectInst = llvm.Class(Instruction) +ShuffleVectorInst = llvm.Class(Instruction) +StoreInst = llvm.Class(Instruction) +TerminatorInst = llvm.Class(Instruction) +UnaryInstruction = llvm.Class(Instruction) + +IntrinsicInst = llvm.Class(CallInst) + +FCmpInst = llvm.Class(CmpInst) +ICmpInst = llvm.Class(CmpInst) + +BranchInst = llvm.Class(TerminatorInst) +IndirectBrInst = llvm.Class(TerminatorInst) +InvokeInst = llvm.Class(TerminatorInst) +ResumeInst = llvm.Class(TerminatorInst) +ReturnInst = llvm.Class(TerminatorInst) +SwitchInst = llvm.Class(TerminatorInst) +UnreachableInst = llvm.Class(TerminatorInst) + +AllocaInst = llvm.Class(UnaryInstruction) +CastInst = llvm.Class(UnaryInstruction) +ExtractValueInst = llvm.Class(UnaryInstruction) +LoadInst = llvm.Class(UnaryInstruction) +VAArgInst = llvm.Class(UnaryInstruction) + +DbgInfoIntrinsic = llvm.Class(IntrinsicInst) +MemIntrinsic = llvm.Class(IntrinsicInst) +VACopyInst = llvm.Class(IntrinsicInst) +VAEndInst = llvm.Class(IntrinsicInst) +VAStartInst = llvm.Class(IntrinsicInst) + +BitCastInst = llvm.Class(CastInst) +FPExtInst = llvm.Class(CastInst) +FPToSIInst = llvm.Class(CastInst) +FPToUIInst = llvm.Class(CastInst) +FPTruncInst = llvm.Class(CastInst) + +AtomicOrdering = llvm.Enum('AtomicOrdering', + 'NotAtomic', 'Unordered', 'Monotonic', 'Acquire', + 'Release', 'AcquireRelease', + 'SequentiallyConsistent') + +SynchronizationScope = llvm.Enum('SynchronizationScope', + 'SingleThread', 'CrossThread') + + + +from .ADT.StringRef import StringRef +from .CallingConv import CallingConv +from .Attributes import Attributes +from .Type import Type + + + +@Instruction +class Instruction: + _downcast_ = Value, User + + removeFromParent = Method() + eraseFromParent = Method() + eraseFromParent.disowning = True + + getParent = Method(ptr(BasicBlock)) + getOpcode = Method(cast(Unsigned, int)) + getOpcodeName = Method(cast(ConstCharPtr, str)) + + insertBefore = Method(Void, ptr(Instruction)) + insertAfter = Method(Void, ptr(Instruction)) + moveBefore = Method(Void, ptr(Instruction)) + + isTerminator = Method(cast(Bool, bool)) + isBinaryOp = Method(cast(Bool, bool)) + isShift = Method(cast(Bool, bool)) + isCast = Method(cast(Bool, bool)) + isLogicalShift = Method(cast(Bool, bool)) + isArithmeticShift = Method(cast(Bool, bool)) + hasMetadata = Method(cast(Bool, bool)) + hasMetadataOtherThanDebugLoc = Method(cast(Bool, bool)) + isAssociative = Method(cast(Bool, bool)) + isCommutative = Method(cast(Bool, bool)) + isIdempotent = Method(cast(Bool, bool)) + isNilpotent = Method(cast(Bool, bool)) + mayWriteToMemory = Method(cast(Bool, bool)) + mayReadFromMemory = Method(cast(Bool, bool)) + mayReadOrWriteMemory = Method(cast(Bool, bool)) + mayThrow = Method(cast(Bool, bool)) + mayHaveSideEffects = Method(cast(Bool, bool)) + + hasMetadata = Method(cast(Bool, bool)) + getMetadata = Method(ptr(MDNode), cast(str, StringRef)) + setMetadata = Method(Void, cast(str, StringRef), ptr(MDNode)) + + clone = Method(ptr(Instruction)) + +# LLVM 3.3 +# hasUnsafeAlgebra = Method(cast(Bool, bool)) +# hasNoNans = Method(cast(Bool, bool)) +# hasNoInfs = Method(cast(Bool, bool)) +# hasNoSignedZeros = Method(cast(Bool, bool)) +# hasAllowReciprocal = Method(cast(Bool, bool)) + + +@AtomicCmpXchgInst +class AtomicCmpXchgInst: + _downcast_ = Value, Instruction + +@AtomicRMWInst +class AtomicRMWInst: + _downcast_ = Value, Instruction + BinOp = Enum('Xchg', 'Add', 'Sub', 'And', 'Nand', 'Or', 'Xor', 'Max', 'Min', + 'UMax', 'UMin', 'FIRST_BINOP', 'LAST_BINOP', 'BAD_BINOP') + +@BinaryOperator +class BinaryOperator: + _downcast_ = Value, Instruction + +@CallInst +class CallInst: + _downcast_ = Value, User, Instruction + + getCallingConv = Method(CallingConv.ID) + setCallingConv = Method(Void, CallingConv.ID) + getParamAlignment = Method(cast(Unsigned, int), cast(int, Unsigned)) + addAttribute = Method(Void, cast(int, Unsigned), ref(Attributes)) + removeAttribute = Method(Void, cast(int, Unsigned), ref(Attributes)) + getCalledFunction = Method(ptr(Function)) + getCalledValue = Method(ptr(Value)) + setCalledFunction = Method(Void, ptr(Function)) + isInlineAsm = Method(cast(Bool, bool)) + + CreateMalloc = StaticMethod(ptr(Instruction), + ptr(BasicBlock), # insertAtEnd + ptr(Type), # intptrty + ptr(Type), # allocty + ptr(Value), # allocsz + ptr(Value), # array size = 0 + ptr(Function), # malloc fn = 0 + cast(str, StringRef), # name + ).require_only(4) + + CreateFree = StaticMethod(ptr(Instruction), ptr(Value), ptr(BasicBlock)) + +@CmpInst +class CmpInst: + _downcast_ = Value, Instruction + Predicate = Enum('FCMP_FALSE', 'FCMP_OEQ', 'FCMP_OGT', 'FCMP_OGE', + 'FCMP_OLT', 'FCMP_OLE', 'FCMP_ONE', 'FCMP_ORD', 'FCMP_UNO', + 'FCMP_UEQ', 'FCMP_UGT', 'FCMP_UGE', 'FCMP_ULT', 'FCMP_ULE', + 'FCMP_UNE', 'FCMP_TRUE', 'FIRST_FCMP_PREDICATE', + 'LAST_FCMP_PREDICATE', + 'BAD_FCMP_PREDICATE', + 'ICMP_EQ', 'ICMP_NE', 'ICMP_UGT', 'ICMP_UGE', 'ICMP_ULT', + 'ICMP_ULE', 'ICMP_SGT', 'ICMP_SGE', 'ICMP_SLT', 'ICMP_SLE', + 'FIRST_ICMP_PREDICATE', + 'LAST_ICMP_PREDICATE', + 'BAD_ICMP_PREDICATE',) + + getPredicate = Method(Predicate) + +@ExtractElementInst +class ExtractElementInst: + _downcast_ = Value, Instruction + +@FenceInst +class FenceInst: + _downcast_ = Value, Instruction + +@GetElementPtrInst +class GetElementPtrInst: + _downcast_ = Value, Instruction + +@InsertElementInst +class InsertElementInst: + _downcast_ = Value, Instruction + +@InsertValueInst +class InsertValueInst: + _downcast_ = Value, Instruction + +@LandingPadInst +class LandingPadInst: + _downcast_ = Value, Instruction + +@PHINode +class PHINode: + _downcast_ = Value, Instruction + getNumIncomingValues = Method(cast(Unsigned, int)) + getIncomingValue = Method(ptr(Value), cast(int, Unsigned)) + setIncomingValue = Method(Void, cast(int, Unsigned), ptr(Value)) + getIncomingBlock = Method(ptr(BasicBlock), cast(int, Unsigned)) + setIncomingBlock = Method(Void, cast(int, Unsigned), ptr(BasicBlock)) + addIncoming = Method(Void, ptr(Value), ptr(BasicBlock)) + hasConstantValue = Method(ptr(Value)) + getBasicBlockIndex = Method(cast(Int, int), ptr(BasicBlock)) + +@SelectInst +class SelectInst: + _downcast_ = Value, Instruction + +@ShuffleVectorInst +class ShuffleVectorInst: + _downcast_ = Value, Instruction + +@StoreInst +class StoreInst: + _downcast_ = Value, Instruction + isVolatile = Method(cast(Bool, bool)) + isSimple = Method(cast(Bool, bool)) + isUnordered = Method(cast(Bool, bool)) + isAtomic = Method(cast(Bool, bool)) + + setVolatile = Method(Void, cast(Bool, bool)) + + getAlignment = Method(cast(Unsigned, int)) + setAlignment = Method(Void, cast(int, Unsigned)) + + setAtomic = Method(Void, + AtomicOrdering, + SynchronizationScope).require_only(1) + + classof = StaticMethod(cast(Bool, bool), ptr(Value)) + +@TerminatorInst +class TerminatorInst: + _downcast_ = Value, Instruction + getNumSuccessors = Method(cast(Unsigned, int)) + getSuccessor = Method(ptr(BasicBlock), cast(int, Unsigned)) + setSuccessor = Method(Void, cast(int, Unsigned), ptr(BasicBlock)) + +@UnaryInstruction +class UnaryInstruction: + _downcast_ = Value, Instruction + +#call + +@IntrinsicInst +class IntrinsicInst: + _include_ = 'llvm/IntrinsicInst.h' + _downcast_ = Value, Instruction + +#compare + +@FCmpInst +class FCmpInst: + _downcast_ = Value, Instruction + +@ICmpInst +class ICmpInst: + _downcast_ = Value, Instruction + +# terminator +@BranchInst +class BranchInst: + _downcast_ = Value, Instruction + +@IndirectBrInst +class IndirectBrInst: + _downcast_ = Value, Instruction + +@InvokeInst +class InvokeInst: + _downcast_ = Value, User, Instruction + getCallingConv = Method(CallingConv.ID) + setCallingConv = Method(Void, CallingConv.ID) + getParamAlignment = Method(cast(Unsigned, int), cast(int, Unsigned)) + addAttribute = Method(Void, cast(int, Unsigned), ref(Attributes)) + removeAttribute = Method(Void, cast(int, Unsigned), ref(Attributes)) + getCalledFunction = Method(ptr(Function)) + getCalledValue = Method(ptr(Value)) + setCalledFunction = Method(Void, ptr(Function)) + +@ResumeInst +class ResumeInst: + _downcast_ = Value, Instruction + +@ReturnInst +class ReturnInst: + _downcast_ = Value, Instruction + +@SwitchInst +class SwitchInst: + _downcast_ = Value, Instruction + + getCondition = Method(ptr(Value)) + setCondition = Method(Void, ptr(Value)) + getDefaultDest = Method(ptr(BasicBlock)) + setDefaultDest = Method(Void, ptr(BasicBlock)) + getNumCases = Method(cast(int, Unsigned)) + addCase = Method(Void, ptr(ConstantInt), ptr(BasicBlock)) + + +@UnreachableInst +class UnreachableInst: + _downcast_ = Value, Instruction + +# unary +@AllocaInst +class AllocaInst: + _downcast_ = Value, Instruction + +@CastInst +class CastInst: + _downcast_ = Value, Instruction + +@ExtractValueInst +class ExtractValueInst: + _downcast_ = Value, Instruction + +@LoadInst +class LoadInst: + _downcast_ = Value, Instruction + isVolatile = Method(cast(Bool, bool)) + isSimple = Method(cast(Bool, bool)) + isUnordered = Method(cast(Bool, bool)) + isAtomic = Method(cast(Bool, bool)) + + setVolatile = Method(Void, cast(Bool, bool)) + + getAlignment = Method(cast(Unsigned, int)) + setAlignment = Method(Void, cast(int, Unsigned)) + + setAtomic = Method(Void, + AtomicOrdering, + SynchronizationScope).require_only(1) + + classof = StaticMethod(cast(Bool, bool), ptr(Value)) + +@VAArgInst +class VAArgInst: + _downcast_ = Value, Instruction + +# intrinsic +@DbgInfoIntrinsic +class DbgInfoIntrinsic: + _downcast_ = Value, Instruction + +@MemIntrinsic +class MemIntrinsic: + _downcast_ = Value, Instruction + +@VACopyInst +class VACopyInst: + _downcast_ = Value, Instruction + +@VAEndInst +class VAEndInst: + _downcast_ = Value, Instruction + +@VAStartInst +class VAStartInst: + _downcast_ = Value, Instruction + +@BitCastInst +class BitCastInst: + _downcast_ = Value, Instruction + +@FPExtInst +class FPExtInst: + _downcast_ = Value, Instruction + +@FPToSIInst +class FPToSIInst: + _downcast_ = Value, Instruction + +@FPToUIInst +class FPToUIInst: + _downcast_ = Value, Instruction + +@FPTruncInst +class FPTruncInst: + _downcast_ = Value, Instruction + diff --git a/llvmpy/src/Intrinsics.py b/llvmpy/src/Intrinsics.py new file mode 100644 index 0000000..7e1decd --- /dev/null +++ b/llvmpy/src/Intrinsics.py @@ -0,0 +1,16 @@ +from binding import * +from .namespace import llvm + +from .Module import Module +from .Function import Function + + +Intrinsic = llvm.Namespace('Intrinsic') + +getDeclaration = Intrinsic.CustomFunction('getDeclaration', + 'Intrinsic_getDeclaration', + PyObjectPtr, # Function* + ptr(Module), + cast(int, Unsigned), # intrinsic id + PyObjectPtr, # list of Type + ).require_only(2) diff --git a/llvmpy/src/JITMemoryManager.py b/llvmpy/src/JITMemoryManager.py new file mode 100644 index 0000000..e34e678 --- /dev/null +++ b/llvmpy/src/JITMemoryManager.py @@ -0,0 +1,7 @@ +from binding import * +from .namespace import llvm + +@llvm.Class() +class JITMemoryManager: + pass + diff --git a/llvmpy/src/LLVMContext.py b/llvmpy/src/LLVMContext.py new file mode 100644 index 0000000..4a6b49a --- /dev/null +++ b/llvmpy/src/LLVMContext.py @@ -0,0 +1,8 @@ +from binding import * +from .namespace import llvm + +@llvm.Class() +class LLVMContext: + _include_ = "llvm/LLVMContext.h" + +llvm.Function('getGlobalContext', ref(LLVMContext)) diff --git a/llvmpy/src/Linker.py b/llvmpy/src/Linker.py new file mode 100644 index 0000000..960bd90 --- /dev/null +++ b/llvmpy/src/Linker.py @@ -0,0 +1,58 @@ +from binding import * +from .namespace import llvm +from .ADT.StringRef import StringRef +from .Module import Module +from .LLVMContext import LLVMContext + +llvm.includes.add('llvm/Linker.h') + +Linker = llvm.Class() + +@Linker +class Linker: + ControlFlags = Enum('Verbose, QuietWarnings, QuietErrors') + LinkerMode = Enum('DestroySource, PreserveSource') + + _new_w_empty = Constructor(cast(str, StringRef), + cast(str, StringRef), + ref(LLVMContext), + cast(int, Unsigned)).require_only(3) + + _new_w_existing = Constructor(cast(str, StringRef), + ptr(Module), + cast(int, Unsigned)).require_only(2) + + @CustomPythonStaticMethod + def new(progname, module_or_name, *args): + if isinstance(module_or_name, Module): + return _new_w_existing(progname, module_or_name, *args) + else: + return _new_w_empty(progname, module_or_name, *args) + + delete = Destructor() + + getModule = Method(ptr(Module)) + releaseModule = Method(ptr(Module)) + getLastError = Method(cast(ConstStdString, str)) + + LinkInModule = CustomMethod('Linker_LinkInModule', + PyObjectPtr, # boolean + ptr(Module), + PyObjectPtr, # errmsg + ) + + _LinkModules = CustomStaticMethod('Linker_LinkModules', + PyObjectPtr, # boolean + ptr(Module), + ptr(Module), + LinkerMode, + PyObjectPtr, # errsg + ) + + @CustomPythonStaticMethod + def LinkModules(module, other, mode, errmsg): + failed = Linker._LinkModules(module, other, mode, errmsg) + if not failed and mode != Linker.LinkerMode.PreserveSource: + capsule.release_ownership(other._ptr) + return failed + diff --git a/llvmpy/src/Metadata.py b/llvmpy/src/Metadata.py new file mode 100644 index 0000000..cfeb6ce --- /dev/null +++ b/llvmpy/src/Metadata.py @@ -0,0 +1,54 @@ +from binding import * +from .namespace import llvm +from .Value import Value, MDNode, MDString +from .LLVMContext import LLVMContext +from .ADT.StringRef import StringRef +from .Module import Module +from .Function import Function +from .Support.raw_ostream import raw_ostream +from .Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter + +@MDNode +class MDNode: + _downcast_ = Value + replaceOperandWith = Method(Void, cast(int, Unsigned), ptr(Value)) + getOperand = Method(ptr(Value), cast(int, Unsigned)) + getNumOperands = Method(cast(Unsigned, int)) + isFunctionLocal = Method(cast(Bool, bool)) + getFunction = Method(const(ptr(Function))) + + get = CustomStaticMethod('MDNode_get', + PyObjectPtr, # MDNode* + ref(LLVMContext), + PyObjectPtr, # ArrayRef + ) + +@MDString +class MDString: + _downcast_ = Value + get = StaticMethod(ptr(MDString), ref(LLVMContext), cast(str, StringRef)) + getString = Method(cast(StringRef, str)) + getLength = Method(cast(int, Unsigned)) + +@llvm.Class() +class NamedMDNode: + eraseFromParent = Method() + eraseFromParent.disowning = True + + dropAllReferences = Method() + getParent = Method(ptr(Module)) + getOperand = Method(ptr(MDNode), cast(int, Unsigned)) + getNumOperands = Method(cast(Unsigned, int)) + getName = Method(cast(StringRef, str)) + addOperand = Method(Void, ptr(MDNode)) + print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter)) + print_.realname = "print" + dump = Method() + + + @CustomPythonMethod + def __str__(self): + from llvmpy import extra + os = extra.make_raw_ostream_for_printing() + self.print_(os, None) + return os.str() \ No newline at end of file diff --git a/llvmpy/src/Module.py b/llvmpy/src/Module.py new file mode 100644 index 0000000..46fad5a --- /dev/null +++ b/llvmpy/src/Module.py @@ -0,0 +1,87 @@ +from binding import * +from .namespace import llvm + +Module = llvm.Class() + +from .LLVMContext import LLVMContext +from .ADT.StringRef import StringRef +from .Constant import Constant +from .GlobalVariable import GlobalVariable +from .Function import Function +from .DerivedTypes import FunctionType +from .Support.raw_ostream import raw_ostream +from .Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter +from .Type import Type, StructType +from .Metadata import NamedMDNode + +@Module +class Module: + _include_ = "llvm/Module.h" + # Enumerators + Endianness = Enum('AnyEndianness', 'LittleEndian', 'BigEndian') + PointerSize = Enum('AnyPointerSize', 'Pointer32', 'Pointer64') + + # Constructors & Destructors + new = Constructor(cast(str, StringRef), ref(LLVMContext)) + delete = Destructor() + + # Module Level Accessor + getModuleIdentifier = Method(cast(ConstStdString, str)) + getDataLayout = Method(cast(ConstStdString, str)) + getTargetTriple = Method(cast(ConstStdString, str)) + getEndianness = Method(Endianness) + getPointerSize = Method(PointerSize) + getContext = Method(ref(LLVMContext)) + getModuleInlineAsm = Method(cast(ConstStdString, str)) + + # Module Level Mutators + setModuleIdentifier = Method(Void, cast(str, StringRef)) + setDataLayout = Method(Void, cast(str, StringRef)) + setTargetTriple = Method(Void, cast(str, StringRef)) + setModuleInlineAsm = Method(Void, cast(str, StringRef)) + appendModuleInlineAsm = Method(Void, cast(str, StringRef)) + + # Function Accessors + getOrInsertFunction = Method(ptr(Constant), cast(str, StringRef), + ptr(FunctionType)) + getFunction = Method(ptr(Function), cast(str, StringRef)) + + # Function Iteration + list_functions = CustomMethod('Module_list_functions', PyObjectPtr) + + # GlobalVariabe Accessors + getGlobalVariable = Method(ptr(GlobalVariable), + cast(str, StringRef), + cast(bool, Bool), + ).require_only(1) + getNamedGlobal = Method(ptr(GlobalVariable), cast(str, StringRef)) + getOrInsertGlobal = Method(ptr(Constant), cast(str, StringRef), ptr(Type)) + + # GlobalVariable Iteration + list_globals = CustomMethod('Module_list_globals', PyObjectPtr) + + # Named MetaData Accessors + getNamedMetadata = Method(ptr(NamedMDNode), cast(str, StringRef)) + getOrInsertNamedMetadata = Method(ptr(NamedMDNode), cast(str, StringRef)) + eraseNamedMetadata = Method(Void, ptr(NamedMDNode)) + + # Named MetaData Iteration + list_named_metadata = CustomMethod('Module_list_named_metadata', + PyObjectPtr) + + + # Utilities + dump = Method(Void) + print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter)) + print_.realname = 'print' + + @CustomPythonMethod + def __str__(self): + from llvmpy import extra + os = extra.make_raw_ostream_for_printing() + self.print_(os, None) + return os.str() + + dropAllReferences = Method() + + getTypeByName = Method(ptr(StructType), cast(str, StringRef)) diff --git a/llvmpy/src/Pass.py b/llvmpy/src/Pass.py new file mode 100644 index 0000000..ad03d9a --- /dev/null +++ b/llvmpy/src/Pass.py @@ -0,0 +1,35 @@ +from binding import * +from .namespace import llvm + +Pass = llvm.Class() +ModulePass = llvm.Class(Pass) +FunctionPass = llvm.Class(Pass) +ImmutablePass = llvm.Class(ModulePass) + +from .ADT.StringRef import StringRef +from .Module import Module +from .Value import Function + +@Pass +class Pass: + _include_ = 'llvm/Pass.h' + + delete = Destructor() + getPassName = Method(cast(StringRef, str)) + dump = Method() + +@ModulePass +class ModulePass: + runOnModule = Method(cast(Bool, bool), ref(Module)) + + +@FunctionPass +class FunctionPass: + doInitialization = Method(cast(Bool, bool), ref(Module)) + doFinalization = Method(cast(Bool, bool), ref(Module)) + + +@ImmutablePass +class ImmutablePass: + pass + diff --git a/llvmpy/src/PassManager.py b/llvmpy/src/PassManager.py new file mode 100644 index 0000000..760f080 --- /dev/null +++ b/llvmpy/src/PassManager.py @@ -0,0 +1,36 @@ +from binding import * +from .namespace import llvm + +PassManagerBase = llvm.Class() +PassManager = llvm.Class(PassManagerBase) +FunctionPassManager = llvm.Class(PassManagerBase) + +from .Pass import Pass +from .Module import Module +from .Value import Function + + +@PassManagerBase +class PassManagerBase: + _include_ = 'llvm/PassManager.h' + + delete = Destructor() + + add = Method(Void, ownedptr(Pass)) + +@PassManager +class PassManager: + new = Constructor() + + run = Method(cast(Bool, bool), ref(Module)) + + +@FunctionPassManager +class FunctionPassManager: + new = Constructor(ptr(Module)) + + run = Method(cast(Bool, bool), ref(Function)) + + doInitialization = Method(cast(Bool, bool)) + doFinalization = Method(cast(Bool, bool)) + diff --git a/llvmpy/src/PassRegistry.py b/llvmpy/src/PassRegistry.py new file mode 100644 index 0000000..ede026c --- /dev/null +++ b/llvmpy/src/PassRegistry.py @@ -0,0 +1,21 @@ +from binding import * +from .namespace import llvm +from src.ADT.StringRef import StringRef + +PassRegistry = llvm.Class() + +from src.PassSupport import PassInfo + +@PassRegistry +class PassRegistry: + _include_ = 'llvm/PassRegistry.h' + + delete = Destructor() + + getPassRegistry = StaticMethod(ownedptr(PassRegistry)) + + getPassInfo = Method(const(ptr(PassInfo)), cast(str, StringRef)) + + # This is a custom method that wraps enumerateWith + # Returns list of tuples of (pass-arg, pass-name) + enumerate = CustomMethod('PassRegistry_enumerate', PyObjectPtr) \ No newline at end of file diff --git a/llvmpy/src/PassSupport.py b/llvmpy/src/PassSupport.py new file mode 100644 index 0000000..d239a6d --- /dev/null +++ b/llvmpy/src/PassSupport.py @@ -0,0 +1,24 @@ +from binding import * +from .namespace import llvm + +PassInfo = llvm.Class() + +from src.Pass import Pass +from src.PassRegistry import PassRegistry + +@PassInfo +class PassInfo: + _include_ = 'llvm/PassSupport.h' + + createPass = Method(ptr(Pass)) + +llvm.Function('initializeCore', Void, ref(PassRegistry)) +llvm.Function('initializeScalarOpts', Void, ref(PassRegistry)) +llvm.Function('initializeVectorization', Void, ref(PassRegistry)) +llvm.Function('initializeIPO', Void, ref(PassRegistry)) +llvm.Function('initializeAnalysis', Void, ref(PassRegistry)) +llvm.Function('initializeIPA', Void, ref(PassRegistry)) +llvm.Function('initializeTransformUtils', Void, ref(PassRegistry)) +llvm.Function('initializeInstCombine', Void, ref(PassRegistry)) +llvm.Function('initializeInstrumentation', Void, ref(PassRegistry)) +llvm.Function('initializeTarget', Void, ref(PassRegistry)) diff --git a/llvmpy/src/Support/CodeGen.py b/llvmpy/src/Support/CodeGen.py new file mode 100644 index 0000000..3bc6f9d --- /dev/null +++ b/llvmpy/src/Support/CodeGen.py @@ -0,0 +1,20 @@ +from binding import * +from ..namespace import llvm + + +Reloc = llvm.Namespace('Reloc') +Reloc.Enum('Model', + 'Default', 'Static', 'PIC_', 'DynamicNoPIC') + +CodeModel = llvm.Namespace('CodeModel') +CodeModel.Enum('Model', + 'Default', 'JITDefault', 'Small', 'Kernel', 'Medium', 'Large') + +TLSModel = llvm.Namespace('TLSModel') +TLSModel.Enum('Model', + 'GeneralDynamic', 'LocalDynamic', 'InitialExec', 'LocalExec') + +CodeGenOpt = llvm.Namespace('CodeGenOpt') +CodeGenOpt.Enum('Level', + 'None', 'Less', 'Default', 'Aggressive') + diff --git a/llvmpy/src/Support/CommandLine.py b/llvmpy/src/Support/CommandLine.py new file mode 100644 index 0000000..2a114f7 --- /dev/null +++ b/llvmpy/src/Support/CommandLine.py @@ -0,0 +1,12 @@ +from binding import * +from src.namespace import cl + +cl.includes.add('llvm/Support/CommandLine.h') + +ParseEnvironmentOptions = cl.Function('ParseEnvironmentOptions', + Void, + cast(str, ConstCharPtr), # progName + cast(str, ConstCharPtr), # envvar + cast(str, ConstCharPtr), # overiew = 0 + ).require_only(2) + diff --git a/llvmpy/src/Support/DynamicLibrary.py b/llvmpy/src/Support/DynamicLibrary.py new file mode 100644 index 0000000..7dce97a --- /dev/null +++ b/llvmpy/src/Support/DynamicLibrary.py @@ -0,0 +1,28 @@ +from binding import * +from ..namespace import sys +from ..ADT.StringRef import StringRef + +DynamicLibrary = sys.Class() + + +@DynamicLibrary +class DynamicLibrary: + _include_ = 'llvm/Support/DynamicLibrary.h' + isValid = Method(cast(Bool, bool)) + getAddressOfSymbol = Method(cast(VoidPtr, int), cast(str, ConstCharPtr)) + + LoadPermanentLibrary = CustomStaticMethod( + 'DynamicLibrary_LoadLibraryPermanently', + PyObjectPtr, # bool --- failed? + cast(str, ConstCharPtr), # filename + PyObjectPtr, # std::string * errmsg = 0 + ).require_only(1) + + SearchForAddressOfSymbol = StaticMethod(cast(VoidPtr, int), # address + cast(str, ConstCharPtr), # symName + ) + + AddSymbol = StaticMethod(Void, + cast(str, StringRef), # symbolName + cast(int, VoidPtr), # address + ) diff --git a/llvmpy/src/Support/FormattedStream.py b/llvmpy/src/Support/FormattedStream.py new file mode 100644 index 0000000..3e9159b --- /dev/null +++ b/llvmpy/src/Support/FormattedStream.py @@ -0,0 +1,15 @@ +from binding import * +from ..namespace import llvm +from .raw_ostream import raw_ostream + +@llvm.Class(raw_ostream) +class formatted_raw_ostream: + _include_ = 'llvm/Support/FormattedStream.h' + _new = Constructor(ref(raw_ostream), cast(bool, Bool)) + + @CustomPythonStaticMethod + def new(stream, destroy=False): + inst = formatted_raw_ostream._new(stream, destroy) + inst.__underlying_stream = stream # to prevent it being freed first + return inst + diff --git a/llvmpy/src/Support/Host.py b/llvmpy/src/Support/Host.py new file mode 100644 index 0000000..8163ebe --- /dev/null +++ b/llvmpy/src/Support/Host.py @@ -0,0 +1,25 @@ +from binding import * +from src.namespace import sys + +isLittleEndianHost = sys.Function('isLittleEndianHost', + cast(Bool, bool)) + +isBigEndianHost = sys.Function('isBigEndianHost', + cast(Bool, bool)) + +getDefaultTargetTriple = sys.Function('getDefaultTargetTriple', + cast(ConstStdString, str)) + +# llvm 3.3 +#getProcessTriple = sys.Function('getProcessTriple', +# cast(ConstStdString, str)) + +getHostCPUName = sys.Function('getHostCPUName', + cast(ConstStdString, str)) + +getHostCPUFeatures = sys.CustomFunction('getHostCPUFeatures', + 'llvm_sys_getHostCPUFeatures', + PyObjectPtr, # bool: success? + PyObjectPtr, # dict: store feature map + ) + diff --git a/llvmpy/src/Support/SourceMgr.py b/llvmpy/src/Support/SourceMgr.py new file mode 100644 index 0000000..7dc75be --- /dev/null +++ b/llvmpy/src/Support/SourceMgr.py @@ -0,0 +1,10 @@ +from binding import * +from ..namespace import llvm + +llvm.includes.add('llvm/Support/SourceMgr.h') + +@llvm.Class() +class SMDiagnostic: + new = Constructor() + delete = Destructor() + diff --git a/llvmpy/src/Support/TargetRegistry.py b/llvmpy/src/Support/TargetRegistry.py new file mode 100644 index 0000000..640364b --- /dev/null +++ b/llvmpy/src/Support/TargetRegistry.py @@ -0,0 +1,68 @@ +from binding import * +from src.namespace import llvm + +llvm.includes.add('llvm/Support/TargetRegistry.h') + +Target = llvm.Class() +TargetRegistry = llvm.Class() + +from src.ADT.Triple import Triple +from src.ADT.StringRef import StringRef +from src.Target.TargetMachine import TargetMachine +from src.Target.TargetOptions import TargetOptions +from src.Support.CodeGen import Reloc, CodeModel, CodeGenOpt + +@Target +class Target: + getNext = Method(const(ptr(Target))) + + getName = Method(cast(StringRef, str)) + getShortDescription = Method(cast(StringRef, str)) + + def _has(): + return Method(cast(Bool, bool)) + + hasJIT = _has() + hasTargetMachine = _has() + hasMCAsmBackend = _has() + hasMCAsmParser = _has() + hasAsmPrinter = _has() + hasMCDisassembler = _has() + hasMCInstPrinter = _has() + hasMCCodeEmitter = _has() + hasMCObjectStreamer = _has() + hasAsmStreamer = _has() + + createTargetMachine = Method(ptr(TargetMachine), + cast(str, StringRef), # triple + cast(str, StringRef), # cpu + cast(str, StringRef), # features + ref(TargetOptions), + Reloc.Model, # = Reloc::Default + CodeModel.Model, # = CodeModel.Default + CodeGenOpt.Level, # = CodeGenOpt.Default + ).require_only(4) + + +@TargetRegistry +class TargetRegistry: + printRegisteredTargetsForVersion = StaticMethod() + + lookupTarget = CustomStaticMethod('TargetRegistry_lookupTarget', + PyObjectPtr, # const Target* + cast(str, ConstCharPtr), # triple + PyObjectPtr, # std::string &Error + ) + + lookupTarget |= CustomStaticMethod('TargetRegistry_lookupTarget', + PyObjectPtr, # const Target* + cast(str, ConstCharPtr), # arch + ref(Triple), # triple + PyObjectPtr, # std::string &Error + ) + + getClosestTargetForJIT = CustomStaticMethod( + 'TargetRegistry_getClosestTargetForJIT', + PyObjectPtr, # const Target* + PyObjectPtr, # std::string &Error + ) diff --git a/llvmpy/src/Support/TargetSelect.py b/llvmpy/src/Support/TargetSelect.py new file mode 100644 index 0000000..ca97c24 --- /dev/null +++ b/llvmpy/src/Support/TargetSelect.py @@ -0,0 +1,28 @@ +from binding import * +from ..namespace import llvm, default + +llvm.includes.add('llvm/Support/TargetSelect.h') + +InitializeNativeTarget = llvm.Function('InitializeNativeTarget') +InitializeNativeTargetAsmPrinter = llvm.Function( + 'InitializeNativeTargetAsmPrinter', cast(Bool, bool)) +InitializeNativeTargetAsmParser = llvm.Function( + 'InitializeNativeTargetAsmParser', cast(Bool, bool)) +InitializeNativeTargetDisassembler = llvm.Function( + 'InitializeNativeTargetDisassembler', cast(Bool, bool)) + + +#InitializeAllTargets = llvm.Function('InitializeAllTargets') +#InitializeAllTargetInfos = llvm.Function('InitializeAllTargetInfos') +#InitializeAllTargetMCs = llvm.Function('InitializeAllTargetMCs') +#InitializeAllAsmPrinters = llvm.Function('InitializeAllAsmPrinters') + +#LLVMInitializePTXTarget = default.Function('LLVMInitializePTXTarget') +#LLVMInitializePTXTargetInfo = default.Function('LLVMInitializePTXTargetInfo') +#LLVMInitializePTXTargetMC = default.Function('LLVMInitializePTXTargetMC') +#LLVMInitializePTXAsmPrinter = default.Function('LLVMInitializePTXAsmPrinter') + +LLVMInitializeNVPTXTarget = default.Function('LLVMInitializeNVPTXTarget') +LLVMInitializeNVPTXTargetInfo = default.Function('LLVMInitializeNVPTXTargetInfo') +LLVMInitializeNVPTXTargetMC = default.Function('LLVMInitializeNVPTXTargetMC') +LLVMInitializeNVPTXAsmPrinter = default.Function('LLVMInitializeNVPTXAsmPrinter') diff --git a/llvmpy/src/Support/__init__.py b/llvmpy/src/Support/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/Support/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/Support/raw_ostream.py b/llvmpy/src/Support/raw_ostream.py new file mode 100644 index 0000000..dcce73f --- /dev/null +++ b/llvmpy/src/Support/raw_ostream.py @@ -0,0 +1,18 @@ +from binding import * +from ..namespace import llvm +from ..LLVMContext import LLVMContext +from ..ADT.StringRef import StringRef + +@llvm.Class() +class raw_ostream: + _include_ = "llvm/Support/raw_ostream.h" + delete = Destructor() + flush = Method() + +@llvm.Class(raw_ostream) +class raw_svector_ostream: + _include_ = "llvm/Support/raw_os_ostream.h" + _base_ = raw_ostream + + str = Method(cast(str, StringRef)) + diff --git a/llvmpy/src/Target/TargetLibraryInfo.py b/llvmpy/src/Target/TargetLibraryInfo.py new file mode 100644 index 0000000..9c47814 --- /dev/null +++ b/llvmpy/src/Target/TargetLibraryInfo.py @@ -0,0 +1,78 @@ +from binding import * +from ..namespace import llvm + +from src.Pass import ImmutablePass + +TargetLibraryInfo = llvm.Class(ImmutablePass) + +LibFunc = llvm.Namespace('LibFunc') +LibFunc.Enum('Func', ''' + ZdaPv, ZdlPv, Znaj, ZnajRKSt9nothrow_t, + Znam, ZnamRKSt9nothrow_t, Znwj, ZnwjRKSt9nothrow_t, + Znwm, ZnwmRKSt9nothrow_t, cxa_atexit, cxa_guard_abort, + cxa_guard_acquire, cxa_guard_release, memcpy_chk, + acos, acosf, acosh, acoshf, + acoshl, acosl, asin, asinf, + asinh, asinhf, asinhl, asinl, + atan, atan2, atan2f, atan2l, + atanf, atanh, atanhf, atanhl, + atanl, calloc, cbrt, cbrtf, + cbrtl, ceil, ceilf, ceill, + copysign, copysignf, copysignl, cos, + cosf, cosh, coshf, coshl, + cosl, exp, exp10, exp10f, + exp10l, exp2, exp2f, exp2l, + expf, expl, expm1, expm1f, + expm1l, fabs, fabsf, fabsl, + fiprintf, + floor, floorf, floorl, fmod, + fmodf, fmodl, fputc, + fputs, free, fwrite, iprintf, + log, log10, log10f, log10l, + log1p, log1pf, log1pl, log2, + log2f, log2l, logb, logbf, + logbl, logf, logl, malloc, + memchr, memcmp, memcpy, memmove, + memset, memset_pattern16, nearbyint, nearbyintf, + nearbyintl, posix_memalign, pow, powf, + powl, putchar, puts, + realloc, reallocf, rint, rintf, + rintl, round, roundf, roundl, + sin, sinf, sinh, sinhf, + sinhl, sinl, siprintf, + sqrt, sqrtf, sqrtl, stpcpy, + strcat, strchr, strcmp, strcpy, + strcspn, strdup, strlen, strncat, + strncmp, strncpy, strndup, strnlen, + strpbrk, strrchr, strspn, strstr, + strtod, strtof, strtol, strtold, + strtoll, strtoul, strtoull, tan, + tanf, tanh, tanhf, tanhl, + tanl, trunc, truncf, + truncl, valloc, NumLibFuncs''') + # not in llvm-3.2 abs, ffs, ffsl, ffsll, fprintf, isascii, + # isdigit, labs, llabs, printf, sprintf, toascii + +from src.ADT.Triple import Triple +from src.ADT.StringRef import StringRef + + +@TargetLibraryInfo +class TargetLibraryInfo: + _include_ = 'llvm/Target/TargetLibraryInfo.h' + + new = Constructor() + new |= Constructor(ref(Triple)) + + delete = Destructor() + + has = Method(cast(bool, Bool), LibFunc.Func) + hasOptimizedCodeGen = Method(cast(bool, Bool), LibFunc.Func) + + getName = Method(cast(str, StringRef), LibFunc.Func) + + setUnavailable = Method(Void, LibFunc.Func) + setAvailable = Method(Void, LibFunc.Func) + setAvailableWithName = Method(Void, LibFunc.Func, cast(str, StringRef)) + disableAllFunctions = Method() + diff --git a/llvmpy/src/Target/TargetMachine.py b/llvmpy/src/Target/TargetMachine.py new file mode 100644 index 0000000..1bd6843 --- /dev/null +++ b/llvmpy/src/Target/TargetMachine.py @@ -0,0 +1,54 @@ +from binding import * +from src.namespace import llvm + +TargetMachine = llvm.Class() + +from src.Support.TargetRegistry import Target +from src.ADT.StringRef import StringRef +from src.Support.CodeGen import CodeModel, TLSModel, CodeGenOpt, Reloc +from src.GlobalValue import GlobalValue +from src.DataLayout import DataLayout +from src.TargetTransformInfo import (ScalarTargetTransformInfo, + VectorTargetTransformInfo) +from src.PassManager import PassManagerBase +from src.Support.FormattedStream import formatted_raw_ostream + +@TargetMachine +class TargetMachine: + _include_ = 'llvm/Target/TargetMachine.h' + + CodeGenFileType = Enum(''' + CGFT_AssemblyFile + CGFT_ObjectFile + CGFT_Null''') + + delete = Destructor() + + getTarget = Method(const(ref(Target))) + + getTargetTriple = Method(cast(StringRef, str)) + getTargetCPU = Method(cast(StringRef, str)) + getTargetFeatureString = Method(cast(StringRef, str)) + + getRelocationModel = Method(Reloc.Model) + getCodeModel = Method(CodeModel.Model) + getTLSModel = Method(TLSModel.Model, ptr(GlobalValue)) + getOptLevel = Method(CodeGenOpt.Level) + + hasMCUseDwarfDirectory = Method(cast(Bool, bool)) + setMCUseDwarfDirectory = Method(Void, cast(bool, Bool)) + + getDataLayout = Method(const(ownedptr(DataLayout))) + getScalarTargetTransformInfo = Method(const( + ownedptr(ScalarTargetTransformInfo))) + getVectorTargetTransformInfo = Method(const( + ownedptr(VectorTargetTransformInfo))) + + addPassesToEmitFile = Method(cast(bool, Bool), + ref(PassManagerBase), + ref(formatted_raw_ostream), + CodeGenFileType, + cast(bool, Bool) + ).require_only(3) + + diff --git a/llvmpy/src/Target/TargetOptions.py b/llvmpy/src/Target/TargetOptions.py new file mode 100644 index 0000000..0e28677 --- /dev/null +++ b/llvmpy/src/Target/TargetOptions.py @@ -0,0 +1,12 @@ +from binding import * +from src.namespace import llvm + +llvm.includes.add('llvm/Target/TargetOptions.h') + +TargetOptions = llvm.Class() + +@TargetOptions +class TargetOptions: + new = Constructor() + delete = Destructor() + diff --git a/llvmpy/src/Target/__init__.py b/llvmpy/src/Target/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/Target/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/TargetTransformInfo.py b/llvmpy/src/TargetTransformInfo.py new file mode 100644 index 0000000..1208050 --- /dev/null +++ b/llvmpy/src/TargetTransformInfo.py @@ -0,0 +1,24 @@ +from binding import * +from src.namespace import llvm +from src.Pass import ImmutablePass + +llvm.includes.add('llvm/TargetTransformInfo.h') + +TargetTransformInfo = llvm.Class(ImmutablePass) +ScalarTargetTransformInfo = llvm.Class() +VectorTargetTransformInfo = llvm.Class() + + +@ScalarTargetTransformInfo +class ScalarTargetTransformInfo: + delete = Destructor() + +@VectorTargetTransformInfo +class VectorTargetTransformInfo: + delete = Destructor() + +@TargetTransformInfo +class TargetTransformInfo: + new = Constructor(ptr(ScalarTargetTransformInfo), + ptr(VectorTargetTransformInfo)) + diff --git a/llvmpy/src/Transforms/IPO.py b/llvmpy/src/Transforms/IPO.py new file mode 100644 index 0000000..48b34f9 --- /dev/null +++ b/llvmpy/src/Transforms/IPO.py @@ -0,0 +1,9 @@ +from binding import * +from ..namespace import llvm +from ..Pass import Pass + +llvm.includes.add('llvm/Transforms/IPO.h') + +createFunctionInliningPass = llvm.Function('createFunctionInliningPass', + ptr(Pass), + cast(int, Unsigned)).require_only(0) diff --git a/llvmpy/src/Transforms/PassManagerBuilder.py b/llvmpy/src/Transforms/PassManagerBuilder.py new file mode 100644 index 0000000..c940062 --- /dev/null +++ b/llvmpy/src/Transforms/PassManagerBuilder.py @@ -0,0 +1,46 @@ +from binding import * +from ..namespace import llvm + +PassManagerBuilder = llvm.Class() + +from src.PassManager import PassManagerBase, FunctionPassManager +from src.Target.TargetLibraryInfo import TargetLibraryInfo +from src.Pass import Pass + +@PassManagerBuilder +class PassManagerBuilder: + _include_ = 'llvm/Transforms/IPO/PassManagerBuilder.h' + + new = Constructor() + delete = Destructor() + + populateFunctionPassManager = Method(Void, ref(FunctionPassManager)) + populateModulePassManager = Method(Void, ref(PassManagerBase)) + populateLTOPassManager = Method(Void, + ref(PassManagerBase), + cast(bool, Bool), + cast(bool, Bool), + cast(bool, Bool)).require_only(3) + + def _attr_int(): + return Attr(getter=cast(Unsigned, int), + setter=cast(int, Unsigned)) + + OptLevel = _attr_int() + SizeLevel = _attr_int() + + def _attr_bool(): + return Attr(getter=cast(Bool, bool), + setter=cast(bool, Bool)) + + DisableSimplifyLibCalls = _attr_bool() + DisableUnitAtATime = _attr_bool() + DisableUnrollLoops = _attr_bool() + Vectorize = _attr_bool() + LoopVectorize = _attr_bool() + + LibraryInfo = Attr(getter=ownedptr(TargetLibraryInfo), + setter=ownedptr(TargetLibraryInfo)) + + Inliner = Attr(getter=ownedptr(Pass), + setter=ownedptr(Pass)) diff --git a/llvmpy/src/Transforms/Utils/Cloning.py b/llvmpy/src/Transforms/Utils/Cloning.py new file mode 100644 index 0000000..c6eaf0a --- /dev/null +++ b/llvmpy/src/Transforms/Utils/Cloning.py @@ -0,0 +1,25 @@ +from binding import * +from src.namespace import llvm + +llvm.includes.add('llvm/Transforms/Utils/Cloning.h') + +InlineFunctionInfo = llvm.Class() + + +from src.Module import Module +from src.Instruction import CallInst + +@InlineFunctionInfo +class InlineFunctionInfo: + new = Constructor() + delete = Destructor() + + +CloneModule = llvm.Function('CloneModule', ptr(Module), ptr(Module)) + +InlineFunction = llvm.Function('InlineFunction', + cast(Bool, bool), # bool --- failed + ptr(CallInst), + ref(InlineFunctionInfo), + cast(bool, Bool), # insert lifetime = true + ).require_only(2) diff --git a/llvmpy/src/Transforms/Utils/__init__.py b/llvmpy/src/Transforms/Utils/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/Transforms/Utils/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/Transforms/__init__.py b/llvmpy/src/Transforms/__init__.py new file mode 100644 index 0000000..944426e --- /dev/null +++ b/llvmpy/src/Transforms/__init__.py @@ -0,0 +1,2 @@ +from src import _init +_init(__name__, __file__) diff --git a/llvmpy/src/Type.py b/llvmpy/src/Type.py new file mode 100644 index 0000000..ea1f0e5 --- /dev/null +++ b/llvmpy/src/Type.py @@ -0,0 +1,219 @@ +from binding import * +from .namespace import llvm +from .LLVMContext import LLVMContext +from .Support.raw_ostream import raw_ostream +from .ADT.StringRef import StringRef + +Type = llvm.Class() +IntegerType = llvm.Class(Type) +CompositeType = llvm.Class(Type) +StructType = llvm.Class(CompositeType) +SequentialType = llvm.Class(CompositeType) +ArrayType = llvm.Class(SequentialType) +PointerType = llvm.Class(SequentialType) +VectorType = llvm.Class(SequentialType) + +@Type +class Type: + _include_ = 'llvm/Type.h' + + TypeID = Enum(''' + VoidTyID, HalfTyID, FloatTyID, DoubleTyID, + X86_FP80TyID, FP128TyID, PPC_FP128TyID, LabelTyID, + MetadataTyID, X86_MMXTyID, IntegerTyID, FunctionTyID, + StructTyID, ArrayTyID, PointerTyID, VectorTyID, + NumTypeIDs, LastPrimitiveTyID, FirstDerivedTyID + ''') + + getContext = Method(ref(LLVMContext)) + dump = Method() + print_ = Method(Void, ref(raw_ostream)) + print_.realname = 'print' + + getTypeID = Method(TypeID) + + def type_checker(): + return Method(cast(Bool, bool)) + + isVoidTy = type_checker() + isHalfTy = type_checker() + isFloatTy = type_checker() + isDoubleTy = type_checker() + isX86_FP80Ty = type_checker() + isFP128Ty = type_checker() + isPPC_FP128Ty = type_checker() + isFloatingPointTy = type_checker() + isX86_MMXTy = type_checker() + isFPOrFPVectorTy = type_checker() + isLabelTy = type_checker() + isMetadataTy = type_checker() + isIntOrIntVectorTy = type_checker() + isFunctionTy = type_checker() + isStructTy = type_checker() + isArrayTy = type_checker() + isPointerTy = type_checker() + isPtrOrPtrVectorTy = type_checker() + isVectorTy = type_checker() + isEmptyTy = type_checker() + isPrimitiveType = type_checker() + isDerivedType = type_checker() + isFirstClassType = type_checker() + isSingleValueType = type_checker() + isAggregateType = type_checker() + isSized = type_checker() + + isIntegerTy = Method(cast(Bool, bool)) + isIntegerTy |= Method(cast(Bool, bool), cast(int, Unsigned)) + + getIntegerBitWidth = Method(cast(Unsigned, int)) + getFunctionParamType = Method(ptr(Type), cast(int, Unsigned)) + getFunctionNumParams = Method(cast(int, Unsigned)) + + isFunctionVarArg = type_checker() + + getStructName = Method(cast(StringRef, str)) + getStructNumElements = Method(cast(Unsigned, int)) + getStructElementType = Method(ptr(Type), cast(int, Unsigned)) + getSequentialElementType = Method(ptr(Type)) + + # Factories + + + def type_factory(): + return StaticMethod(ptr(Type), ref(LLVMContext)) + + getVoidTy = type_factory() + getLabelTy = type_factory() + getHalfTy = type_factory() + getFloatTy = type_factory() + getDoubleTy = type_factory() + getMetadataTy = type_factory() + getX86_FP80Ty = type_factory() + getFP128Ty = type_factory() + getPPC_FP128Ty = type_factory() + getX86_MMXTy = type_factory() + + getIntNTy = StaticMethod(ptr(IntegerType), + ref(LLVMContext), cast(Unsigned, int)) + + def integer_factory(): + return StaticMethod(ptr(IntegerType), ref(LLVMContext)) + + getInt1Ty = integer_factory() + getInt8Ty = integer_factory() + getInt16Ty = integer_factory() + getInt32Ty = integer_factory() + getInt64Ty = integer_factory() + + def pointer_factory(): + return StaticMethod(ptr(PointerType), ref(LLVMContext)) + + getHalfPtrTy = pointer_factory() + getFloatPtrTy = pointer_factory() + getDoublePtrTy = pointer_factory() + getX86_FP80PtrTy = pointer_factory() + getFP128PtrTy = pointer_factory() + getPPC_FP128PtrTy = pointer_factory() + getX86_MMXPtrTy = pointer_factory() + getInt1PtrTy = pointer_factory() + getInt8PtrTy = pointer_factory() + getInt16PtrTy = pointer_factory() + getInt32PtrTy = pointer_factory() + getInt64PtrTy = pointer_factory() + getIntNPtrTy = StaticMethod(ptr(PointerType), + ref(LLVMContext), cast(int, Unsigned)) + + @CustomPythonMethod + def __str__(self): + from llvmpy import extra + os = extra.make_raw_ostream_for_printing() + self.print_(os) + return os.str() + + getContainedType = Method(ptr(Type), cast(int, Unsigned)) + getNumContainedTypes = Method(cast(int, Unsigned)) + + getArrayNumElements = Method(cast(Uint64, int)) + getArrayElementType = Method(ptr(Type)) + + getVectorNumElements = Method(cast(Unsigned, int)) + getVectorElementType = Method(ptr(Type)) + + getPointerElementType = Method(ptr(Type)) + getPointerAddressSpace = Method(cast(Unsigned, int)) + getPointerTo = Method(ptr(PointerType), cast(int, Unsigned)) + + +@IntegerType +class IntegerType: + _downcast_ = Type + + +@CompositeType +class CompositeType: + _downcast_ = Type + +@SequentialType +class SequentialType: + _downcast_ = Type + +@ArrayType +class ArrayType: + _downcast_ = Type + getNumElements = Method(cast(Uint64, int)) + get = StaticMethod(ptr(ArrayType), ptr(Type), cast(int, Uint64)) + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) + +@PointerType +class PointerType: + _downcast_ = Type + getAddressSpace = Method(cast(Unsigned, int)) + get = StaticMethod(ptr(PointerType), ptr(Type), cast(int, Unsigned)) + getUnqual = StaticMethod(ptr(PointerType), ptr(Type)) + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) + +@VectorType +class VectorType: + _downcast_ = Type + getNumElements = Method(cast(Unsigned, int)) + getBitWidth = Method(cast(Unsigned, int)) + get = StaticMethod(ptr(VectorType), ptr(Type), cast(int, Unsigned)) + getInteger = StaticMethod(ptr(VectorType), ptr(VectorType)) + getExtendedElementVectorType = StaticMethod(ptr(VectorType), + ptr(VectorType)) + getTruncatedElementVectorType = StaticMethod(ptr(VectorType), + ptr(VectorType)) + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) + +@StructType +class StructType: + _downcast_ = Type + isPacked = Method(cast(Bool, bool)) + isLiteral = Method(cast(Bool, bool)) + isOpaque = Method(cast(Bool, bool)) + hasName = Method(cast(Bool, bool)) + getName = Method(cast(StringRef, str)) + setName = Method(Void, cast(str, StringRef)) + setBody = CustomMethod('StructType_setBody', + PyObjectPtr, # None + PyObjectPtr, # ArrayRef + cast(bool, Bool), + ).require_only(1) + getNumElements = Method(cast(Unsigned, int)) + getElementType = Method(ptr(Type), cast(int, Unsigned)) + + create = StaticMethod(ptr(StructType), + ref(LLVMContext), + cast(str, StringRef), + ).require_only(1) + + get = CustomStaticMethod('StructType_get', + PyObjectPtr, # StructType* + ref(LLVMContext), + PyObjectPtr, # ArrayRef elements + cast(bool, Bool), # is packed + ).require_only(2) + + + isValidElementType = StaticMethod(cast(Bool, bool), ptr(Type)) + diff --git a/llvmpy/src/User.py b/llvmpy/src/User.py new file mode 100644 index 0000000..1d3cc1f --- /dev/null +++ b/llvmpy/src/User.py @@ -0,0 +1,11 @@ +from binding import * +from .namespace import llvm +from .Value import Value, User + +@User +class User: + _downcast_ = Value + getOperand = Method(ptr(Value), cast(int, Unsigned)) + setOperand = Method(Void, cast(int, Unsigned), ptr(Value)) + getNumOperands = Method(cast(Unsigned, int)) + diff --git a/llvmpy/src/Value.py b/llvmpy/src/Value.py new file mode 100644 index 0000000..669ed80 --- /dev/null +++ b/llvmpy/src/Value.py @@ -0,0 +1,73 @@ +from binding import * +from .namespace import llvm + +# forward declarations +Value = llvm.Class() +Argument = llvm.Class(Value) +MDNode = llvm.Class(Value) +MDString = llvm.Class(Value) +User = llvm.Class(Value) +BasicBlock = llvm.Class(Value) +Constant = llvm.Class(User) +GlobalValue = llvm.Class(Constant) +Function = llvm.Class(GlobalValue) +UndefValue = llvm.Class(Constant) +ConstantInt = llvm.Class(Constant) +ConstantFP = llvm.Class(Constant) +ConstantArray = llvm.Class(Constant) +ConstantStruct = llvm.Class(Constant) +ConstantVector = llvm.Class(Constant) +ConstantDataSequential = llvm.Class(Constant) +ConstantDataArray = llvm.Class(ConstantDataSequential) +ConstantExpr = llvm.Class(Constant) + +from .Support.raw_ostream import raw_ostream +from .Assembly.AssemblyAnnotationWriter import AssemblyAnnotationWriter +from .Type import Type +from .LLVMContext import LLVMContext +from .ADT.StringRef import StringRef + + +@Value +class Value: + + ValueTy = Enum(''' + ArgumentVal, BasicBlockVal, FunctionVal, GlobalAliasVal, + GlobalVariableVal, UndefValueVal, BlockAddressVal, ConstantExprVal, + ConstantAggregateZeroVal, ConstantDataArrayVal, ConstantDataVectorVal, + ConstantIntVal, ConstantFPVal, ConstantArrayVal, ConstantStructVal, + ConstantVectorVal, ConstantPointerNullVal, MDNodeVal, MDStringVal, + InlineAsmVal, PseudoSourceValueVal, FixedStackPseudoSourceValueVal, + InstructionVal, ConstantFirstVal, ConstantLastVal + ''') + + dump = Method() + + print_ = Method(Void, ref(raw_ostream), ptr(AssemblyAnnotationWriter)) + print_.realname = 'print' + + getType = Method(ptr(Type)) + getContext = Method(ref(LLVMContext)) + + hasName = Method(cast(Bool, bool)) + # skip getValueName, setValueName + getName = Method(cast(StringRef, str)) + setName = Method(Void, cast(str, StringRef)) + + replaceAllUsesWith = Method(Void, ptr(Value)) + + list_use = CustomMethod('Value_use_iterator_to_list', PyObjectPtr) + + hasOneUse = Method(cast(Bool, bool)) + hasNUses = Method(cast(Bool, bool), cast(int, Unsigned)) + isUsedInBasicBlock = Method(cast(Bool, bool), BasicBlock) + getNumUses = Method(cast(Unsigned, int)) + + @CustomPythonMethod + def __str__(self): + from llvmpy import extra + os = extra.make_raw_ostream_for_printing() + self.print_(os, None) + return os.str() + + getValueID = Method(cast(Unsigned, int)) diff --git a/llvmpy/src/__init__.py b/llvmpy/src/__init__.py new file mode 100644 index 0000000..36bc12f --- /dev/null +++ b/llvmpy/src/__init__.py @@ -0,0 +1,17 @@ +import os.path + +def _init(root=__name__, file=__file__): + base = os.path.dirname(file) + for fname in os.listdir(base): + is_python_script = fname.endswith('.py') or fname.endswith('.pyc') + is_init_script = fname.startswith('__init__') + is_directory = os.path.isdir(os.path.join(base, fname)) + is_python_module = is_directory and not fname.startswith('__') + if (is_python_module or is_python_script) and not is_init_script: + print(fname) + modname = os.path.basename(fname).rsplit('.', 1)[0] + #importlib.import_module('.' + modname, __name__) + __import__('.'.join([root, modname])) + +_init() + diff --git a/llvmpy/src/namespace.py b/llvmpy/src/namespace.py new file mode 100644 index 0000000..8ad62a3 --- /dev/null +++ b/llvmpy/src/namespace.py @@ -0,0 +1,6 @@ +from binding import * + +default = Namespace('') +llvm = default.Namespace('llvm') +sys = llvm.Namespace('sys') +cl = llvm.Namespace('cl') diff --git a/llvmpy/test_binding.py b/llvmpy/test_binding.py new file mode 100644 index 0000000..aee0167 --- /dev/null +++ b/llvmpy/test_binding.py @@ -0,0 +1,387 @@ +from io import BytesIO, StringIO + +from llvmpy.api import llvm +from llvmpy import extra +from llvmpy import _capsule +import llvmpy.capsule +import collections +llvmpy.capsule.set_debug(True) + + +llvm.InitializeNativeTarget() +llvm.InitializeNativeTargetAsmPrinter() + +def test_basic_jit_use(): + context = llvm.getGlobalContext() + + m = llvm.Module.new("modname", context) + print(m.getModuleIdentifier()) + m.setModuleIdentifier('modname2') + print(m.getModuleIdentifier()) + print('endianness', m.getEndianness()) + assert m.getEndianness() == llvm.Module.Endianness.AnyEndianness + print('pointer-size', m.getPointerSize()) + assert m.getPointerSize() == llvm.Module.PointerSize.AnyPointerSize + m.dump() + + + os = extra.make_raw_ostream_for_printing() + m.print_(os, None) + print(os.str()) + + + int1ty = llvm.Type.getInt1Ty(context) + int1ty.dump() + + assert int1ty.isIntegerTy(1) + + fnty = llvm.FunctionType.get(int1ty, False) + fnty.dump() + + types = [llvm.Type.getIntNTy(context, 8), llvm.Type.getIntNTy(context, 32)] + fnty = llvm.FunctionType.get(llvm.Type.getIntNTy(context, 8), types, False) + + print(fnty) + + const = m.getOrInsertFunction("foo", fnty) + fn = const._downcast(llvm.Function) + print(fn) + assert fn.hasName() + assert 'foo' == fn.getName() + fn.setName('bar') + assert 'bar' == fn.getName() + + assert fn.getReturnType().isIntegerTy(8) + + assert fnty is fn.getFunctionType() + + assert fn.isVarArg() == False + assert fn.getIntrinsicID() == 0 + assert not fn.isIntrinsic() + + fn_uselist = fn.list_use() + assert isinstance(fn_uselist, list) + assert len(fn_uselist) == 0 + + builder = llvm.IRBuilder.new(context) + print(builder) + + bb = llvm.BasicBlock.Create(context, "entry", fn, None) + assert bb.empty() + builder.SetInsertPoint(bb) + + assert bb.getTerminator() is None + + arg0, arg1 = fn.getArgumentList() + print(arg0, arg1) + + extended = builder.CreateZExt(arg0, arg1.getType()) + result = builder.CreateAdd(extended, arg1) + ret = builder.CreateTrunc(result, fn.getReturnType()) + builder.CreateRet(ret) + + print(arg0.list_use()) + + print(fn) + + errio = StringIO() + print(m) + + # verifier + action = llvm.VerifierFailureAction.ReturnStatusAction + + corrupted = llvm.verifyFunction(fn, action) + assert not corrupted + corrupted = llvm.verifyModule(m, action, errio) + print(corrupted) + assert not corrupted, errio.getvalue() + + # build pass manager + pmb = llvm.PassManagerBuilder.new() + pmb.OptLevel = 3 + assert pmb.OptLevel == 3 + pmb.LibraryInfo = llvm.TargetLibraryInfo.new() + pmb.Inliner = llvm.createFunctionInliningPass() + + fpm = llvm.FunctionPassManager.new(m) + pm = llvm.PassManager.new() + + pmb.populateFunctionPassManager(fpm) + pmb.populateModulePassManager(pm) + + fpm.doInitialization() + fpm.run(fn) + fpm.doFinalization() + + pm.run(m) + + print(m) + + # build engine + + ee = llvm.ExecutionEngine.createJIT(m, errio) + print(ee, errio.getvalue()) + print(ee.getDataLayout().getStringRepresentation()) + + datalayout_str = 'e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64' + + assert datalayout_str == str(llvm.DataLayout.new(datalayout_str)) + assert datalayout_str == str(llvm.DataLayout.new(str(llvm.DataLayout.new(datalayout_str)))) + + fn2 = ee.FindFunctionNamed(fn.getName()) + assert fn2 is fn + + assert ee.getPointerToFunction(fn) + assert ee.getPointerToNamedFunction('printf') + + gv0 = llvm.GenericValue.CreateInt(arg0.getType(), 12, False) + gv1 = llvm.GenericValue.CreateInt(arg1.getType(), -32, True) + + assert gv0.valueIntWidth() == arg0.getType().getIntegerBitWidth() + assert gv1.valueIntWidth() == arg1.getType().getIntegerBitWidth() + + assert gv0.toUnsignedInt() == 12 + assert gv1.toSignedInt() == -32 + + gv1 = llvm.GenericValue.CreateInt(arg1.getType(), 32, False) + + gvR = ee.runFunction(fn, (gv0, gv1)) + + assert 44 == gvR.toUnsignedInt() + + # write bitcode + bc_buffer = BytesIO() + llvm.WriteBitcodeToFile(m, bc_buffer) + bc = bc_buffer.getvalue() + bc_buffer.close() + + # read bitcode + errbuf = BytesIO() + m2 = llvm.ParseBitCodeFile(bc, context, errbuf) + if not m2: + raise Exception(errbuf.getvalue()) + else: + m2.setModuleIdentifier(m.getModuleIdentifier()) + assert str(m2) == str(m) + + # parse llvm ir + m3 = llvm.ParseAssemblyString(str(m), None, llvm.SMDiagnostic.new(), context) + m3.setModuleIdentifier(m.getModuleIdentifier()) + assert str(m3) == str(m) + + # test clone + m4 = llvm.CloneModule(m) + assert m4 is not m + assert str(m4) == str(m) + +def test_engine_builder(): + llvm.InitializeNativeTarget() + context = llvm.getGlobalContext() + + m = llvm.Module.new("modname", context) + + int32ty = llvm.Type.getIntNTy(context, 32) + fnty = llvm.FunctionType.get(int32ty, [int32ty], False) + fn = m.getOrInsertFunction("foo", fnty)._downcast(llvm.Function) + bb = llvm.BasicBlock.Create(context, "entry", fn, None) + builder = llvm.IRBuilder.new(context) + builder.SetInsertPoint(bb) + builder.CreateRet(fn.getArgumentList()[0]) + + print(fn) + + eb = llvm.EngineBuilder.new(m) + eb2 = eb.setEngineKind(llvm.EngineKind.Kind.JIT) + assert eb is eb2 + eb.setOptLevel(llvm.CodeGenOpt.Level.Aggressive).setUseMCJIT(False) + + tm = eb.selectTarget() + + print('target triple:', tm.getTargetTriple()) + print('target cpu:', tm.getTargetCPU()) + print('target feature string:', tm.getTargetFeatureString()) + + target = tm.getTarget() + print('target name:', target.getName()) + print('target short description:', target.getShortDescription()) + + assert target.hasJIT() + assert target.hasTargetMachine() + + ee = eb.create(tm) + + triple = llvm.Triple.new('x86_64-unknown-linux') + assert triple.getArchName() == 'x86_64' + assert triple.getVendorName() == 'unknown' + assert triple.getOSName() == 'linux' + assert triple.isArch64Bit() + assert not triple.isArch32Bit() + triple_32variant = triple.get32BitArchVariant() + assert triple_32variant.isArch32Bit() + + print(tm.getDataLayout()) + + pm = llvm.PassManager.new() + pm.add(llvm.DataLayout.new(str(tm.getDataLayout()))) + pm.add(llvm.TargetLibraryInfo.new()) + + # write assembly + pm = llvm.PassManager.new() + pm.add(llvm.DataLayout.new(str(tm.getDataLayout()))) + + raw = extra.make_raw_ostream_for_printing() + formatted = llvm.formatted_raw_ostream.new(raw, False) + + cgft = llvm.TargetMachine.CodeGenFileType.CGFT_AssemblyFile + failed = tm.addPassesToEmitFile(pm, formatted, cgft, False) + assert not failed + + pm.run(m) + + formatted.flush() + raw.flush() + asm = raw.str() + print(asm) + assert 'foo' in asm + + +def test_linker(): + context = llvm.getGlobalContext() + + mA = llvm.Module.new("modA", context) + mB = llvm.Module.new("modB", context) + + def create_function(m, name): + int32ty = llvm.Type.getIntNTy(context, 32) + fnty = llvm.FunctionType.get(int32ty, [int32ty], False) + fn = m.getOrInsertFunction(name, fnty)._downcast(llvm.Function) + bb = llvm.BasicBlock.Create(context, "entry", fn, None) + builder = llvm.IRBuilder.new(context) + builder.SetInsertPoint(bb) + builder.CreateRet(fn.getArgumentList()[0]) + + create_function(mA, 'foo') + create_function(mB, 'bar') + + errmsg = StringIO() + linkermode = llvm.Linker.LinkerMode.PreserveSource + failed = llvm.Linker.LinkModules(mA, mB, linkermode, errmsg) + assert not failed, errmsg.getvalue() + assert mA.getFunction('foo') + assert mA.getFunction('bar') + + assert set(mA.list_functions()) == set([mA.getFunction('foo'), + mA.getFunction('bar')]) + +def test_structtype(): + context = llvm.getGlobalContext() + m = llvm.Module.new("modname", context) + + assert m.getTypeByName("truck") is None + + truck = llvm.StructType.create(context, "truck") + assert 'type opaque' in str(truck) + elemtys = [llvm.Type.getInt32Ty(context), llvm.Type.getDoubleTy(context)] + truck.setBody(elemtys) + + assert 'i32' in str(truck) + assert 'double' in str(truck) + + assert m.getTypeByName("truck") is truck + +def test_globalvariable(): + context = llvm.getGlobalContext() + m = llvm.Module.new("modname", context) + + ty = llvm.Type.getInt32Ty(context) + LinkageTypes = llvm.GlobalVariable.LinkageTypes + linkage = LinkageTypes.ExternalLinkage + gvar = llvm.GlobalVariable.new(m, ty, False, linkage, None, "apple") + assert '@apple = external global i32' in str(m) + + gvar2 = m.getNamedGlobal('apple') + assert gvar2 is gvar + + print(m.list_globals()) + + +def test_sequentialtypes(): + context = llvm.getGlobalContext() + int32ty = llvm.Type.getInt32Ty(context) + ary_int32x4 = llvm.ArrayType.get(int32ty, 4) + assert '[4 x i32]' == str(ary_int32x4) + ptr_int32 = llvm.PointerType.get(int32ty, 1) + assert 'i32 addrspace(1)*' == str(ptr_int32) + vec_int32x4 = llvm.VectorType.get(int32ty, 4) + assert '<4 x i32>' == str(vec_int32x4) + + +def test_constants(): + context = llvm.getGlobalContext() + int32ty = llvm.Type.getInt32Ty(context) + ary_int32x4 = llvm.ArrayType.get(int32ty, 4) + intconst = llvm.ConstantInt.get(int32ty, 123) + aryconst = llvm.ConstantArray.get(ary_int32x4, [intconst] * 4) + assert str(aryconst.getAggregateElement(0)) == str(intconst) + + bignum = 4415104608 + int64ty = llvm.Type.getInt64Ty(context) + const_bignum = llvm.ConstantInt.get(int64ty, 4415104608) + assert str(bignum) in str(const_bignum) + +def test_intrinsic(): + context = llvm.getGlobalContext() + m = llvm.Module.new("modname", context) + INTR_SIN = 1652 + floatty = llvm.Type.getFloatTy(context) + fn = llvm.Intrinsic.getDeclaration(m, INTR_SIN, [floatty]) + assert 'llvm.sin.f32' in str(fn) + fn.eraseFromParent() + assert 'llvm.sin.f32' not in str(m) + +def test_passregistry(): + passreg = llvm.PassRegistry.getPassRegistry() + + llvm.initializeScalarOpts(passreg) + + passinfo = passreg.getPassInfo("dce") + dcepass = passinfo.createPass() + print(dcepass.getPassName()) + + print(passreg.enumerate()) + +def test_targetregistry(): + llvm.TargetRegistry.printRegisteredTargetsForVersion() + errmsg = StringIO() + + target = llvm.TargetRegistry.getClosestTargetForJIT(errmsg) + errmsg.close() + + print(target.getName()) + print(target.getShortDescription()) + assert target.hasJIT() + assert target.hasTargetMachine() + + next = target.getNext() + if next: + print(next.getName()) + print(next.getShortDescription()) + + triple = llvm.sys.getDefaultTargetTriple() + cpu = llvm.sys.getHostCPUName() + features = {} + assert not llvm.sys.getHostCPUFeatures(features), "Only for Linux and ARM?" + + targetoptions = llvm.TargetOptions.new() + tm = target.createTargetMachine(triple, cpu, "", targetoptions) + +def main(): + for name, value in list(globals().items()): + if name.startswith('test_') and isinstance(value, collections.Callable): + print(name.center(80, '-')) + value() + + +if __name__ == '__main__': + main() + diff --git a/test/constants.py b/test/constants.py index afe1020..90a5a53 100644 --- a/test/constants.py +++ b/test/constants.py @@ -21,8 +21,6 @@ def _build_test_module(datatype, constants): bb_entry = func_subject.append_basic_block('entry') builder = Builder.new(bb_entry) - - for k in constants: builder.call(func_subject.args[0], [k]) diff --git a/test/inlineasm.py b/test/inlineasm.py index df91d71..64a4cbe 100644 --- a/test/inlineasm.py +++ b/test/inlineasm.py @@ -20,7 +20,7 @@ class TestInlineAsm(TestCase): inlineasm = InlineAsm.get(iaty, "bswap $0", "=r,r") self.assertIn('asm "bswap $0", "=r,r"', str(inlineasm)) builder.ret(builder.call(inlineasm, [fn.args[0]])) - print fn + print(fn) if __name__ == '__main__': unittest.main() diff --git a/test/malloc.py b/test/malloc.py new file mode 100644 index 0000000..be37dcd --- /dev/null +++ b/test/malloc.py @@ -0,0 +1,16 @@ +from llvm.core import * + +def test(): + m = Module.new('sdf') + f = m.add_function(Type.function(Type.void(), []), 'foo') + bb = f.append_basic_block('entry') + b = Builder.new(bb) + alloc = b.malloc(Type.int(), 'ha') + inst = b.free(alloc) + alloc = b.malloc_array(Type.int(), Constant.int(Type.int(), 10), 'hee') + inst = b.free(alloc) + b.ret_void() + print(m) + +if __name__ == '__main__': + test() diff --git a/test/operands.py b/test/operands.py index 674bc9e..32fb811 100644 --- a/test/operands.py +++ b/test/operands.py @@ -49,6 +49,7 @@ class TestOperands(unittest.TestCase): i1 = test_func.basic_blocks[0].instructions[0] i2 = test_func.basic_blocks[0].instructions[1] + logging.debug("Testing User.operand_count ..") self.assertEqual(i1.operand_count, 3) @@ -61,6 +62,7 @@ class TestOperands(unittest.TestCase): self.assert_(i1.operands[1] is test_func.args[1]) self.assert_(i2.operands[0] is i1) self.assert_(i2.operands[1] is test_func.args[2]) + self.assertEqual(len(i1.operands), 3) self.assertEqual(len(i2.operands), 2) diff --git a/test/tbaa.py b/test/tbaa.py index 242ed19..ad11081 100644 --- a/test/tbaa.py +++ b/test/tbaa.py @@ -29,7 +29,7 @@ class TestTBAABuilder(TestCase): bldr.ret_void() - print mod + print(mod) if __name__ == '__main__': unittest.main() diff --git a/test/test_debuginfo.py b/test/test_debuginfo.py index 33dbbdb..b6a5d6f 100644 --- a/test/test_debuginfo.py +++ b/test/test_debuginfo.py @@ -122,7 +122,7 @@ def debug_in_gdb(lfunc): # Now let's compile and run! retval = ee.run_function(lfunc, [arg1]) - print retval.as_real(float_type) + print(retval.as_real(float_type)) if __name__ == '__main__': diff --git a/test/testall.py b/test/testall.py index 3b5f0c3..231bca3 100644 --- a/test/testall.py +++ b/test/testall.py @@ -18,16 +18,6 @@ def do_llvmexception(): e = LLVMException() -def do_ownable(): - print(" Testing class Ownable") - o = Ownable(None, lambda x: None) - try: - o._own(None) - o._disown() - except LLVMException: - pass - - def do_misc(): print(" Testing miscellaneous functions") try: @@ -44,7 +34,6 @@ def do_misc(): def do_llvm(): print(" Testing module llvm") do_llvmexception() - do_ownable() do_misc() @@ -208,7 +197,9 @@ def do_constant(): Constant.struct([Constant.int(ti,42)]*10) Constant.packed_struct([Constant.int(ti,42)]*10) Constant.vector([Constant.int(ti,42)]*10) + Constant.sizeof(ti) + k = Constant.int(ti, 10) f = Constant.real(Type.float(), 3.1415) k.neg().not_().add(k).sub(k).mul(k).udiv(k).sdiv(k).urem(k) @@ -271,7 +262,8 @@ def do_global_variable(): def do_argument(): print(" Testing class Argument") m = Module.new('a') - ft = Type.function(ti, [ti]) + tip = Type.pointer(ti) + ft = Type.function(tip, [tip]) f = Function.new(m, ft, 'func') a = f.args[0] a.add_attribute(ATTR_ZEXT) @@ -301,13 +293,14 @@ def do_function(): c = f.collector a = list(f.args) g = f.basic_block_count - g = f.get_entry_basic_block() - g = f.append_basic_block('a') - g = f.get_entry_basic_block() +# g = f.entry_basic_block +# g = f.append_basic_block('a') +# g = f.entry_basic_block g = list(f.basic_blocks) f.add_attribute(ATTR_NO_RETURN) f.add_attribute(ATTR_ALWAYS_INLINE) f.remove_attribute(ATTR_NO_RETURN) + # LLVM misbehaves: #try: # f.verify() @@ -414,7 +407,7 @@ def do_builder(): b.position_at_beginning(blk) b.position_at_end(blk) b.position_before(blk.instructions[0]) - blk2 = b.block + blk2 = b.basic_block b.ret_void() b.ret(Constant.int(ti, 10)) _do_builder_mrv() @@ -552,7 +545,7 @@ def do_genericvalue(): def do_executionengine(): print(" Testing class ExecutionEngine") m = Module.new('a') - ee = ExecutionEngine.new(m, True) + ee = ExecutionEngine.new(m, False) # True) ft = Type.function(ti, []) f = m.add_function(ft, 'func') bb = f.append_basic_block('entry') @@ -573,7 +566,7 @@ def do_executionengine(): ee3 = ExecutionEngine.new(m4, False) ee3.add_module(m5) x = ee3.remove_module(m5) - check_is_module(x) + isinstance(x, Module) def do_llvm_ee():