[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A possible code generation issue



On 4 July 2015 at 23:09, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote:
> On 4 July 2015 at 22:41, David Malcolm <dmalcolm@redhat.com> wrote:
>>> Adding the -fno-strict-aliasing appears to resolve the issue with -O2
>>> and -O3 but with this enabled the benchmarks are degraded.
>>
>> If "-fno-strict-aliasing" resolved this, then that suggests that there
>> are various casts in the code that if this were C would take us into
>> "undefined behavior" territory, and the optimizer is trying a little too
>> hard.   This isn't C, but similar rules apply.  If that's what this is,
>> then this is at least a documentation issue with libgccjit; we need to
>> document what the rules are.
>>
>>
>> Of course, it could well be a bug at my end.
>>

Dave,

Attached is a hacked version in C of the dump from the code. I thought
it might be useful to generate code directly using gcc -O3 -S on this
file - from what I can tell the generated code looks different from
what I am getting in libgccjit.

BTW the dump of types is problematic in many ways:
1) types are in wrong order
2) function types are incorrectly output
3) array types are incorrectly output
4) in one case as least a pointer was missing.

It would be useful if the generated dump was correct C so that it can
directly compiled in gcc.

Thanks and Regards
Dibyendu
#include <stdbool.h>
#include <stdlib.h>

struct ravi_lua_State;

struct ravi_lua_Debug;

struct ravi_GCObject;

union ravi_Value;

struct ravi_TValue;

struct ravi_TString;

struct ravi_Table;

struct ravi_Udata;

struct ravi_Upvaldesc;

struct ravi_LocVar;

struct ravi_LClosure;

struct ravi_RaviJITProto;

struct ravi_Proto;

struct ravi_UpVal;

struct ravi_CClosure;

union ravi_Closure;

struct ravi_TKey_nk;

union ravi_TKey;

struct ravi_Node;

struct ravi_RaviArray;

struct ravi_lua_longjmp;

struct ravi_Mbuffer;

struct ravi_stringtable;

struct ravi_CallInfo;

struct ravi_CallInfo_lua;

struct ravi_CallInfo_C;

union ravi_CallInfo_u;

struct ravi_State;

struct ravi_global_State;

struct ravi_UpVal_u_open;

union ravi_UpVal_u;

struct ravi_GCObject
{
  struct ravi_GCObject * next;
  unsigned char tt;
  unsigned char marked;
};

union ravi_Value
{
  struct ravi_GCObject * gc;
  void * p;
  int b;
  int (*f) (struct ravi_lua_State *);
  long long i;
  double n;
};

struct ravi_TValue
{
  union ravi_Value value_;
  int tt_;
};

struct ravi_TString
{
  struct ravi_GCObject * next;
  unsigned char tt;
  unsigned char marked;
  unsigned char extra;
  unsigned int hash;
  size_t len;
  struct ravi_TString * hash_next;
};

struct ravi_RaviArray
{
  void * data;
  unsigned int len;
  unsigned int size;
  unsigned char array_type;
  unsigned char array_modifier;
};

struct ravi_Table
{
  struct ravi_GCObject * next;
  unsigned char tt;
  unsigned char marked;
  unsigned char flags;
  unsigned char lsizenode;
  unsigned int sizearray;
  struct ravi_TValue * array;
  struct ravi_Node * node;
  struct ravi_Node * lastfree;
  struct ravi_Table * metatable;
  struct ravi_GCObject * gclist;
  struct ravi_RaviArray ravi_array;
};

struct ravi_Udata
{
  struct ravi_GCObject * next;
  unsigned char tt;
  unsigned char marked;
  unsigned char ttuv_;
  struct ravi_Table * metatable;
  size_t len;
  union ravi_Value user_;
};

struct ravi_Upvaldesc
{
  struct ravi_TString * name;
  int type;
  unsigned char instack;
  unsigned char idx;
};

struct ravi_LocVar
{
  struct ravi_TString * varname;
  int startpc;
  int endpc;
  int ravi_type;
};

struct ravi_LClosure
{
  struct ravi_GCObject * next;
  unsigned char tt;
  unsigned char marked;
  unsigned char nupvalues;
  struct ravi_GCObject * gclist;
  struct ravi_Proto * p;
  struct ravi_UpVal *upvals[1];
};

struct ravi_RaviJITProto
{
  unsigned char jit_status;
  unsigned char jit_flags;
  unsigned short execution_count;
  void * jit_data;
  int (* jit_function) (struct ravi_lua_State *);
};

struct ravi_Proto
{
  struct ravi_GCObject * next;
  unsigned char tt;
  unsigned char marked;
  unsigned char numparams;
  unsigned char is_vararg;
  unsigned char maxstacksize;
  int sizeupvalues;
  int sizek;
  int sizecode;
  int sizelineinfo;
  int sizep;
  int sizelocvars;
  int linedefined;
  int lastlinedefined;
  struct ravi_TValue * k;
  unsigned int * code;
  struct ravi_Proto * * p;
  int * lineinfo;
  struct ravi_LocVar * locvars;
  struct ravi_Upvaldesc * upvalues;
  struct ravi_LClosure * cache;
  struct ravi_TString * source;
  struct ravi_GCObject * gclist;
  struct ravi_RaviJITProto ravi_jit;
};

struct ravi_TKey_nk
{
  union ravi_Value value_;
  int tt_;
  int next;
};

union ravi_TKey
{
  struct ravi_TKey_nk nk;
  struct ravi_TValue tvk;
};

struct ravi_Node
{
  struct ravi_TValue i_val;
  union ravi_TKey i_key;
};

struct ravi_Mbuffer
{
  char * buffer;
  size_t n;
  size_t buffsize;
};

struct ravi_stringtable
{
  struct ravi_TString * * hash;
  int nuse;
  int size;
};

struct ravi_CallInfo_lua
{
  struct ravi_TValue * base;
  unsigned int * savedpc;
};

struct ravi_CallInfo_C
{
  int (*k) (struct ravi_lua_State *, int, long long);
  long long old_errfunc;
  long long ctx;
};

union ravi_CallInfo_u
{
  struct ravi_CallInfo_lua l;
  struct ravi_CallInfo_C c;
};

struct ravi_CClosure
{
  struct ravi_GCObject * next;
  unsigned char tt;
  unsigned char marked;
  unsigned char nupvalues;
  struct ravi_GCObject * gclist;
  int (*f) (struct ravi_lua_State *);
  struct ravi_TValue upvalue[1];
};

union ravi_Closure
{
  struct ravi_CClosure c;
  struct ravi_LClosure l;
};


struct ravi_CallInfo
{
  struct ravi_TValue * func;
  struct ravi_TValue * top;
  struct ravi_CallInfo * previous;
  struct ravi_CallInfo * next;
  union ravi_CallInfo_u u;
  long long extra;
  short nresults;
  unsigned char callstatus;
};

struct ravi_lua_State
{
  struct ravi_GCObject * next;
  unsigned char tt;
  unsigned char marked;
  unsigned char status;
  struct ravi_TValue * top;
  struct ravi_global_State * l_G;
  struct ravi_CallInfo * ci;
  unsigned int * oldpc;
  struct ravi_TValue * stack_last;
  struct ravi_TValue * stack;
  struct ravi_UpVal * openupval;
  struct ravi_GCObject * gclist;
  struct ravi_lua_State * twups;
  struct ravi_lua_longjmp * errorJmp;
  struct ravi_CallInfo base_ci;
  void * (*hook) (struct ravi_lua_State *, struct ravi_lua_Debug *);
  long long errfunc;
  int stacksize;
  int basehookcount;
  int hookcount;
  unsigned short nny;
  unsigned short nCcalls;
  unsigned char hookmask;
  unsigned char allowhook;
};



struct ravi_UpVal_u_open
{
  struct ravi_UpVal * next;
  int touched;
};

union ravi_UpVal_u
{
  struct ravi_UpVal_u_open open;
  struct ravi_TValue value;
};

struct ravi_UpVal
{
  struct ravi_TValue * v;
  size_t refcount;
  union ravi_UpVal_u u;
};



extern int
luaD_poscall (struct ravi_lua_State * L, struct ravi_TValue * firstResult); /* (imported) */

extern void
luaC_upvalbarrier_ (struct ravi_lua_State * L, struct ravi_UpVal * uv); /* (imported) */

extern int
luaD_precall (struct ravi_lua_State * L, struct ravi_TValue * func, int nresults); /* (imported) */

