Commits

ebo committed 78985d1

Updated for latest python trunk. Worked on support for inlineing.

  • Participants
  • Parent commits 6c0b96d

Comments (0)

Files changed (1)

 # HG changeset patch
-# Parent fba68b5b8c5b5a1baf2d6bbecba138a633db9acf
+# Parent 59223da36dec7b53d3e63d2ed747d9720abbe66a
 
 diff --git a/.hgignore b/.hgignore
 --- a/.hgignore
 new file mode 100644
 --- /dev/null
 +++ b/JIT/global_jit_data.h
-@@ -0,0 +1,171 @@
+@@ -0,0 +1,196 @@
 +// -*- C++ -*-
 +//
 +
 +#include "llvm/PassManager.h"
 +
 +#include <vector>
++#include <set>
 +#include <iostream>
 +
 +namespace llvm {
 +    suspended_ = false;
 +    merge_point_ = false;
 +    trace_.clear();
++    typedef std::set<PyObject*>::iterator iter_t;
++    for(iter_t iter = funcs_.begin(), end = funcs_.end(); iter != end; ++iter) {
++      Py_DECREF(*iter);
++    }
++    funcs_.clear();
 +  }
 +
 +  void suspend()
 +      return;
 +    if (trace_.size() == 0)
 +      return;
++
 +    TraceEntry &entry = trace_.back();
 +    entry.flag = flag;
 +  }
 +
++  void registerFunction(PyObject *func)
++  {
++    if (!active_ || suspended_)
++      return;
++    if (trace_.size() == 0)
++      return;
++
++    TraceEntry &entry = trace_.back();
++    assert(entry.opcode == 131);
++
++    entry.arg0 = (PyTypeObject*)(func);
++    if (funcs_.count(func) == 0) {
++      Py_INCREF(func);
++      funcs_.insert(func);
++    }
++  }
++
 +  void setType(int pos, PyTypeObject* type)
 +  {
 +    if (!active_ || suspended_)
 +  bool merge_point_;
 +
 +  std::vector<TraceEntry> trace_;
++  std::set<PyObject*> funcs_;
 +};
 +
 +struct _JITFunction {
 +using llvm::Type;
 +
 +namespace jit {
-+  JITFunctionBuilder::JITFunctionBuilder(JITFunctionState *state)
++  JITFrameFBuilder::JITFrameFBuilder(JITFunctionState *state)
 +    : state_(state),
 +      builder_(state_->builder()),
 +      context_(state_->context()),
 +  }
 +
 +  void
-+  JITFunctionBuilder::CreateBailBlock()
++  JITFrameFBuilder::CreateBailBlock()
 +  {
 +    this->bail_block_ = this->state_->CreateBasicBlock("bail_block");
 +    this->builder_.SetInsertPoint(this->bail_block_);
 +  }
 +
 +  void
-+  JITFunctionBuilder::SetLastI(int v)
++  JITFrameFBuilder::SetLastI(int v)
 +  {
 +    this->builder_.CreateStore(
 +      ConstantInt::getSigned(Type::getInt32Ty(this->context_), v),
 +  }
 +
 +  void
-+  JITFunctionBuilder::SetBailReason(int v)
++  JITFrameFBuilder::SetBailReason(int v)
 +  {
 +    this->builder_.CreateStore(
 +      ConstantInt::getSigned(Type::getInt32Ty(this->context_), v),
 +  }
 +
 +  void
-+  JITFunctionBuilder::CreateBailBr()
++  JITFrameFBuilder::CreateBailBr()
 +  {
 +    this->builder_.CreateBr(this->bail_block_);
 +  }
 +
 +  void
-+  JITFunctionBuilder::CreateEntryBr()
++  JITFrameFBuilder::CreateEntryBr()
 +  {
 +    this->builder_.CreateBr(this->trace_block_);
 +  }
 +
 +  Value *
-+  JITFunctionBuilder::Pop()
++  JITFrameFBuilder::Pop()
 +  {
 +    Value *stack_pointer = this->builder_.CreateLoad(this->stack_pointer_addr_);
 +    Value *new_stack_pointer = this->builder_.CreateGEP(stack_pointer,
 +  }
 +
 +  void
-+  JITFunctionBuilder::Push(Value *value)
++  JITFrameFBuilder::Push(Value *value)
 +  {
 +    Value *stack_pointer = this->builder_.CreateLoad(this->stack_pointer_addr_);
 +    this->builder_.CreateStore(value, stack_pointer);
 +  }
 +
 +  Value *
-+  JITFunctionBuilder::Top()
++  JITFrameFBuilder::Top()
 +  {
 +    Value *stack_pointer = this->builder_.CreateLoad(this->stack_pointer_addr_);
 +    Value *new_stack_pointer = this->builder_.CreateGEP(stack_pointer,
 +  }
 +
 +  void
-+  JITFunctionBuilder::StoreLocal(int num, llvm::Value *value)
++  JITFrameFBuilder::StoreLocal(int num, llvm::Value *value)
 +  {
 +    Value *ptr = this->LocalPtr(num);
 +    this->builder_.CreateStore(value, ptr);
 +  }
 +
 +  llvm::Value *
-+  JITFunctionBuilder::LoadLocal(int num)
++  JITFrameFBuilder::LoadLocal(int num)
 +  {
 +    Value *ptr = this->LocalPtr(num);
 +    return this->builder_.CreateLoad(ptr);
 +  }
 +
 +  llvm::Value *
-+  JITFunctionBuilder::LocalPtr(int arg)
++  JITFrameFBuilder::LocalPtr(int arg)
 +  {
 +    return this->builder_.CreateGEP(this->fastlocals_,
 +      ConstantInt::getSigned(Type::getInt32Ty(this->context_), arg));
 +  }
 +
 +  llvm::Value *
-+  JITFunctionBuilder::ConstPtr(int arg)
++  JITFrameFBuilder::ConstPtr(int arg)
 +  {
 +    return this->builder_.CreateGEP(this->consts_,
 +      ConstantInt::getSigned(Type::getInt32Ty(this->context_), arg));
 +  }
 +
 +  void
-+  JITFunctionBuilder::OutputInfo(Value *v)
++  JITFrameFBuilder::OutputInfo(Value *v)
 +  {
 +    Function *func = this->state_->GetGlobalFunction<void(PyObject*)>("output_info");
 +    // Value *arg0 = ConstantInt::getSigned(Type::getInt32Ty(this->context_),
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_fbuilder.h
-@@ -0,0 +1,89 @@
+@@ -0,0 +1,117 @@
 +// -*- C++ -*-
 +#ifndef PYTHON_JIT_FBUILDER_H_
 +#define PYTHON_JIT_FBUILDER_H_
 +namespace jit {
 +
 +  class JITFunctionBuilder {
-+    JITFunctionBuilder(const JITFunctionBuilder &);
-+    void operator=(const JITFunctionBuilder &);
-+
 +  public:
-+    JITFunctionBuilder(JITFunctionState *state);
++    virtual JITFunctionState::BuilderT &builder() = 0;
++    virtual JITFunctionState *getState() = 0;
++
++    virtual llvm::Value *Pop() = 0;
++    virtual llvm::Value *Top() = 0;
++    virtual void Push(llvm::Value *value) = 0;
++
++    virtual void StoreLocal(int num, llvm::Value *value) = 0;
++    virtual llvm::Value *LoadLocal(int num) = 0;
++
++    virtual void SetLastI(int v) = 0;
++    virtual void SetBailReason(int v) = 0;
++    virtual void CreateBailBr() = 0;
++    virtual void CreateEntryBr() = 0;
++
++    virtual void OutputInfo(llvm::Value *v) = 0;
++
++    virtual llvm::Value *LocalPtr(int arg) = 0;
++    virtual llvm::Value *ConstPtr(int arg) = 0;
++
++    virtual llvm::Value *getNames() = 0;
++    virtual llvm::Value *getGlobals() = 0;
++    virtual llvm::Value *getBuiltins() = 0;
++
++  };
++
++  class JITFrameFBuilder : public JITFunctionBuilder {
++    JITFrameFBuilder(const JITFrameFBuilder &);
++    void operator=(const JITFrameFBuilder &);
++
++  public:
++    JITFrameFBuilder(JITFunctionState *state);
 +    JITFunctionState::BuilderT &builder()
 +    {
 +      return builder_;
 new file mode 100644
 --- /dev/null
 +++ b/JIT/jit_tracer.cc
-@@ -0,0 +1,986 @@
+@@ -0,0 +1,1018 @@
 +#include "Python.h"
 +#include "opcode.h"
 +
 +
 +PyJITTracer::~PyJITTracer()
 +{
++  typedef std::set<PyObject*>::iterator iter_t;
++  for(iter_t iter = funcs_.begin(), end = funcs_.end(); iter != end; ++iter) {
++    Py_DECREF(*iter);
++  }
++  funcs_.clear();
 +}
 +
 +static bool
 +  void
 +  JITTraceAnalysis::emit(JITFunctionState &state)
 +  {
-+    JITFunctionBuilder builder(&state);
++    JITFrameFBuilder builder(&state);
 +    for (size_t i = 0; i < loaded_stack_.size(); ++i) {
 +      loaded_stack_[i]->emit(builder);
 +    }
 +    int oparg = iter->oparg;
 +    int na = oparg & 0xff;
 +    std::vector<JITValue *> args(na, NULL);
-+    while (--oparg >= 0) {
-+      args[oparg] = stack.Pop();
++    while (--na >= 0) {
++      args[na] = stack.Pop();
 +    }
 +    JITValue *func = stack.Pop();
 +    JITValue *res = this->createCallFunction(func, args, stack, locals);
 +    this->createGuardNull(res, BH_EXC_RAISED, iter->pc, stack, locals);
 +    stack.Push(res);
 +
++//     PyObject *py_func = (PyObject*)(iter->arg0);
++//     std::cout << "EMIT CALL_FUNCTION " << py_func->ob_type->tp_name << "\n";
++
++//     if (PyFunction_Check(py_func)) {
++//       func = NULL;
++//       int na = oparg & 0xff;
++//       int nk = (oparg>>8) & 0xff;
++//       int n = na + 2 * nk;
++
++//       PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(py_func);
++//       PyObject *argdefs = PyFunction_GET_DEFAULTS(py_func);
++
++// #define FLAGS(NAME) " " << #NAME << "=" << (co->co_flags & NAME)
++
++//       std::cout << "PyFunction_Check oparg=" << oparg
++//                 << " na=" << na << " nk=" << nk << " n=" << n
++//                 << " argdefs=" << argdefs << " co->co_argcount=" << co->co_argcount
++//                 << " co_flags=" << co->co_flags
++//                 << FLAGS(CO_OPTIMIZED)
++//                 << FLAGS(CO_NEWLOCALS)
++//                 << FLAGS(CO_NOFREE)
++//                 << FLAGS(CO_NESTED)
++//                 << "\n";
++
++//     }
++
 +    std::vector<TraceEntry>::iterator next = iter + 1;
 +    if (next->opcode == JIT_ENTER_FUNC) {
 +      iter = next;
 +      swallowTrace(iter, end);
 +    }
++
 +  }
 +
 +  void
 diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
 --- a/Lib/test/test_sys.py
 +++ b/Lib/test/test_sys.py
-@@ -701,7 +701,7 @@
+@@ -666,13 +666,13 @@
              return inner
-         check(get_cell().__closure__[0], size(h + 'P'))
+         check(get_cell().__closure__[0], size('P'))
          # code
--        check(get_cell().__code__, size(h + '5i9Pi3P'))
-+        check(get_cell().__code__, size(h + '5i9Pi3PP'))
+-        check(get_cell().__code__, size('5i9Pi3P'))
+-        check(get_cell.__code__, size('5i9Pi3P'))
++        check(get_cell().__code__, size('5i9Pi3PP'))
++        check(get_cell.__code__, size('5i9Pi3PP'))
+         def get_cell2(x):
+             def inner():
+                 return x
+             return inner
+-        check(get_cell2.__code__, size('5i9Pi3P') + 1)
++        check(get_cell2.__code__, size('5i9Pi3PP') + 1)
          # complex
-         check(complex(0,1), size(h + '2d'))
+         check(complex(0,1), size('2d'))
          # method_descriptor (descriptor object)
 diff --git a/Makefile.pre.in b/Makefile.pre.in
 --- a/Makefile.pre.in
  MAINCC=		@MAINCC@
  LINKCC=		@LINKCC@
  AR=		@AR@
-@@ -64,6 +65,7 @@
+@@ -65,6 +66,7 @@
  
  # Compiler options
  OPT=		@OPT@
  BASECFLAGS=	@BASECFLAGS@
  CONFIGURE_CFLAGS=	@CFLAGS@
  CONFIGURE_CPPFLAGS=	@CPPFLAGS@
-@@ -72,10 +74,11 @@
+@@ -73,10 +75,11 @@
  # command line to append to these values without stomping the pre-set
  # values.
  PY_CFLAGS=	$(BASECFLAGS) $(OPT) $(CONFIGURE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS)
  PY_LDFLAGS=	$(CONFIGURE_LDFLAGS) $(LDFLAGS)
  NO_AS_NEEDED=	@NO_AS_NEEDED@
  LDLAST=		@LDLAST@
-@@ -86,7 +89,17 @@
+@@ -87,7 +90,17 @@
  # Extra C flags added for building the interpreter object files.
  CFLAGSFORSHARED=@CFLAGSFORSHARED@
  # C flags used for building the interpreter object files
  
  
  # Machine-dependent subdirectories
-@@ -173,6 +186,7 @@
+@@ -174,6 +187,7 @@
  BLDLIBRARY=     @BLDLIBRARY@
  PY3LIBRARY=     @PY3LIBRARY@
  DLLLIBRARY=	@DLLLIBRARY@
  LDLIBRARYDIR=   @LDLIBRARYDIR@
  INSTSONAME=	@INSTSONAME@
  
-@@ -319,7 +333,7 @@
+@@ -324,7 +338,7 @@
  		Python/asdl.o \
  		Python/ast.o \
  		Python/bltinmodule.o \
  		Python/compile.o \
  		Python/codecs.o \
  		Python/dynamic_annotations.o \
-@@ -362,6 +376,18 @@
+@@ -367,6 +381,18 @@
  		$(MACHDEP_OBJS) \
  		$(THREADOBJ)
  
  
  ##########################################################################
  # Objects
-@@ -457,8 +483,8 @@
+@@ -463,8 +489,8 @@
  
  
  # Build the interpreter
 +	$(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Modules/python.o $(BLDLIBRARY) $(LLVM_LDFLAGS) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
  
  platform: $(BUILDPYTHON) $(SYSCONFIGDATA)
- 	$(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from sysconfig import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform
-@@ -476,33 +502,33 @@
+ 	$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform
+@@ -481,33 +507,33 @@
  
  # Build static library
  # avoid long command lines, same as LIBRARY_OBJS
  
  # Copy up the gdb python hooks into a position where they can be automatically
  # loaded by gdb during Lib/test/test_gdb.py
-@@ -541,7 +567,7 @@
+@@ -546,7 +572,7 @@
  # for a shared core library; otherwise, this rule is a noop.
  $(DLLLIBRARY) libpython$(VERSION).dll.a: $(LIBRARY_OBJS)
  	if test -n "$(DLLLIBRARY)"; then \
  			$(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST); \
  	else true; \
  	fi
-@@ -576,7 +602,7 @@
+@@ -581,7 +607,7 @@
  	fi
  
  Modules/_testembed: Modules/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY)
  
  ############################################################################
  # Importlib
-@@ -615,10 +641,10 @@
+@@ -620,10 +646,10 @@
  		-o $@ $(srcdir)/Modules/getpath.c
  
  Modules/python.o: $(srcdir)/Modules/python.c
  
  Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile
  	$(CC) -c $(PY_CORE_CFLAGS) \
-@@ -708,7 +734,7 @@
+@@ -713,7 +739,7 @@
  $(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES)
  	$(OPCODETARGETGEN) $(OPCODETARGETS_H)
  
  
  Python/formatter_unicode.o: $(srcdir)/Python/formatter_unicode.c \
  				$(BYTESTR_DEPS)
-@@ -806,11 +832,33 @@
+@@ -811,11 +837,33 @@
  		$(srcdir)/Include/unicodeobject.h \
  		$(srcdir)/Include/warnings.h \
  		$(srcdir)/Include/weakrefobject.h \
  
  ######################################################################
  
-@@ -1153,6 +1201,7 @@
+@@ -1158,6 +1206,7 @@
  			echo Skip install of $(LIBRARY) - use make frameworkinstall; \
  		fi; \
  	fi
  	$(INSTALL_DATA) Modules/config.c $(DESTDIR)$(LIBPL)/config.c
  	$(INSTALL_DATA) Modules/python.o $(DESTDIR)$(LIBPL)/python.o
  	$(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in
-@@ -1276,6 +1325,16 @@
+@@ -1284,6 +1333,16 @@
  .c.o:
  	$(CC) -c $(PY_CORE_CFLAGS) -o $@ $<
  
  # Run reindent on the library
  reindent:
  	./$(BUILDPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
-@@ -1332,6 +1391,8 @@
+@@ -1340,6 +1399,8 @@
  	find . -name '*.so.[0-9]*.[0-9]*' -exec rm -f {} ';'
  	find build -name 'fficonfig.h' -exec rm -f {} ';' || true
  	find build -name 'fficonfig.py' -exec rm -f {} ';' || true
      return co;
  }
  
-@@ -219,6 +220,15 @@
+@@ -219,6 +220,9 @@
      {NULL}      /* Sentinel */
  };
  
 +PyObject* code_has_jit(PyCodeObject *self);
 +PyObject* code_dump_jit(PyCodeObject *self);
 +
-+static PyMethodDef code_methods[] = {
-+    {"_has_jit", (PyCFunction)code_has_jit, METH_NOARGS},
-+    {"_dump_jit", (PyCFunction)code_dump_jit, METH_NOARGS},
-+    {NULL,              NULL}           /* sentinel */
-+};
-+
  /* Helper for code_new: return a shallow copy of a tuple that is
     guaranteed to contain exact strings, by converting string subclasses
     to exact strings and complaining if a non-string is found. */
-@@ -371,6 +381,8 @@
+@@ -371,6 +375,8 @@
          PyObject_GC_Del(co->co_zombieframe);
      if (co->co_weakreflist != NULL)
          PyObject_ClearWeakRefs((PyObject*)co);
      PyObject_DEL(co);
  }
  
-@@ -508,7 +520,7 @@
-     offsetof(PyCodeObject, co_weakreflist),     /* tp_weaklistoffset */
-     0,                                  /* tp_iter */
-     0,                                  /* tp_iternext */
--    0,                                  /* tp_methods */
-+    code_methods,                       /* tp_methods */
-     code_memberlist,                    /* tp_members */
-     0,                                  /* tp_getset */
-     0,                                  /* tp_base */
+@@ -493,6 +499,8 @@
+ 
+ static struct PyMethodDef code_methods[] = {
+     {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
++    {"_has_jit", (PyCFunction)code_has_jit, METH_NOARGS},
++    {"_dump_jit", (PyCFunction)code_dump_jit, METH_NOARGS},
+     {NULL, NULL}                /* sentinel */
+ };
+ 
 diff --git a/Objects/floatobject.c b/Objects/floatobject.c
 --- a/Objects/floatobject.c
 +++ b/Objects/floatobject.c
      PyObject *func = *pfunc;
      PyObject *x, *w;
 +    PyJITTracer *trace = PyJITTracer_GET();
-+    trace->setType(0, func->ob_type);
++    trace->registerFunction(func);
  
      /* Always dispatch PyCFunction first, because these are
         presumed to be the most frequent callable object.
 diff --git a/configure b/configure
 --- a/configure
 +++ b/configure
-@@ -657,6 +657,7 @@
+@@ -637,6 +637,7 @@
  OTHER_LIBTOOL_OPT
  UNIVERSAL_ARCH_FLAGS
  BASECFLAGS
  OPT
  ABIFLAGS
  LN
-@@ -670,6 +671,7 @@
+@@ -653,6 +654,7 @@
  AR
  RANLIB
  USE_INLINE
  GNULD
  LINKCC
  LDVERSION
-@@ -695,6 +697,13 @@
+@@ -679,6 +681,13 @@
  LDFLAGS
  CFLAGS
  CC
  EXPORT_MACOSX_DEPLOYMENT_TARGET
  CONFIGURE_MACOSX_DEPLOYMENT_TARGET
  SGI_ABI
-@@ -774,6 +783,7 @@
+@@ -760,6 +769,7 @@
  with_framework_name
  enable_framework
  with_gcc
  with_cxx_main
  with_suffix
  enable_shared
-@@ -802,6 +812,7 @@
+@@ -788,6 +798,7 @@
        ac_precious_vars='build_alias
  host_alias
  target_alias
  CC
  CFLAGS
  LDFLAGS
-@@ -1444,6 +1455,11 @@
+@@ -1432,6 +1443,11 @@
                            specify an alternate name of the framework built
                            with --enable-framework
    --without-gcc           never use gcc
    --with-cxx-main=<compiler>
                            compile main() and link python executable with C++
                            compiler
-@@ -1476,6 +1492,7 @@
+@@ -1464,6 +1480,7 @@
                            default on supported compilers)
  
  Some influential environment variables:
    CC          C compiler command
    CFLAGS      C compiler flags
    LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-@@ -3416,6 +3433,239 @@
+@@ -3442,6 +3459,239 @@
  (it is also a good idea to do 'make clean' before compiling)" "$LINENO" 5
  fi
  
  # Don't let AC_PROG_CC set the default CFLAGS. It normally sets -g -O2
  # when the compiler supports them, but we don't always want -O2, and
  # we set -g later.
-@@ -4295,14 +4545,26 @@
+@@ -4322,14 +4572,26 @@
  	esac
  else
  
  preset_cxx="$CXX"
  if test -z "$CXX"
  then
-@@ -5145,6 +5407,12 @@
+@@ -5400,6 +5662,12 @@
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNULD" >&5
  $as_echo "$GNULD" >&6; }
  
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
  $as_echo_n "checking for inline... " >&6; }
  if ${ac_cv_c_inline+:} false; then :
-@@ -5726,6 +5994,7 @@
+@@ -6149,6 +6417,7 @@
  # tweak OPT based on compiler and platform, only if the user didn't set
  # it on the command line
  
  if test "${OPT-unset}" = "unset"
  then
      case $GCC in
-@@ -5750,22 +6019,28 @@
+@@ -6173,22 +6442,28 @@
  		# Optimization messes up debuggers, so turn it off for
  		# debug builds.
  		OPT="-g -O0 -Wall $STRICT_PROTO"
  	;;
      esac
  fi
-@@ -14425,7 +14700,7 @@
+@@ -14897,7 +15172,7 @@
  done
  
  
 diff --git a/configure.ac b/configure.ac
 --- a/configure.ac
 +++ b/configure.ac
-@@ -514,6 +514,75 @@
+@@ -558,6 +558,75 @@
  (it is also a good idea to do 'make clean' before compiling)])
  fi
  
  # Don't let AC_PROG_CC set the default CFLAGS. It normally sets -g -O2
  # when the compiler supports them, but we don't always want -O2, and
  # we set -g later.
-@@ -599,11 +668,23 @@
+@@ -643,11 +712,23 @@
  			CXX=$withval
  		fi;;
  	esac], [
  preset_cxx="$CXX"
  if test -z "$CXX"
  then
-@@ -789,6 +870,12 @@
+@@ -833,6 +914,12 @@
  esac
  AC_MSG_RESULT($GNULD)
  
  AC_C_INLINE
  if test "$ac_cv_c_inline" != no ; then
          AC_DEFINE(USE_INLINE, 1, [Define to use the C99 inline keyword.])
-@@ -990,6 +1077,7 @@
+@@ -1049,6 +1136,7 @@
  # tweak OPT based on compiler and platform, only if the user didn't set
  # it on the command line
  AC_SUBST(OPT)
  if test "${OPT-unset}" = "unset"
  then
      case $GCC in
-@@ -1014,22 +1102,28 @@
+@@ -1073,22 +1161,28 @@
  		# Optimization messes up debuggers, so turn it off for
  		# debug builds.
  		OPT="-g -O0 -Wall $STRICT_PROTO"
  	;;
      esac
  fi
-@@ -4429,7 +4523,7 @@
+@@ -4504,7 +4598,7 @@
  done
  
  AC_SUBST(SRCDIRS)
 diff --git a/setup.py b/setup.py
 --- a/setup.py
 +++ b/setup.py
-@@ -673,6 +673,8 @@
+@@ -729,6 +729,8 @@
          # CSV files
          exts.append( Extension('_csv', ['_csv.c']) )