(
self, opname: str, c: pathlib.Path, tempdir: pathlib.Path
)
| 131 | raise NotImplementedError(type(self)) |
| 132 | |
| 133 | async def _compile( |
| 134 | self, opname: str, c: pathlib.Path, tempdir: pathlib.Path |
| 135 | ) -> _stencils.StencilGroup: |
| 136 | s = tempdir / f"{opname}.s" |
| 137 | o = tempdir / f"{opname}.o" |
| 138 | args_s = [ |
| 139 | f"--target={self.triple}", |
| 140 | "-DPy_BUILD_CORE_MODULE", |
| 141 | "-D_DEBUG" if self.debug else "-DNDEBUG", |
| 142 | f"-DSUPPORTS_SMALL_CONSTS={1 if self.optimizer.supports_small_constants else 0}", |
| 143 | f"-D_JIT_OPCODE={opname}", |
| 144 | "-D_PyJIT_ACTIVE", |
| 145 | "-D_Py_JIT", |
| 146 | f"-I{self.pyconfig_dir}", |
| 147 | f"-I{CPYTHON / 'Include'}", |
| 148 | f"-I{CPYTHON / 'Include' / 'internal'}", |
| 149 | f"-I{CPYTHON / 'Include' / 'internal' / 'mimalloc'}", |
| 150 | f"-I{CPYTHON / 'Python'}", |
| 151 | f"-I{CPYTHON / 'Tools' / 'jit'}", |
| 152 | # -O2 and -O3 include some optimizations that make sense for |
| 153 | # standalone functions, but not for snippets of code that are going |
| 154 | # to be laid out end-to-end (like ours)... common examples include |
| 155 | # passes like tail-duplication, or aligning jump targets with nops. |
| 156 | # -Os is equivalent to -O2 with many of these problematic passes |
| 157 | # disabled. Based on manual review, for *our* purposes it usually |
| 158 | # generates better code than -O2 (and -O2 usually generates better |
| 159 | # code than -O3). As a nice benefit, it uses less memory too: |
| 160 | "-Os", |
| 161 | "-S", |
| 162 | # Shorten full absolute file paths in the generated code (like the |
| 163 | # __FILE__ macro and assert failure messages) for reproducibility: |
| 164 | f"-ffile-prefix-map={CPYTHON}=.", |
| 165 | f"-ffile-prefix-map={tempdir}=.", |
| 166 | # This debug info isn't necessary, and bloats out the JIT'ed code. |
| 167 | # We *may* be able to re-enable this, process it, and JIT it for a |
| 168 | # nicer debugging experience... but that needs a lot more research: |
| 169 | "-fno-asynchronous-unwind-tables", |
| 170 | # Don't call built-in functions that we can't find or patch: |
| 171 | "-fno-builtin", |
| 172 | # Don't call stack-smashing canaries that we can't find or patch: |
| 173 | "-fno-stack-protector", |
| 174 | "-std=c11", |
| 175 | "-o", |
| 176 | f"{s}", |
| 177 | f"{c}", |
| 178 | ] |
| 179 | is_shim = opname == "shim" |
| 180 | if self.frame_pointers: |
| 181 | frame_pointer = "all" if is_shim else "reserved" |
| 182 | args_s += ["-Xclang", f"-mframe-pointer={frame_pointer}"] |
| 183 | args_s += self.args |
| 184 | # Allow user-provided CFLAGS to override any defaults |
| 185 | args_s += shlex.split(self.cflags) |
| 186 | await _llvm.run( |
| 187 | "clang", args_s, echo=self.verbose, llvm_version=self.llvm_version |
| 188 | ) |
| 189 | if not is_shim: |
| 190 | self.optimizer( |
no test coverage detected