forked from M-Labs/artiq
compiler: Cache expensive target data layout queries
On one typical experiment, this shaves about 3 seconds (~25%) off the overall kernel compilation time. GitHub: Closes #1370.
This commit is contained in:
parent
5d7f22ffa4
commit
611bcc4db4
|
@ -124,6 +124,35 @@ class DebugInfoEmitter:
|
||||||
"scope": scope
|
"scope": scope
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class ABILayoutInfo:
|
||||||
|
"""Caches DataLayout size/alignment lookup results.
|
||||||
|
|
||||||
|
llvmlite's Type.get_abi_{size, alignment}() are implemented in a very
|
||||||
|
inefficient way, in particular _get_ll_pointer_type() used to construct the
|
||||||
|
corresponding llvm::Type is. We thus cache the results, optionally directly
|
||||||
|
using the compiler type as a key.
|
||||||
|
|
||||||
|
(This is a separate class for use with @memoize.)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, lldatalayout, llcontext, llty_of_type):
|
||||||
|
self.cache = {}
|
||||||
|
self.lldatalayout = lldatalayout
|
||||||
|
self.llcontext = llcontext
|
||||||
|
self.llty_of_type = llty_of_type
|
||||||
|
|
||||||
|
@memoize
|
||||||
|
def get_size_align(self, llty):
|
||||||
|
lowered = llty._get_ll_pointer_type(self.lldatalayout, self.llcontext)
|
||||||
|
return (self.lldatalayout.get_pointee_abi_size(lowered),
|
||||||
|
self.lldatalayout.get_pointee_abi_alignment(lowered))
|
||||||
|
|
||||||
|
@memoize
|
||||||
|
def get_size_align_for_type(self, typ):
|
||||||
|
return self.get_size_align(self.llty_of_type(typ))
|
||||||
|
|
||||||
|
|
||||||
class LLVMIRGenerator:
|
class LLVMIRGenerator:
|
||||||
def __init__(self, engine, module_name, target, embedding_map):
|
def __init__(self, engine, module_name, target, embedding_map):
|
||||||
self.engine = engine
|
self.engine = engine
|
||||||
|
@ -134,6 +163,8 @@ class LLVMIRGenerator:
|
||||||
self.llmodule.triple = target.triple
|
self.llmodule.triple = target.triple
|
||||||
self.llmodule.data_layout = target.data_layout
|
self.llmodule.data_layout = target.data_layout
|
||||||
self.lldatalayout = llvm.create_target_data(self.llmodule.data_layout)
|
self.lldatalayout = llvm.create_target_data(self.llmodule.data_layout)
|
||||||
|
self.abi_layout_info = ABILayoutInfo(self.lldatalayout, self.llcontext,
|
||||||
|
self.llty_of_type)
|
||||||
self.function_flags = None
|
self.function_flags = None
|
||||||
self.llfunction = None
|
self.llfunction = None
|
||||||
self.llmap = {}
|
self.llmap = {}
|
||||||
|
@ -547,11 +578,8 @@ class LLVMIRGenerator:
|
||||||
offset = 0
|
offset = 0
|
||||||
llrpcattrs = []
|
llrpcattrs = []
|
||||||
for attr in typ.attributes:
|
for attr in typ.attributes:
|
||||||
attrtyp = typ.attributes[attr]
|
attrtyp = typ.attributes[attr]
|
||||||
size = self.llty_of_type(attrtyp). \
|
size, alignment = self.abi_layout_info.get_size_align_for_type(attrtyp)
|
||||||
get_abi_size(self.lldatalayout, context=self.llcontext)
|
|
||||||
alignment = self.llty_of_type(attrtyp). \
|
|
||||||
get_abi_alignment(self.lldatalayout, context=self.llcontext)
|
|
||||||
|
|
||||||
if offset % alignment != 0:
|
if offset % alignment != 0:
|
||||||
offset += alignment - (offset % alignment)
|
offset += alignment - (offset % alignment)
|
||||||
|
@ -735,7 +763,7 @@ class LLVMIRGenerator:
|
||||||
|
|
||||||
def mark_dereferenceable(self, load):
|
def mark_dereferenceable(self, load):
|
||||||
assert isinstance(load, ll.LoadInstr) and isinstance(load.type, ll.PointerType)
|
assert isinstance(load, ll.LoadInstr) and isinstance(load.type, ll.PointerType)
|
||||||
pointee_size = load.type.pointee.get_abi_size(self.lldatalayout, context=self.llcontext)
|
pointee_size, _ = self.abi_layout_info.get_size_align(load.type.pointee)
|
||||||
metadata = self.llmodule.add_metadata([ll.Constant(lli64, pointee_size)])
|
metadata = self.llmodule.add_metadata([ll.Constant(lli64, pointee_size)])
|
||||||
load.set_metadata('dereferenceable', metadata)
|
load.set_metadata('dereferenceable', metadata)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue