Commit be01e422 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Initial commit

parents
Makefile.local
tools/demangle
tools/mcjitcache
tools/mcjitcache_release
tools/publicize
tools/publicize_release
pyston
pyston_opt
pyston_noasserts
pyston_oprof
pyston_pprof
pyston_pprof_opt
pyston_dbg
pyston_debug
pyston_prof
pyston_profile
pyston_release
*.cache
tests/t.py
tests/t2.py
*.bc
stdlib.ll
*.o
*.d
*.o.ll
*.o.*.ll
stdlib*.ll
oprofile_data
pprof.jit
tags
*.pyc
perf.data
perf.data.old
perf_map
gmon.out
find_problem.status
*.expected_cache
*.so
Copyright (c) 2014 Dropbox, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This diff is collapsed.
import time
def fannkuch(n):
count = range(1, n+1)
max_flips = 0
m = n-1
r = n
check = 0
perm1 = range(n)
perm = range(n)
perm1_ins = perm1.insert
perm1_pop = perm1.pop
while 1:
if check < 30:
#print "".join(str(i+1) for i in perm1)
check = check + 1
while r != 1:
count[r-1] = r
r = r - 1
if perm1[0] != 0 and perm1[m] != m:
perm = perm1[:]
flips_count = 0
k = perm[0]
while k:
perm[:k+1] = perm[k::-1]
flips_count = flips_count + 1
k = perm[0]
if flips_count > max_flips:
max_flips = flips_count
while r != n:
perm1_ins(r, perm1_pop(0))
count[r] = count[r] - 1
if count[r] > 0:
break
r = r + 1
else:
return max_flips
DEFAULT_ARG = 9
def main(n):
for i in range(2, n):
t0 = time.time()
print fannkuch(i)
tk = time.time()
print tk - t0
main(11)
import time
def fannkuch(n):
count = range(1, n+1)
max_flips = 0
m = n-1
r = n
check = 0
perm1 = range(n)
perm = range(n)
perm1_ins = perm1.insert
perm1_pop = perm1.pop
while 1:
if check < 30:
#print "".join(str(i+1) for i in perm1)
check = check + 1
while r != 1:
count[r-1] = r
r = r - 1
if perm1[0] != 0 and perm1[m] != m:
perm = perm1[:]
flips_count = 0
k = perm[0]
while k:
perm[:k+1] = perm[k::-1]
flips_count = flips_count + 1
k = perm[0]
if flips_count > max_flips:
max_flips = flips_count
while r != n:
perm1_ins(r, perm1_pop(0))
count[r] = count[r] - 1
if count[r] > 0:
break
r = r + 1
else:
return max_flips
DEFAULT_ARG = 9
def main(n):
for i in range(2, n):
t0 = time.time()
print fannkuch(i)
tk = time.time()
print tk - t0
main(10)
class Random(object):
def __init__(self, seed):
self.cur = seed
def next(self):
self.cur = (self.cur * 1103515245 + 12345) % (1 << 31)
return self.cur
class AstAssign(object):
def __init__(self, name, expr):
self.name = name
self.expr = expr
class AstWhile(object):
def __init__(self, test, body):
self.test = test
self.body = body
class AstBinop(object):
def __init__(self, lhs, rhs, op):
self.lhs = lhs
self.rhs = rhs
self.op = op
class AstPrint(object):
def __init__(self, expr):
self.expr = expr
class AstIf(object):
def __init__(self, test, then, orelse):
self.test = test
self.then = then
self.orelse = orelse
class State(object):
def __init__(self):
self.syms = {}
def _run(state, node):
if isinstance(node, list):
for s in node:
_run(state, s)
return None
elif isinstance(node, AstAssign):
v = _run(state, node.expr)
state.syms[node.name] = v
return None
elif isinstance(node, int):
return node
elif isinstance(node, str):
return state.syms[node]
elif isinstance(node, AstPrint):
v = _run(state, node.expr)
print v
elif isinstance(node, AstBinop):
l = _run(state, node.lhs)
r = _run(state, node.rhs)
if node.op == '+':
return l + r
if node.op == '-':
return l - r
if node.op == '*':
return l * r
if node.op == '%':
return l % r
if node.op == "<":
return l < r
if node.op == "<=":
return l <= r
if node.op == "==":
return l == r
print node.op
1/0
elif isinstance(node, AstIf):
v = _run(state, node.test)
if v:
_run(state, node.then)
else:
_run(state, node.orelse)
elif isinstance(node, AstWhile):
while True:
v = _run(state, node.test)
if not v:
break
_run(state, node.body)
return None
else:
print type(node)
1/0
def run(node):
_run(State(), node)
prog = [
AstAssign("x", 100000),
AstAssign("t", 0),
AstWhile("x", [
AstAssign("t", AstBinop("t", "x", '+')),
AstAssign("x", AstBinop("x", 1, '-')),
# AstPrint("x"),
]),
AstPrint("t"),
]
prog = [
AstAssign("i", 2),
AstAssign("t", 0),
AstWhile(AstBinop("i", 10000, '<'), [
AstAssign("j", 2),
AstAssign("good", 1),
AstWhile(AstBinop(AstBinop("j", "j", '*'), "i", "<="), [
AstIf(AstBinop(AstBinop("i", "j", "%"), 0, "=="), [
AstAssign("good", 0),
], [
]),
AstAssign("j", AstBinop("j", 1, "+")),
]),
AstIf("good", [
AstPrint("i"),
AstAssign("t", AstBinop("t", "i", "+")),
], []),
AstAssign("i", AstBinop("i", 1, "+")),
]),
AstPrint("t"),
]
run(prog)
class Random(object):
def __init__(self, seed):
self.cur = seed
def next(self):
self.cur = (self.cur * 1103515245 + 12345) % (1 << 31)
return self.cur
class AstAssign(object):
def __init__(self, name, expr):
self.name = name
self.expr = expr
class AstWhile(object):
def __init__(self, test, body):
self.test = test
self.body = body
class AstBinop(object):
def __init__(self, lhs, rhs, op):
self.lhs = lhs
self.rhs = rhs
self.op = op
class AstPrint(object):
def __init__(self, expr):
self.expr = expr
class AstIf(object):
def __init__(self, test, then, orelse):
self.test = test
self.then = then
self.orelse = orelse
class State(object):
def __init__(self):
self.syms = {}
def visit(visitor, node):
if isinstance(node, list):
for s in node:
visit(visitor, s)
return None
type_name = type(node).__name__.lower()
return getattr(visitor, "visit_" + type_name)(node)
class InterpVisitor(object):
def __init__(self):
self.syms = {}
def visit(self, node):
return visit(self, node)
def visit_astassign(self, node):
v = self.visit(node.expr)
self.syms[node.name] = v
def visit_int(self, node):
return node
def visit_str(self, node):
return self.syms[node]
def visit_astwhile(self, node):
while True:
v = self.visit(node.test)
if not v:
break
self.visit(node.body)
def visit_astbinop(self, node):
l = self.visit(node.lhs)
r = self.visit(node.rhs)
if node.op == '+':
return l + r
if node.op == '-':
return l - r
if node.op == '*':
return l * r
if node.op == '%':
return l % r
if node.op == "<":
return l < r
if node.op == "<=":
return l <= r
if node.op == "==":
return l == r
print node.op
1/0
def visit_astif(self, node):
v = self.visit(node.test)
if v:
self.visit(node.then)
else:
self.visit(node.orelse)
def visit_astprint(self, node):
v = self.visit(node.expr)
print v
def run(node):
visit(InterpVisitor(), node)
prog = [
AstAssign("x", 100000),
AstAssign("t", 0),
AstWhile("x", [
AstAssign("t", AstBinop("t", "x", '+')),
AstAssign("x", AstBinop("x", 1, '-')),
# AstPrint("x"),
]),
AstPrint("t"),
]
prog = [
AstAssign("i", 2),
AstAssign("t", 0),
AstWhile(AstBinop("i", 5000, '<'), [
AstAssign("j", 2),
AstAssign("good", 1),
AstWhile(AstBinop(AstBinop("j", "j", '*'), "i", "<="), [
AstIf(AstBinop(AstBinop("i", "j", "%"), 0, "=="), [
AstAssign("good", 0),
], [
]),
AstAssign("j", AstBinop("j", 1, "+")),
]),
AstIf("good", [
AstPrint("i"),
AstAssign("t", AstBinop("t", "i", "+")),
], []),
AstAssign("i", AstBinop("i", 1, "+")),
]),
AstPrint("t"),
]
run(prog)
# -*- coding: utf-8 -*-
# The Computer Language Benchmarks Game
# http://shootout.alioth.debian.org/
#
# contributed by Kevin Carson
# modified by Tupteq, Fredrik Johansson, and Daniel Nanz
import time
def combinations(l):
result = []
for x in xrange(len(l) - 1):
for j in xrange(x+1, len(l)):
# ls = l[x+1:]
# for y in ls:
y = l[j]
result.append((l[x],y))
return result
PI = 3.14159265358979323
SOLAR_MASS = 4 * PI * PI
DAYS_PER_YEAR = 365.24
BODIES = {
1: ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], SOLAR_MASS),
2: ([4.84143144246472090e+00,
-1.16032004402742839e+00,
-1.03622044471123109e-01],
[1.66007664274403694e-03 * DAYS_PER_YEAR,
7.69901118419740425e-03 * DAYS_PER_YEAR,
-6.90460016972063023e-05 * DAYS_PER_YEAR],
9.54791938424326609e-04 * SOLAR_MASS),
3: ([8.34336671824457987e+00,
4.12479856412430479e+00,
-4.03523417114321381e-01],
[-2.76742510726862411e-03 * DAYS_PER_YEAR,
4.99852801234917238e-03 * DAYS_PER_YEAR,
2.30417297573763929e-05 * DAYS_PER_YEAR],
2.85885980666130812e-04 * SOLAR_MASS),
4: ([1.28943695621391310e+01,
-1.51111514016986312e+01,
-2.23307578892655734e-01],
[2.96460137564761618e-03 * DAYS_PER_YEAR,
2.37847173959480950e-03 * DAYS_PER_YEAR,
-2.96589568540237556e-05 * DAYS_PER_YEAR],
4.36624404335156298e-05 * SOLAR_MASS),
5: ([1.53796971148509165e+01,
-2.59193146099879641e+01,
1.79258772950371181e-01],
[2.68067772490389322e-03 * DAYS_PER_YEAR,
1.62824170038242295e-03 * DAYS_PER_YEAR,
-9.51592254519715870e-05 * DAYS_PER_YEAR],
5.15138902046611451e-05 * SOLAR_MASS) }
SYSTEM = BODIES.values()
PAIRS = combinations(SYSTEM)
def advance(dt, n):
bodies=SYSTEM
pairs=PAIRS
for i in xrange(n):
for (((x1, y1, z1), v1, m1),
((x2, y2, z2), v2, m2)) in pairs:
dx = x1 - x2
dy = y1 - y2
dz = z1 - z2
mag = dt * ((dx * dx + dy * dy + dz * dz) ** (-1.5))
b1m = m1 * mag
b2m = m2 * mag
v1[0] = v1[0] - dx * b2m
v1[1] = v1[1] - dy * b2m
v1[2] = v1[2] - dz * b2m
v2[0] = v2[0] + dx * b1m
v2[1] = v2[1] + dy * b1m
v2[2] = v2[2] + dz * b1m
for (r, (vx, vy, vz), m) in bodies:
r[0] = r[0] + dt * vx
r[1] = r[1] + dt * vy
r[2] = r[2] + dt * vz
def report_energy():
bodies=SYSTEM
pairs=PAIRS
e=0.0
for (((x1, y1, z1), v1, m1),
((x2, y2, z2), v2, m2)) in pairs:
dx = x1 - x2
dy = y1 - y2
dz = z1 - z2
e = e - (m1 * m2) / ((dx * dx + dy * dy + dz * dz) ** 0.5)
for (r, (vx, vy, vz), m) in bodies:
e = e + m * (vx * vx + vy * vy + vz * vz) / 2.
return e
def offset_momentum(ref, bodies, px, py, pz):
for (r, (vx, vy, vz), m) in bodies:
px = px - vx * m
py = py - vy * m
pz = pz - vz * m
(r, v, m) = ref
v[0] = px / m
v[1] = py / m
v[2] = pz / m
NUMBER_OF_ITERATIONS = 20000
def main(n, ref):
# XXX warmup
times = []
for i in range(n):
t0 = time.time()
offset_momentum(BODIES[ref], SYSTEM, 0.0, 0.0, 0.0)
e1 = report_energy()
advance(0.01, NUMBER_OF_ITERATIONS)
print e1 - report_energy()
tk = time.time()
times.append(tk - t0)
return times
main(40,2)
# -*- coding: utf-8 -*-
# The Computer Language Benchmarks Game
# http://shootout.alioth.debian.org/
#
# contributed by Kevin Carson
# modified by Tupteq, Fredrik Johansson, and Daniel Nanz
import time
def combinations(l):
result = []
for x in xrange(len(l) - 1):
for j in xrange(x+1, len(l)):
# ls = l[x+1:]
# for y in ls:
y = l[j]
result.append((l[x],y))
return result
PI = 3.14159265358979323
SOLAR_MASS = 4 * PI * PI
DAYS_PER_YEAR = 365.24
BODIES = {
1: ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], SOLAR_MASS),
2: ([4.84143144246472090e+00,
-1.16032004402742839e+00,
-1.03622044471123109e-01],
[1.66007664274403694e-03 * DAYS_PER_YEAR,
7.69901118419740425e-03 * DAYS_PER_YEAR,
-6.90460016972063023e-05 * DAYS_PER_YEAR],
9.54791938424326609e-04 * SOLAR_MASS),
3: ([8.34336671824457987e+00,
4.12479856412430479e+00,
-4.03523417114321381e-01],
[-2.76742510726862411e-03 * DAYS_PER_YEAR,
4.99852801234917238e-03 * DAYS_PER_YEAR,
2.30417297573763929e-05 * DAYS_PER_YEAR],
2.85885980666130812e-04 * SOLAR_MASS),
4: ([1.28943695621391310e+01,
-1.51111514016986312e+01,
-2.23307578892655734e-01],
[2.96460137564761618e-03 * DAYS_PER_YEAR,
2.37847173959480950e-03 * DAYS_PER_YEAR,
-2.96589568540237556e-05 * DAYS_PER_YEAR],
4.36624404335156298e-05 * SOLAR_MASS),
5: ([1.53796971148509165e+01,
-2.59193146099879641e+01,
1.79258772950371181e-01],
[2.68067772490389322e-03 * DAYS_PER_YEAR,
1.62824170038242295e-03 * DAYS_PER_YEAR,
-9.51592254519715870e-05 * DAYS_PER_YEAR],
5.15138902046611451e-05 * SOLAR_MASS) }
SYSTEM = BODIES.values()
PAIRS = combinations(SYSTEM)
def advance(dt, n):
bodies=SYSTEM
pairs=PAIRS
for i in xrange(n):
for (((x1, y1, z1), v1, m1),
((x2, y2, z2), v2, m2)) in pairs:
dx = x1 - x2
dy = y1 - y2
dz = z1 - z2
mag = dt * ((dx * dx + dy * dy + dz * dz) ** (-1.5))
b1m = m1 * mag
b2m = m2 * mag
v1[0] = v1[0] - dx * b2m
v1[1] = v1[1] - dy * b2m
v1[2] = v1[2] - dz * b2m
v2[0] = v2[0] + dx * b1m
v2[1] = v2[1] + dy * b1m
v2[2] = v2[2] + dz * b1m
for (r, (vx, vy, vz), m) in bodies:
r[0] = r[0] + dt * vx
r[1] = r[1] + dt * vy
r[2] = r[2] + dt * vz
def report_energy():
bodies=SYSTEM
pairs=PAIRS
e=0.0
for (((x1, y1, z1), v1, m1),
((x2, y2, z2), v2, m2)) in pairs:
dx = x1 - x2
dy = y1 - y2
dz = z1 - z2
e = e - (m1 * m2) / ((dx * dx + dy * dy + dz * dz) ** 0.5)
for (r, (vx, vy, vz), m) in bodies:
e = e + m * (vx * vx + vy * vy + vz * vz) / 2.
return e
def offset_momentum(ref, bodies, px, py, pz):
for (r, (vx, vy, vz), m) in bodies:
px = px - vx * m
py = py - vy * m
pz = pz - vz * m
(r, v, m) = ref
v[0] = px / m
v[1] = py / m
v[2] = pz / m
NUMBER_OF_ITERATIONS = 5000
def main(n, ref):
# XXX warmup
times = []
for i in range(n):
t0 = time.time()
offset_momentum(BODIES[ref], SYSTEM, 0.0, 0.0, 0.0)
e1 = report_energy()
advance(0.01, NUMBER_OF_ITERATIONS)
print e1 - report_energy()
tk = time.time()
times.append(tk - t0)
return times
main(40,2)
This diff is collapsed.
DEPENDENCIES:
# Pyston expects to find all of its dependencies in ~/pyston_deps:
mkdir ~/pyston_deps
GCC (assuming 4.8.2):
sudo apt-get install libgmp-dev libmpfr-dev libmpc-dev make build-essential libtool zip gcc-multilib autogen
cd ~/pyston_deps
wget 'http://www.netgull.com/gcc/releases/gcc-4.8.2/gcc-4.8.2.tar.bz2'
tar xvf gcc-4.8.2.tar.bz2
mkdir gcc-4.8.2-{build,install}
cd gcc-4.8.2-build
# Space-saving configuration:
../gcc-4.8.2/configure --disable-bootstrap --enable-languages=c,c++ --prefix=$HOME/pyston_deps/gcc-4.8.2-install
# full configuration:
# ../gcc-4.8.2/configure --prefix=$HOME/pyston_deps/gcc-4.8.2-install
make -j4
make check
make install
curses, zlib:
sudo apt-get install libncurses5-dev zlib1g-dev
LLVM: # note: requires gcc-4.7+, and pyston by default assumes you've installed gcc-4.8.2 as above)
cd ~/pyston_deps
git clone http://llvm.org/git/llvm.git llvm-trunk
git clone http://llvm.org/git/clang.git llvm-trunk/tools/clang
cd ~/pyston/src
make llvm_up
make llvm_configure
make llvm -j4
libunwind:
download from http://download.savannah.gnu.org/releases/libunwind
valgrind:
not sure exactly what version is required, but 3.7.0 doesn't seem quite good enough (can't handle 'tzcnt' instruction)
cd ~/pyston_deps
wget http://valgrind.org/downloads/valgrind-3.9.0.tar.bz2
tar xvf valgrind-3.9.0.tar.bz2
mkdir valgrind-3.9.0-install
cd valgrind-3.9.0
./configure --prefix=$HOME/pyston_deps/valgrind-3.9.0-install
make -j4
make install
# Add this line to Makefile.local:
VALGRIND := VALGRIND_LIB=$(HOME)/pyston_deps/valgrind-3.9.0-install/lib/valgrind $(HOME)/pyston_deps/valgrind-3.9.0-install/bin/valgrind
sudo apt-get install libc6-dbg
OPTIONAL DEPENDENCIES:
ccache, distcc:
sudo apt-get install ccache
sudo apt-get install distcc distcc-pump
gtest:
cd ~/pyston_deps
wget https://googletest.googlecode.com/files/gtest-1.7.0.zip
unzip gtest-1.7.0.zip
cd gtest-1.7.0
./configure
make -j4
gdb:
cd ~/pyston_deps
wget http://ftp.gnu.org/gnu/gdb/gdb-7.6.2.tar.gz
tar xvf gdb-7.6.2.tar.gz
cd gdb-7.6.2
./configure
make -j4
# then add this to Makefile.local:
GDB := $(HOME)/pyston_deps/gdb-7.6.2/gdb/gdb
gperftools (-lprofiler):
download from http://code.google.com/p/gperftools/downloads/list
standard ./configure, make, make install
gold, if not installed (instructions mostly from http://llvm.org/docs/GoldPlugin.html):
cd ~/pyston_deps
git clone --depth 1 git://sourceware.org/git/binutils-gdb.git binutils
mkdir binutils-build
cd binutils-build
../binutils/configure --enable-gold --enable-plugins --disable-werror
make all-gold
perf:
sudo apt-get install linux-tools
sudo apt-get install linux-tools-`uname -r`
# may need to strip off the -generic from that last one
turning off ASLR:
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
gdb does this automatically, but disabling it outside of gdb can be nice to correlate runs with other runs or debugging.
for better tracebacks, make sure that NoFramePointerElim is set to true in entry.cpp
#ifndef PYSTON_EXTINCLUDE_PYTHON_H
#define PYSTON_EXTINCLUDE_PYTHON_H
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
//struct PyObject {
//};
//typedef struct PyObject PyObject;
typedef void PyObject;
#define Py_INCREF(x)
bool PyArg_ParseTuple(PyObject*, const char*, ...);
PyObject* Py_BuildValue(const char*, ...);
typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
struct PyMethodDef {
const char *ml_name; /* The name of the built-in function/method */
PyCFunction ml_meth; /* The C function that implements it */
int ml_flags; /* Combination of METH_xxx flags, which mostly
describe the args expected by the C func */
const char *ml_doc; /* The __doc__ attribute, or NULL */
};
typedef struct PyMethodDef PyMethodDef;
#define METH_VARARGS 0x0001
#ifdef __cplusplus
#define PyMODINIT_FUNC extern "C" void
#else
#define PyMODINIT_FUNC void
#endif
#define PYTHON_API_VERSION 1013
#define PYTHON_API_STRING "1013"
PyObject* Py_InitModule4(const char *arg0, PyMethodDef *arg1, const char *arg2, PyObject *arg3, int arg4);
#define Py_InitModule(name, methods) \
Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \
PYTHON_API_VERSION)
#endif
From b370f4621298ec557e356e21fa0fa675a21d2331 Mon Sep 17 00:00:00 2001
From: Kevin Modzelewski <kmod@dropbox.com>
Date: Fri, 21 Mar 2014 16:06:58 -0700
Subject: [PATCH] Support emitting stackmap sections for ELF object files as
well
---
lib/IR/Function.cpp | 8 ++-
lib/MC/MCObjectFileInfo.cpp | 5 ++
lib/Target/X86/X86AsmPrinter.cpp | 2 +
test/CodeGen/X86/stackmap-elf.ll | 124 ++++++++++++++++++++++++++++++++++++++
4 files changed, 138 insertions(+), 1 deletion(-)
create mode 100644 test/CodeGen/X86/stackmap-elf.ll
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index c1fa372..d11727d 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -681,7 +681,13 @@ FunctionType *Intrinsic::getType(LLVMContext &Context,
while (!TableRef.empty())
ArgTys.push_back(DecodeFixedType(TableRef, Tys, Context));
- return FunctionType::get(ResultTy, ArgTys, false);
+ bool variadic = false;
+ if (ArgTys.size() && ArgTys.back() == Type::getVoidTy(Context)) {
+ variadic = true;
+ ArgTys.pop_back();
+ }
+
+ return FunctionType::get(ResultTy, ArgTys, variadic);
}
bool Intrinsic::isOverloaded(ID id) {
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index 931b354..40899c1 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -537,6 +537,11 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfAddrSection =
Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+
+ StackMapSection =
+ Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC,
+ SectionKind::getMetadata());
}
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index e6ad2f1..62f8f23 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -723,6 +723,8 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
}
Stubs.clear();
}
+
+ SM.serializeToStackMapSection();
}
}
diff --git a/test/CodeGen/X86/stackmap-elf.ll b/test/CodeGen/X86/stackmap-elf.ll
new file mode 100644
index 0000000..1c838e2
--- /dev/null
+++ b/test/CodeGen/X86/stackmap-elf.ll
@@ -0,0 +1,125 @@
+; XFAIL:
+; RUN: llc < %s -mtriple=x86_64-linux -mcpu=corei7 -disable-fp-elim | FileCheck %s
+;
+; Note: the main stackmap tests are in stackmap.ll; this file is for
+; ensuring that the functionality transfers to ELF.
+;
+; Note: Print verbose stackmaps using -debug-only=stackmaps.
+
+; CHECK-LABEL: .section .llvm_stackmaps
+; CHECK-NEXT: __LLVM_StackMaps:
+; CHECK-NEXT: .long 0
+; Num LargeConstants
+; CHECK-NEXT: .long 1
+; CHECK-NEXT: .quad 4294967296
+; Num Callsites
+; CHECK-NEXT: .long 8
+
+; Constant arguments
+;
+; CHECK-NEXT: .quad 1
+; CHECK-NEXT: .long .L{{.*}}-constantargs
+; CHECK-NEXT: .short 0
+; CHECK-NEXT: .short 2
+; SmallConstant
+; CHECK-NEXT: .byte 4
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .short 0
+; CHECK-NEXT: .long -1
+; LargeConstant at index 0
+; CHECK-NEXT: .byte 5
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .short 0
+; CHECK-NEXT: .long 0
+
+define void @constantargs() {
+entry:
+ %0 = inttoptr i64 12345 to i8*
+ tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 1, i32 15, i8* %0, i32 0, i64 4294967295, i64 4294967296)
+ ret void
+}
+
+; Property Read
+; CHECK-LABEL: .long .L{{.*}}-propertyRead
+; CHECK-NEXT: .short 0
+; CHECK-NEXT: .short 2
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .short {{[0-9]+}}
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .short {{[0-9]+}}
+; CHECK-NEXT: .long 0
+define i64 @propertyRead(i64* %obj) {
+entry:
+ %resolveRead = inttoptr i64 -559038737 to i8*
+ %result = call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 5, i32 15, i8* %resolveRead, i32 1, i64* %obj)
+ %add = add i64 %result, 3
+ ret i64 %add
+}
+
+; i64 JS Call
+;
+; 2 live variables in registers.
+;
+; CHECK-LABEL: .long .L{{.*}}-jsIntCall
+; CHECK-NEXT: .short 0
+; CHECK-NEXT: .short 2
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .short {{[0-9]+}}
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .short {{[0-9]+}}
+; CHECK-NEXT: .long 0
+define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
+entry:
+ %resolveCall = inttoptr i64 -559038737 to i8*
+ %result = call i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 8, i32 15, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
+ %add = add i64 %result, 3
+ ret i64 %add
+}
+
+; Spilled stack map values.
+;
+; Verify 17 stack map entries.
+;
+; CHECK-LABEL: .long .L{{.*}}-spilledValue
+; CHECK-NEXT: .short 0
+; CHECK-NEXT: .short 17
+;
+; Check that at least one is a spilled entry from RBP.
+; Location: Indirect RBP + ...
+; CHECK: .byte 3
+; CHECK-NEXT: .byte 8
+; CHECK-NEXT: .short 6
+define void @spilledValue(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) {
+entry:
+ call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 11, i32 15, i8* null, i32 5, i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16)
+ ret void
+}
+
+; Test a 64-bit ID.
+;
+; CHECK: .quad 4294967295
+; CHECK-LABEL: .long .L{{.*}}-longid
+; CHECK: .quad 4294967296
+; CHECK-LABEL: .long .L{{.*}}-longid
+; CHECK: .quad 9223372036854775807
+; CHECK-LABEL: .long .L{{.*}}-longid
+; CHECK: .quad -1
+; CHECK-LABEL: .long .L{{.*}}-longid
+define void @longid() {
+entry:
+ tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4294967295, i32 0, i8* null, i32 0)
+ tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4294967296, i32 0, i8* null, i32 0)
+ tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 9223372036854775807, i32 0, i8* null, i32 0)
+ tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 -1, i32 0, i8* null, i32 0)
+ ret void
+}
+
+declare void @llvm.experimental.stackmap(i64, i32, ...)
+declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
+declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)
--
1.7.9.5
From 333e582e651efaf3678ed8b89cd2274f75818649 Mon Sep 17 00:00:00 2001
From: Kevin Modzelewski <kmod@dropbox.com>
Date: Fri, 21 Mar 2014 16:56:28 -0700
Subject: [PATCH] Update TailCallElim to avoid making redundant changes
---
lib/Transforms/Scalar/TailRecursionElimination.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp
index 351aee0..7300d84 100644
--- a/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -252,8 +252,10 @@ bool TailCallElim::runOnFunction(Function &F) {
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
if (CallInst *CI = dyn_cast<CallInst>(I)) {
if (!ACT.UsesAlloca.count(CI)) {
- CI->setTailCall();
- MadeChange = true;
+ if (!CI->isTailCall()) {
+ CI->setTailCall();
+ MadeChange = true;
+ }
}
}
}
--
1.7.9.5
class C(object):
pass
def f(n):
c = C()
c.x = 1.0
t = 2.0
for i in xrange(n):
t = t + (c.x * 1.0 + 1.0)
# while n:
# t = t + (c.x * 1.0 + 1.0)
# n = n - 1
return t
print f(2000000000)
# attr perf test: functions are still the only
# things that support setattr, so use those
def p(x, p):
p.n = p.n + x.a
p.n = 0
def s(x, n):
x.a = n
x.b = "hello world"
n = 1000000
while n:
n = n - 1
def f():
pass
s(f, n)
p(f, p)
print p.n
def outer(n):
def inner():
return n
return inner
n = 1000000
t = 0
while n:
n = n - 1
t = t + outer(n)()
print t
def f(n):
for i in xrange(n):
pass
f(100000000)
print "done with first"
_xrange = xrange
def xrange(end):
return _xrange(end-1)
f(100000000)
print "done with second"
# Simple function call test.
# Uses this formulation (passing the function in to itself) to not require supporting scoped lookups.
def fib(n, f):
if n <= 2:
return n
return f(n-1, f) + f(n-2, f)
print fib(36, fib)
# Same as fib.py, but I now support global lookups!
def fib(n):
if n <= 2:
return n
return fib(n-1) + fib(n-2)
print fib(36)
# Simple function call microbenchmark.
# Not really that interesting, but useful because it does a lot of work without any control flow
def f0():
return 1
def f1():
return f0() + f0()
def f2():
return f1() + f1()
def f3():
return f2() + f2()
def f4():
return f3() + f3()
def f5():
return f4() + f4()
def f6():
return f5() + f5()
def f7():
return f6() + f6()
def f8():
return f7() + f7()
def f9():
return f8() + f8()
def f10():
return f9() + f9()
def f11():
return f10() + f10()
def f12():
return f11() + f11()
def f13():
return f12() + f12()
def f14():
return f13() + f13()
def f15():
return f14() + f14()
def f16():
return f15() + f15()
def f17():
return f16() + f16()
def f18():
return f17() + f17()
def f19():
return f18() + f18()
def f20():
return f19() + f19()
def f21():
return f20() + f20()
def f22():
return f21() + f21()
def f23():
return f22() + f22()
def f24():
return f23() + f23()
def f25():
return f24() + f24()
def f26():
return f25() + f25()
def f27():
return f26() + f26()
def f28():
return f27() + f27()
def f29():
return f28() + f28()
def f30():
return f29() + f29()
print f25()
t = 0
for i in range(1000000):
t = t + i
print t
class Random(object):
def __init__(self, seed):
self.cur = seed
def next(self):
self.cur = (self.cur * 1103515245 + 12345) % (1 << 31)
return self.cur
def f():
r = Random(0)
t = 0
for i in xrange(10000000):
t = t + r.next()
print t
f()
def outer():
def inner(n):
return n
return inner
n = 1000000
t = 0
while n:
n = n - 1
t = t + outer()(n)
print t
#include <cstdio>
int main(int argc, char** argv) {
long long total = 0;
for (long long i = 2; i < 2000000; i++) {
bool prime = true;
for (int j = 2; j * j <= i; j++) {
if (i % j == 0) {
prime = false;
break;
}
}
if (prime)
total += i;
}
printf("%lld\n", total);
return 0;
}
def f():
total = 0
i = 1
while i < 2000000:
i = i + 1
j = 2
while j * j <= i:
if i % j == 0:
break
j = j + 1
else:
total = total + i
print total
f()
# Re-patching test: have a single callsite that frequently has different target functions:
def a():
return 1
def b():
return 2
def c(f):
# The difficult callsite:
return f()
x = 1000000
y = 0
while x:
y = y + c(a)
y = y + c(b)
x = x - 1
print y
def f(n):
t = 0
for i in xrange(n):
t = t + n
return t
print f(1000000)
_xrange = xrange
def xrange(end):
return _xrange(end-1)
print f(1000000)
def sort(l):
n = len(l)
for i in xrange(n):
print i
for j in xrange(i):
if l[i] < l[j]:
l[i], l[j] = l[j], l[i]
return l
l = []
N = 5000
for i in xrange(N):
l.append(N - i)
sort(l)
print l
class Vector(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __add__(self, rhs):
return Vector(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
def __str__(self):
return "Vector(%f, %f, %f)" % (self.x, self.y, self.z)
def f(n):
v = Vector(0,0,0)
a = Vector(1.0, 1.1, 1.2)
# b = Vector(1, -2, 1)
for i in xrange(n):
# if v.y > 0:
# v = v + b
v = v + a
return v
print f(10000000)
class Vector(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __add__(self, rhs):
return Vector(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
def dot(self, rhs):
return self.x * rhs.x + self.y * rhs.y + self.z * rhs.z
def f(n):
v = Vector(0,0.1,0)
a = Vector(1.0, 1.1, 1.2)
t = 0
for i in xrange(n):
t = t + v.dot(a)
return t
print f(10000000)
This diff is collapsed.
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_ANALYSIS_FPC_H
#define PYSTON_ANALYSIS_FPC_H
#include "core/common.h"
#include "core/options.h"
#include "core/cfg.h"
namespace pyston {
template <typename T>
class BBAnalyzer {
public:
typedef std::unordered_map<std::string, T> Map;
typedef std::unordered_map<CFGBlock*, Map> AllMap;
virtual T merge(T from, T into) const = 0;
virtual T mergeBlank(T into) const = 0;
virtual void processBB(Map &starting, CFGBlock *block) const = 0;
};
template <typename T>
typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &analyzer, bool reverse) {
assert(!reverse);
typedef typename BBAnalyzer<T>::Map Map;
typedef typename BBAnalyzer<T>::AllMap AllMap;
AllMap states;
std::vector<CFGBlock*> q;
states.insert(make_pair(cfg->blocks[0], Map()));
q.push_back(cfg->blocks[0]);
while (q.size()) {
CFGBlock *block = q.back();
q.pop_back();
Map initial = states[block];
if (VERBOSITY("analysis") >= 2) printf("fpc on block %d - %ld entries\n", block->idx, initial.size());
Map ending = Map(initial);
analyzer.processBB(ending, block);
for (int i = 0; i < block->successors.size(); i++) {
CFGBlock *next_block = block->successors[i];
bool changed = false;
bool initial = false;
if (states.count(next_block) == 0) {
changed = true;
initial = true;
}
Map &next = states[next_block];
for (typename Map::iterator it = ending.begin(), end = ending.end(); it != end; ++it) {
if (next.count(it->first) == 0) {
changed = true;
if (initial) {
next[it->first] = it->second;
} else {
next[it->first] = analyzer.mergeBlank(it->second);
}
} else {
T &next_elt = next[it->first];
T new_elt = analyzer.merge(it->second, next_elt);
if (next_elt != new_elt) {
next_elt = new_elt;
changed = true;
}
}
}
for (typename Map::iterator it = next.begin(), end = ending.end(); it != end; ++it) {
if (ending.count(it->first))
continue;
T next_elt = analyzer.mergeBlank(it->second);
if (next_elt != it->second) {
next[it->first] = next_elt;
changed = true;
}
}
if (changed)
q.push_back(next_block);
}
states.erase(block);
states.insert(make_pair(block, ending));
}
return states;
}
}
#endif
This diff is collapsed.
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_ANALYSIS_FUNCTIONANALYSIS_H
#define PYSTON_ANALYSIS_FUNCTIONANALYSIS_H
#include <unordered_set>
namespace pyston {
class AST_arguments;
class AST_Jump;
class CFG;
class CFGBlock;
class ScopeInfo;
class LivenessAnalysis {
public:
bool isLiveAtEnd(const std::string &name, CFGBlock *block);
};
class DefinednessAnalysis {
public:
enum DefinitionLevel {
Undefined,
PotentiallyDefined,
Defined,
};
typedef std::unordered_set<std::string> RequiredSet;
private:
std::unordered_map<CFGBlock*, std::unordered_map<std::string, DefinitionLevel> > results;
std::unordered_map<CFGBlock*, const RequiredSet> defined;
ScopeInfo *scope_info;
public:
DefinednessAnalysis(AST_arguments *args, CFG* cfg, ScopeInfo *scope_info);
DefinitionLevel isDefinedAt(const std::string &name, CFGBlock *block);
const RequiredSet& getDefinedNamesAt(CFGBlock *block);
};
class PhiAnalysis {
public:
typedef std::unordered_set<std::string> RequiredSet;
private:
DefinednessAnalysis definedness;
LivenessAnalysis *liveness;
std::unordered_map<CFGBlock*, const RequiredSet> required_phis;
public:
PhiAnalysis(AST_arguments*, CFG* cfg, LivenessAnalysis *liveness, ScopeInfo *scope_info);
bool isRequired(const std::string &name, CFGBlock* block);
bool isRequiredAfter(const std::string &name, CFGBlock* block);
const RequiredSet& getAllRequiredAfter(CFGBlock *block);
const RequiredSet& getAllDefinedAt(CFGBlock *block);
bool isPotentiallyUndefinedAfter(const std::string &name, CFGBlock* block);
};
LivenessAnalysis* computeLivenessInfo(CFG*);
PhiAnalysis* computeRequiredPhis(AST_arguments*, CFG*, LivenessAnalysis*, ScopeInfo* scope_Info);
}
#endif
This diff is collapsed.
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_ANALYSIS_SCOPINGANALYSIS_H
#define PYSTON_ANALYSIS_SCOPINGANALYSIS_H
#include "core/common.h"
namespace pyston {
class AST_Module;
class ScopeInfo {
public:
virtual ~ScopeInfo() {}
virtual ScopeInfo* getParent() = 0;
virtual bool createsClosure() = 0;
virtual bool takesClosure() = 0;
virtual bool refersToGlobal(const std::string &name) = 0;
virtual bool refersToClosure(const std::string name) = 0;
virtual bool saveInClosure(const std::string name) = 0;
};
class ScopingAnalysis {
public:
struct ScopeNameUsage;
typedef std::unordered_map<AST*, ScopeNameUsage*> NameUsageMap;
private:
std::unordered_map<AST*, ScopeInfo*> scopes;
AST_Module* parent_module;
ScopeInfo* analyzeSubtree(AST* node);
void processNameUsages(NameUsageMap* usages);
public:
ScopingAnalysis(AST_Module *m);
ScopeInfo* getScopeInfoForNode(AST* node);
};
ScopingAnalysis* runScopingAnalysis(AST_Module* m);
}
#endif
This diff is collapsed.
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_ANALYSIS_TYPEANALYSIS_H
#define PYSTON_ANALYSIS_TYPEANALYSIS_H
#include <vector>
#include <unordered_map>
//#include "ast.h"
#include "codegen/compvars.h"
namespace pyston {
class ScopeInfo;
class TypeAnalysis {
public:
enum SpeculationLevel {
NONE,
SOME,
};
virtual ~TypeAnalysis() {}
virtual ConcreteCompilerType* getTypeAtBlockStart(const std::string &name, CFGBlock* block) = 0;
virtual ConcreteCompilerType* getTypeAtBlockEnd(const std::string &name, CFGBlock* block) = 0;
virtual BoxedClass* speculatedExprClass(AST_expr*) = 0;
};
//TypeAnalysis* analyze(CFG *cfg, std::unordered_map<std::string, ConcreteCompilerType*> arg_types);
TypeAnalysis* doTypeAnalysis(CFG *cfg, const std::vector<AST_expr*> &arg_names, const std::vector<ConcreteCompilerType*> &arg_types, TypeAnalysis::SpeculationLevel speculation, ScopeInfo *scope_info);
}
#endif
This diff is collapsed.
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_ASMWRITING_ASSEMBLER_H
#define PYSTON_ASMWRITING_ASSEMBLER_H
#include <unordered_set>
#include "core/ast.h"
#include "asm_writing/types.h"
namespace pyston {
namespace assembler {
class BoxedClass;
enum ConditionCode {
COND_OVERFLOW = 0, // OF=1: O
COND_NOT_OVERFLOW = 1, // OF=0: NO
// next 4 are unsigned:
COND_BELOW = 2, // CF=1: B/NAE/C
COND_NOT_BELOW = 3, // CF=0: NB/AE/C
COND_EQUAL = 4, // ZF=0: Z/E
COND_NOT_EQUAL = 5, // ZF=1: NZ/NE
COND_NOT_ZERO = 5, // ZF=1: NZ/NE
COND_NOT_ABOVE = 6, // CF=1: ZF=1: BE/NA
COND_ABOVE = 7, // CF=0: ZF=0: NBE/A
COND_SIGN = 8, // SF=1: S
COND_NOT_SIGN = 9, // SF=0: NS
COND_PARITY_EVEN = 0xA, // PF=1: P/PE
COND_PARITY_ODD = 0xB, // PF=0: NP/PO
// next 4 are signed:
COND_LESS = 0xC, // SF!=OF: L/NGE
COND_NOT_LESS = 0xD, // SF==OF: NL/GE
COND_NOT_GREATER = 0xE, // ZF=1 || SF!=OF: LE/NG
COND_GREATER = 0xF, // ZF=0 && SF==OF: NLE/G
};
class Assembler {
private:
uint8_t *const start_addr, *const end_addr;
uint8_t *addr;
static const uint8_t OPCODE_ADD = 0b000, OPCODE_SUB = 0b101;
static const uint8_t REX_B = 1, REX_X = 2, REX_R = 4, REX_W = 8;
private:
void emitByte(uint8_t b);
void emitInt(uint64_t n, int bytes);
void emitRex(uint8_t rex);
void emitModRM(uint8_t mod, uint8_t reg, uint8_t rm);
void emitSIB(uint8_t scalebits, uint8_t index, uint8_t base);
void emitArith(Immediate imm, Register reg, int opcode);
public:
Assembler(uint8_t* start, int size) : start_addr(start), end_addr(start + size), addr(start_addr) {}
void nop() { emitByte(0x90); }
void trap() { emitByte(0xcc); }
// some things (such as objdump) call this "movabs" if the immediate is 64-bit
void mov(Immediate imm, Register dest);
// not sure if we should use the 'q' suffix here, but this is the most ambiguous one;
// this does a 64-bit store of a 32-bit value.
void movq(Immediate imm, Indirect dest);
void mov(Register src, Register dest);
void mov(Register src, Indirect dest);
void mov(Indirect src, Register dest);
void movsd(XMMRegister src, XMMRegister dest);
void movsd(XMMRegister src, Indirect dest);
void movsd(Indirect src, XMMRegister dest);
void push(Register reg);
void pop(Register reg);
void add(Immediate imm, Register reg);
void sub(Immediate imm, Register reg);
void inc(Register reg);
void inc(Indirect mem);
void callq(Register reg);
void cmp(Register reg1, Register reg2);
void cmp(Register reg, Immediate imm);
void cmp(Indirect mem, Immediate imm);
void cmp(Indirect mem, Register reg);
void test(Register reg1, Register reg2);
void jmp_cond(JumpDestination dest, ConditionCode condition);
void jmp(JumpDestination dest);
void je(JumpDestination dest);
void jne(JumpDestination dest);
void set_cond(Register reg, ConditionCode condition);
void sete(Register reg);
void setz(Register reg) { sete(reg); }
void setne(Register reg);
void setnz(Register reg) { setne(reg); }
// Macros:
uint8_t* emitCall(void* func_addr, Register scratch);
void emitBatchPop(StackInfo stack_info, const std::vector<GenericRegister> &to_push);
void emitBatchPush(StackInfo stack_info, const std::vector<GenericRegister> &to_push);
void fillWithNops();
void fillWithNopsExcept(int bytes);
void emitAnnotation(int num);
bool isExactlyFull() { return addr == end_addr; }
};
uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uint8_t* end_addr, StackInfo stack_info, const std::unordered_set<int> &live_outs);
}
}
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_ASMWRITING_MCWRITER_H
#define PYSTON_ASMWRITING_MCWRITER_H
#include "core/ast.h"
namespace pyston {
class BoxedClass;
class MCWriter {
public:
virtual ~MCWriter() {}
virtual int numArgRegs() = 0;
virtual int numTempRegs() = 0;
// TODO I don't like this method, could be broken down into simpler things
virtual void emitAlloca(int bytes, int dest_argnum) = 0;
virtual void emitNop() = 0;
virtual void emitTrap() = 0;
virtual void emitAnnotation(int num) = 0;
virtual void endFastPath(void* success_dest, void* will_relocate_to) = 0;
virtual void endWithSlowpath() = 0;
virtual uint8_t* emitCall(void* target, int npushes) = 0;
virtual void emitGuardFalse() = 0;
virtual void emitAttrGuard(int argnum, int offset, int64_t val, int npops) = 0;
virtual void emitGuard(int argnum, int64_t val, int npops) = 0;
virtual void emitGuardNotEq(int argnum, int64_t val, int npops) = 0;
virtual void emitMove(int src_argnum, int dest_argnum, int npushed) = 0;
virtual void emitSetattr(int src_argnum, int dest_argnum, int dest_offset) = 0;
virtual void emitGetattr(int src_argnum, int src_offset, int dest_argnum) = 0;
virtual void emitIncattr(int argnum, int offset) = 0;
virtual void emitPush(int reg) = 0;
virtual void emitPop(int reg) = 0;
virtual void emitLoadConst(int reg, int64_t value) = 0;
virtual void emitCmp(AST_TYPE::AST_TYPE cmp_type, int lhs_argnum, int rhs_argnum, int dest_argnum) = 0;
virtual void emitToBool(int argnum, int dest_argnum) = 0;
};
void initializePatchpoint(uint8_t* addr, int size);
MCWriter* createMCWriter(uint8_t* addr, int size, int num_temp_regs);
}
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_CODEGEN_ENTRY_H
#define PYSTON_CODEGEN_ENTRY_H
namespace pyston {
class AST_Module;
class BoxedModule;
class CompiledFunction;
void initCodegen();
void teardownCodegen();
void printAllIR();
CompiledFunction* compileModule(AST_Module *m, BoxedModule* bm); // hacky but this method is actually defined in irgen.cpp
int joinRuntime();
BoxedModule* createMainModule(const char* fn);
}
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment