Browse Source

* emit temp lifetime information for llvm
o also allow freeing temps in the middle of a routine for llvm (we won't
reuse them, but it results in better lifetime information)

git-svn-id: trunk@40502 -

Jonas Maebe 6 years ago
parent
commit
51502874af
2 changed files with 47 additions and 7 deletions
  1. 39 5
      compiler/llvm/tgllvm.pas
  2. 8 2
      compiler/tgobj.pas

+ 39 - 5
compiler/llvm/tgllvm.pas

@@ -57,6 +57,9 @@ unit tgllvm;
        protected
        protected
         procedure alloctemp(list: TAsmList; size: asizeint; alignment: shortint; temptype: ttemptype; def: tdef; fini: boolean; out ref: treference); override;
         procedure alloctemp(list: TAsmList; size: asizeint; alignment: shortint; temptype: ttemptype; def: tdef; fini: boolean; out ref: treference); override;
         procedure gethltempintern(list: TAsmList; def: tdef; alignment: shortint; forcesize: asizeint; temptype: ttemptype; out ref: treference);
         procedure gethltempintern(list: TAsmList; def: tdef; alignment: shortint; forcesize: asizeint; temptype: ttemptype; out ref: treference);
+        procedure freetemphook(list: TAsmList; temp: ptemprecord); override;
+
+        procedure emit_lifetime(list: TAsmList; const procname: string; temp: ptemprecord);
        public
        public
         alloclist: tasmlist;
         alloclist: tasmlist;
 
 
@@ -79,8 +82,8 @@ implementation
        systems,verbose,
        systems,verbose,
        procinfo,
        procinfo,
        llvmbase,aasmllvm,
        llvmbase,aasmllvm,
-       symconst,symdef,
-       cgobj
+       symconst,symtable,symdef,defutil,
+       paramgr,parabase,cgobj,hlcgobj
        ;
        ;
 
 
 
 
@@ -106,8 +109,8 @@ implementation
         templist:=tl;
         templist:=tl;
         temp_to_ref(tl,ref);
         temp_to_ref(tl,ref);
         list.concat(tai_tempalloc.alloc(tl^.pos,tl^.size));
         list.concat(tai_tempalloc.alloc(tl^.pos,tl^.size));
-        { TODO: add llvm.lifetime.start() for this allocation and afterwards
-            llvm.lifetime.end() for freetemp (if the llvm version supports it) }
+
+        emit_lifetime(list,'llvm_lifetime_start',tl);
         inc(lasttemp);
         inc(lasttemp);
         { allocation for the temp -- should have lineinfo of the start of the
         { allocation for the temp -- should have lineinfo of the start of the
           routine }
           routine }
@@ -136,6 +139,37 @@ implementation
       end;
       end;
 
 
 
 
+    procedure ttgllvm.freetemphook(list: TAsmList; temp: ptemprecord);
+      begin
+        inherited;
+        emit_lifetime(list,'llvm_lifetime_end',temp);
+      end;
+
+
+    procedure ttgllvm.emit_lifetime(list: TAsmList; const procname: string; temp: ptemprecord);
+      var
+        sizepara, ptrpara: tcgpara;
+        pd: tprocdef;
+        ref: treference;
+      begin
+        if (temp^.size<>0) and
+           not is_managed_type(temp^.def) then
+          begin
+            temp_to_ref(temp,ref);
+            sizepara.init;
+            ptrpara.init;
+            pd:=search_system_proc(procname);
+            paramanager.getintparaloc(list,pd,1,sizepara);
+            paramanager.getintparaloc(list,pd,2,ptrpara);
+            hlcg.a_load_const_cgpara(list,sizepara.def,temp^.size,sizepara);
+            hlcg.a_loadaddr_ref_cgpara(list,temp^.def,ref,ptrpara);
+            hlcg.g_call_system_proc(list,pd,[@sizepara,@ptrpara],nil).resetiftemp;
+            sizepara.reset;
+            ptrpara.reset;
+          end;
+      end;
+
+
     procedure ttgllvm.temp_to_ref(p: ptemprecord; out ref: treference);
     procedure ttgllvm.temp_to_ref(p: ptemprecord; out ref: treference);
       var
       var
         temppos: treftemppos;
         temppos: treftemppos;
@@ -178,7 +212,7 @@ implementation
 
 
     procedure ttgllvm.gethltemp(list: TAsmList; def: tdef; forcesize: asizeint; temptype: ttemptype; out ref: treference);
     procedure ttgllvm.gethltemp(list: TAsmList; def: tdef; forcesize: asizeint; temptype: ttemptype; out ref: treference);
       begin
       begin
-        gethltempintern(list,def,def.alignment,forcesize,tt_persistent,ref);
+        gethltempintern(list,def,def.alignment,forcesize,temptype,ref);
       end;
       end;
 
 
 
 

+ 8 - 2
compiler/tgobj.pas

@@ -64,6 +64,7 @@ unit tgobj;
           procedure alloctemp(list: TAsmList; size: asizeint; alignment: shortint; temptype: ttemptype; def: tdef; fini: boolean; out ref: treference); virtual;
           procedure alloctemp(list: TAsmList; size: asizeint; alignment: shortint; temptype: ttemptype; def: tdef; fini: boolean; out ref: treference); virtual;
           procedure freetemp(list: TAsmList; pos: treftemppos; temptypes: ttemptypeset);virtual;
           procedure freetemp(list: TAsmList; pos: treftemppos; temptypes: ttemptypeset);virtual;
           procedure gettempinternal(list: TAsmList; size: asizeint; alignment: shortint; temptype: ttemptype; def: tdef; fini: boolean; out ref : treference);
           procedure gettempinternal(list: TAsmList; size: asizeint; alignment: shortint; temptype: ttemptype; def: tdef; fini: boolean; out ref : treference);
+          procedure freetemphook(list: TAsmList; temp: ptemprecord); virtual;
        public
        public
           { contains all temps }
           { contains all temps }
           templist      : ptemprecord;
           templist      : ptemprecord;
@@ -502,7 +503,7 @@ implementation
 {$endif}
 {$endif}
                   exit;
                   exit;
                 end;
                 end;
-               list.concat(tai_tempalloc.dealloc(hp^.pos,hp^.size));
+               freetemphook(list,hp);
                { set this block to free }
                { set this block to free }
                hp^.temptype:=Used2Free[hp^.temptype];
                hp^.temptype:=Used2Free[hp^.temptype];
                { Update tempfreelist }
                { Update tempfreelist }
@@ -573,7 +574,6 @@ implementation
       end;
       end;
 
 
 
 
-
     procedure ttgobj.gettemp(list: TAsmList; size: asizeint; alignment: shortint; temptype: ttemptype; out ref : treference);
     procedure ttgobj.gettemp(list: TAsmList; size: asizeint; alignment: shortint; temptype: ttemptype; out ref : treference);
       begin
       begin
         gettempinternal(list,size,alignment,temptype,nil,false,ref);
         gettempinternal(list,size,alignment,temptype,nil,false,ref);
@@ -589,6 +589,12 @@ implementation
       end;
       end;
 
 
 
 
+    procedure ttgobj.freetemphook(list: TAsmList; temp: ptemprecord);
+      begin
+        list.concat(tai_tempalloc.dealloc(temp^.pos,temp^.size));
+      end;
+
+
     procedure ttgobj.gettempmanaged(list: TAsmList; def:tdef;temptype:ttemptype;out ref : treference);
     procedure ttgobj.gettempmanaged(list: TAsmList; def:tdef;temptype:ttemptype;out ref : treference);
       begin
       begin
         gettempinternal(list,def.size,def.alignment,temptype,def,true,ref);
         gettempinternal(list,def.size,def.alignment,temptype,def,true,ref);