extern int
luaD_call (struct ravi_lua_State * L, struct ravi_TValue * func, int nresults, int allowyield); /* (imported) */

extern void
luaV_execute (struct ravi_lua_State * L); /* (imported) */

extern void
luaF_close (struct ravi_lua_State * L, struct ravi_TValue * level); /* (imported) */

extern int
luaV_equalobj (struct ravi_lua_State * L, const struct ravi_TValue * t1, const struct ravi_TValue * t2); /* (imported) */

extern int
luaV_lessthan (struct ravi_lua_State * L, const struct ravi_TValue * l, const struct ravi_TValue * r); /* (imported) */

extern int
luaV_lessequal (struct ravi_lua_State * L, const struct ravi_TValue * l, const struct ravi_TValue * r); /* (imported) */

extern void
luaG_runerror (struct ravi_lua_State * L, const char * fmt); /* (imported) */

extern int
luaV_forlimit (struct ravi_TValue * obj, long long * p, long long step, int * stopnow); /* (imported) */

extern int
luaV_tonumber_ (const struct ravi_TValue * obj, double * n); /* (imported) */

extern int
luaV_tointeger_ (const struct ravi_TValue * obj, long long * p); /* (imported) */

extern void
luaV_objlen (struct ravi_lua_State * L, struct ravi_TValue * ra, const struct ravi_TValue * rb); /* (imported) */

extern void
luaV_gettable (struct ravi_lua_State * L, const struct ravi_TValue * t, struct ravi_TValue * key, struct ravi_TValue * val); /* (imported) */

extern void
luaV_settable (struct ravi_lua_State * L, const struct ravi_TValue * t, struct ravi_TValue * key, struct ravi_TValue * val); /* (imported) */

extern void
luaT_trybinTM (struct ravi_lua_State * L, const struct ravi_TValue * p1, const struct ravi_TValue * p2, struct ravi_TValue * res, int event); /* (imported) */

extern void
raviV_op_loadnil (struct ravi_CallInfo * ci, int a, int b); /* (imported) */

extern void
raviV_op_newarrayint (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_TValue * ra); /* (imported) */

extern void
raviV_op_newarrayfloat (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_TValue * ra); /* (imported) */

extern void
raviV_op_newtable (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_TValue * ra, int b, int c); /* (imported) */

extern void
raviV_op_setlist (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_TValue * ra, int b, int c); /* (imported) */

extern long long
luaV_div (struct ravi_lua_State * L, long long m, long long n); /* (imported) */

extern long long
luaV_mod (struct ravi_lua_State * L, long long m, long long n); /* (imported) */

extern void
raviV_op_concat (struct ravi_lua_State * L, struct ravi_CallInfo * ci, int a, int b, int c); /* (imported) */

extern void
raviV_op_closure (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_LClosure * cl, int a, int Bx); /* (imported) */

extern void
raviV_op_vararg (struct ravi_lua_State * L, struct ravi_CallInfo * ci, struct ravi_LClosure * cl, int a, int b); /* (imported) */

extern void
raviH_set_int (struct ravi_lua_State * L, struct ravi_Table * table, unsigned int key, long long value); /* (imported) */

extern void
raviH_set_float (struct ravi_lua_State * L, struct ravi_Table * table, unsigned int key, double value); /* (imported) */

extern void
raviV_op_setupval (struct ravi_lua_State * L, struct ravi_LClosure * cl, struct ravi_TValue * ra, int b); /* (imported) */

//extern int
//printf (const char * format); /* (imported) */

