I'm beginning to implement structs in my ARM Cortex-M runtime, and I ran across something interesting today.

Consider this struct:
struct TestStruct
{
    uint TestVar;

    void Print()
    {
        trace.WriteLine("TestStruct.Print");
    }
}

And a function that uses that struct:
void MyFunction()
{
    TestStruct test;
    test.Print()
}

Adding this function call created a unresolved reference to _d_assert_msg. When I look at the code generations I see this:
 start.TestStruct.Print (struct start.TestStruct & this)
{
  struct  D.3650;
  const struct  t;
  struct  D.3627;
  struct  D.3626;

  <bb 2>:
  if (this_1(D) != 0)
    goto <bb 4>;
  else
    goto <bb 3>;

  <bb 3>:
  D.3626.length = 9;
  D.3626.ptr = "null this";
  D.3627.length = 14;
  D.3627.ptr = "source/start.d";
  _d_assert_msg (D.3626, D.3627, 26);

  <bb 4>:
  MEM[(struct  *)&t] = 16;
  MEM[(struct  *)&t + 4B] = "TestStruct.Print";
  Write (t);
  t ={v} {CLOBBER};
  D.3650.length = 2;
  D.3650.ptr = "\r\n";
  Write (D.3650);
  return;

}

What bothers me is the branch at <bb 2>. It looks like it's checking the struct instance to see if it is null. Is it even possible for it to be null? Can this be improved?

I imagine in a tight loop (for example, an alpha blend function on an array of pixels), this can be a significant performance hindrance if every call has to make this check.

I'd be happy to submit a bug report if you think this has merit.

Mike

Reply via email to