Browse Source

* optimized a_loadaddr_ref_reg() in cases where an offset is added to a
symbol or base register and the offset is a multiple of the def's size

git-svn-id: branches/hlcgllvm@27007 -

Jonas Maebe 11 năm trước cách đây
mục cha
commit
abee66b611
1 tập tin đã thay đổi với 17 bổ sung1 xóa
  1. 17 1
      compiler/llvm/hlcgllvm.pas

+ 17 - 1
compiler/llvm/hlcgllvm.pas

@@ -915,6 +915,7 @@ implementation
 
   function thlcgllvm.make_simple_ref(list: TAsmList; const ref: treference; def: tdef): treference;
     var
+      ptrindex: tcgint;
       hreg1,
       hreg2: tregister;
       tmpref: treference;
@@ -928,6 +929,22 @@ implementation
           result:=ref;
           exit;
         end;
+
+      hreg2:=getaddressregister(list,getpointerdef(def));
+      { symbol+offset or base+offset with offset a multiple of the size ->
+        use getelementptr }
+      if (ref.index=NR_NO) and
+         (ref.offset mod def.size=0) then
+        begin
+          ptrindex:=ref.offset div def.size;
+          if assigned(ref.symbol) then
+            reference_reset_symbol(tmpref,ref.symbol,0,ref.alignment)
+          else
+            reference_reset_base(tmpref,ref.base,0,ref.alignment);
+          list.concat(taillvm.getelementptr_reg_size_ref_size_const(hreg2,getpointerdef(def),tmpref,ptruinttype,ptrindex,assigned(ref.symbol)));
+          reference_reset_base(result,hreg2,0,ref.alignment);
+          exit;
+        end;
       { for now, perform all calculations using plain pointer arithmetic. Later
         we can look into optimizations based on getelementptr for structured
         accesses (if only to prevent running out of virtual registers).
@@ -963,7 +980,6 @@ implementation
           a_op_const_reg_reg(list,OP_ADD,ptruinttype,ref.offset,hreg1,hreg2);
           hreg1:=hreg2;
         end;
-      hreg2:=getaddressregister(list,getpointerdef(def));
       a_load_reg_reg(list,ptruinttype,getpointerdef(def),hreg1,hreg2);
       reference_reset_base(result,hreg2,0,ref.alignment);
     end;