extern int
ravif1 (struct ravi_lua_State * L)
{
  struct ravi_LClosure * cl;
  bool isfalse_0_4;
  bool comparison_0_5;
  bool comparison_0_6;
  bool comparison_0_7;
  bool isfalse_0_10;
  bool comparison_0_11;
  bool comparison_0_12;
  bool comparison_0_13;
  bool isfalse_0_16;
  bool comparison_0_17;
  bool comparison_0_18;
  bool comparison_0_19;
  bool comparison_0_22;
  bool comparison_0_26;

entry:
  cl = (struct ravi_LClosure *)L->ci->func->value_.gc;
  (void)raviV_op_loadnil (L->ci, (int)0, (int)0);
  (&L->ci->u.l.base[(int)1])->value_.i = (&cl->p->k[(int)0])->value_.i;
  (&L->ci->u.l.base[(int)1])->tt_ = (&cl->p->k[(int)0])->tt_;
  comparison_0_5 = (&L->ci->u.l.base[(int)1])->tt_ == (int)0;
  comparison_0_6 = (&L->ci->u.l.base[(int)1])->tt_ == (int)1;
  comparison_0_7 = (&L->ci->u.l.base[(int)1])->value_.b == (int)0;
  isfalse_0_4 = comparison_0_5 || comparison_0_6 && comparison_0_7;
  if (!(isfalse_0_4)) goto OP_TEST_do_jmp_2_8; else goto OP_TEST_do_skip_2_9;

jmp_5_1:
  (&L->ci->u.l.base[(int)1])->value_.b = (int)0;
  (&L->ci->u.l.base[(int)1])->tt_ = (int)1;
  comparison_0_11 = (&L->ci->u.l.base[(int)1])->tt_ == (int)0;
  comparison_0_12 = (&L->ci->u.l.base[(int)1])->tt_ == (int)1;
  comparison_0_13 = (&L->ci->u.l.base[(int)1])->value_.b == (int)0;
  isfalse_0_10 = comparison_0_11 || comparison_0_12 && comparison_0_13;
  if (!(!(isfalse_0_10))) goto OP_TEST_do_jmp_5_14; else goto OP_TEST_do_skip_5_15;

jmp_9_2:
  (&L->ci->u.l.base[(int)1])->value_.i = (&cl->p->k[(int)0])->value_.i;
  (&L->ci->u.l.base[(int)1])->tt_ = (&cl->p->k[(int)0])->tt_;
  comparison_0_17 = (&L->ci->u.l.base[(int)1])->tt_ == (int)0;
  comparison_0_18 = (&L->ci->u.l.base[(int)1])->tt_ == (int)1;
  comparison_0_19 = (&L->ci->u.l.base[(int)1])->value_.b == (int)0;
  isfalse_0_16 = comparison_0_17 || comparison_0_18 && comparison_0_19;
  if (!(isfalse_0_16)) goto OP_TEST_do_jmp_9_20; else goto OP_TEST_do_skip_9_21;

jmp_12_3:
  (&L->ci->u.l.base[(int)1])->value_.b = (int)0;
  (&L->ci->u.l.base[(int)1])->tt_ = (int)1;
  L->top = &L->ci->u.l.base[(int)2];
  comparison_0_22 = cl->p->sizep > (int)0;
  if (comparison_0_22) goto OP_RETURN_if_sizep_gt_0_12_23; else goto OP_RETURN_else_sizep_gt_0_12_24;

OP_TEST_do_jmp_2_8:
  goto jmp_5_1;

OP_TEST_do_skip_2_9:
  goto jmp_5_1;

OP_TEST_do_jmp_5_14:
  goto jmp_9_2;

OP_TEST_do_skip_5_15:
  (&L->ci->u.l.base[(int)0])->value_.b = (int)1;
  (&L->ci->u.l.base[(int)0])->tt_ = (int)1;
  goto jmp_9_2;

OP_TEST_do_jmp_9_20:
  goto jmp_12_3;

OP_TEST_do_skip_9_21:
  goto jmp_12_3;

OP_RETURN_if_sizep_gt_0_12_23:
  (void)luaF_close (L, L->ci->u.l.base);
  goto OP_RETURN_else_sizep_gt_0_12_24;

OP_RETURN_else_sizep_gt_0_12_24:
  (void)luaD_poscall (L, (&L->ci->u.l.base[(int)1]));
  return (int)1;

LINK_BLOCK_13_25:
  L->top = &L->ci->u.l.base[(int)0];
  comparison_0_26 = cl->p->sizep > (int)0;
  if (comparison_0_26) goto OP_RETURN_if_sizep_gt_0_13_27; else goto OP_RETURN_else_sizep_gt_0_13_28;

OP_RETURN_if_sizep_gt_0_13_27:
  (void)luaF_close (L, L->ci->u.l.base);
  goto OP_RETURN_else_sizep_gt_0_13_28;

OP_RETURN_else_sizep_gt_0_13_28:
  (void)luaD_poscall (L, (&L->ci->u.l.base[(int)0]));
  return (int)1;
}

Attachment: bug.s
Description: Binary data