llvm_c_ext: Improved `LLVMSetMetadata2()` to support also function values
authorJan Vrany <jan.vrany@fit.cvut.cz>
Tue, 30 Aug 2016 16:57:29 +0100
changeset 78 7a4c769a9fea
parent 77 67e1328d58c9
child 79 6d6e5a3ec6b1
llvm_c_ext: Improved `LLVMSetMetadata2()` to support also function values ...in addition to instruction values. This is handy to attach data to functions, such as debugging information. Added Smalltalk API for setting metadata nodes on instructions and functions.
LLVMExamples.st
LLVMMetadataID.st
LLVMValue.st
Make.proto
Make.spec
abbrev.stc
bc.mak
jv_llvm_s.st
libInit.cc
llvm_c_ext/include/llvm-c-ext/CoreExt.h
llvm_c_ext/lib/CoreExt.cpp
--- a/LLVMExamples.st	Tue Aug 30 12:29:23 2016 +0100
+++ b/LLVMExamples.st	Tue Aug 30 16:57:29 2016 +0100
@@ -18,7 +18,8 @@
 TestCase subclass:#LLVMExamples
 	instanceVariableNames:''
 	classVariableNames:''
-	poolDictionaries:'LLVMIntPredicate LLVMDWARFEncoding LLVMDWARFLamguage'
+	poolDictionaries:'LLVMIntPredicate LLVMDWARFEncoding LLVMDWARFLamguage
+		LLVMMetadataID'
 	category:'LLVM-S-Core-Examples'
 !
 
@@ -531,6 +532,7 @@
     functionTypeDI := dib createTypeFunction: { intptrDI }.
     function := module addFunctionNamed:'factorial' type:functionType.
     functionDI := dib createFunction: 'factorial' in: compilationUnitDI file: fileDI line: 03 type: functionTypeDI local: false definition: true optimized: false.
+    function metadataAt: MD_dbg put: functionDI.
     dib createParameterVariable: 'v' in: functionDI file: fileDI line: 03 type: intptrDI flags: 0 index: 1.
     asm := LLVMIRBuilder new.
     entry := function entry.
@@ -658,7 +660,7 @@
      LLVMExamples example7_factorial_with_debug_info"
 
     "Created: / 14-08-2015 / 06:46:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 26-08-2016 / 15:48:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 30-08-2016 / 23:28:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 example8_data_at_fixed_address
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LLVMMetadataID.st	Tue Aug 30 16:57:29 2016 +0100
@@ -0,0 +1,75 @@
+"
+    Copyright (C) 2015-now Jan Vrany
+
+    This code is not an open-source (yet). You may use this code
+    for your own experiments and projects, given that:
+
+    * all modification to the code will be sent to the
+      original author for inclusion in future releases
+    * this is not used in any commercial software
+
+    This license is provisional and may (will) change in
+    a future.
+"
+"{ Package: 'jv:llvm_s' }"
+
+"{ NameSpace: Smalltalk }"
+
+SharedPool subclass:#LLVMMetadataID
+	instanceVariableNames:''
+	classVariableNames:'MD_alias_scope MD_align MD_dbg MD_dereferenceable
+		MD_dereferenceable_or_null MD_fpmath MD_invariant_group
+		MD_invariant_load MD_make_implicit MD_mem_parallel_loop_access
+		MD_noalias MD_nonnull MD_nontemporal MD_prof MD_range MD_tbaa
+		MD_tbaa_struct MD_unpredictable'
+	poolDictionaries:''
+	category:'LLVM-S-Core-Constants'
+!
+
+!LLVMMetadataID class methodsFor:'documentation'!
+
+copyright
+"
+    Copyright (C) 2015-now Jan Vrany
+
+    This code is not an open-source (yet). You may use this code
+    for your own experiments and projects, given that:
+
+    * all modification to the code will be sent to the
+      original author for inclusion in future releases
+    * this is not used in any commercial software
+
+    This license is provisional and may (will) change in
+    a future.
+"
+! !
+
+!LLVMMetadataID class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    MD_dbg := 0.
+    MD_tbaa := 1.
+    MD_prof := 2.
+    MD_fpmath := 3.
+    MD_range := 4.
+    MD_tbaa_struct := 5.
+    MD_invariant_load := 6.
+    MD_alias_scope := 7.
+    MD_noalias := 8.
+    MD_nontemporal := 9.
+    MD_mem_parallel_loop_access := 10.
+    MD_nonnull := 11.
+    MD_dereferenceable := 12.
+    MD_dereferenceable_or_null := 13.
+    MD_make_implicit := 14.
+    MD_unpredictable := 15.
+    MD_invariant_group := 16.
+    MD_align := 17.
+
+    "Modified: / 30-08-2016 / 23:27:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+
+LLVMMetadataID initialize!
--- a/LLVMValue.st	Tue Aug 30 12:29:23 2016 +0100
+++ b/LLVMValue.st	Tue Aug 30 16:57:29 2016 +0100
@@ -51,6 +51,24 @@
     "Created: / 20-06-2016 / 08:03:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+metadataAt: anIntegerOrString put: anLLVMMetadata
+    | id |
+
+    self assert: (anIntegerOrString isInteger or:[ anIntegerOrString isString ]) description: 'ID must be eithen an integer or a string'.
+    self assertIsMetadata: anLLVMMetadata.
+    self assert: (self isInstruction or:[self isFunction]) description: 'Not an instruction or a function'.
+
+    anIntegerOrString isInteger ifTrue:[
+        id := anIntegerOrString
+    ] ifFalse:[ 
+        id := LLVM GetMDKindID: anIntegerOrString  _: anIntegerOrString size.
+    ].
+    ^ LLVMCEXT SetMetadata2: self _: id _: anLLVMMetadata
+
+    "Created: / 30-08-2016 / 16:51:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 30-08-2016 / 23:35:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 name
     ^ LLVM GetValueName: self
 
--- a/Make.proto	Tue Aug 30 12:29:23 2016 +0100
+++ b/Make.proto	Tue Aug 30 16:57:29 2016 +0100
@@ -34,7 +34,7 @@
 # add the path(es) here:,
 # ********** OPTIONAL: MODIFY the next lines ***
 # LOCALINCLUDES=-Ifoo -Ibar
-LOCALINCLUDES= -I$(INCLUDE_TOP)/stx/libbasic
+LOCALINCLUDES= -I$(INCLUDE_TOP)/stx/goodies/sunit -I$(INCLUDE_TOP)/stx/libbasic
 
 
 # if you need any additional defines for embedded C code,
@@ -144,6 +144,7 @@
 $(OUTDIR)LLVMLandingPadClauseTy.$(O) LLVMLandingPadClauseTy.$(C) LLVMLandingPadClauseTy.$(H): LLVMLandingPadClauseTy.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMLinkage.$(O) LLVMLinkage.$(C) LLVMLinkage.$(H): LLVMLinkage.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMMCJITCompilerOptions.$(O) LLVMMCJITCompilerOptions.$(C) LLVMMCJITCompilerOptions.$(H): LLVMMCJITCompilerOptions.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)LLVMMetadataID.$(O) LLVMMetadataID.$(C) LLVMMetadataID.$(H): LLVMMetadataID.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMMetadataKind.$(O) LLVMMetadataKind.$(C) LLVMMetadataKind.$(H): LLVMMetadataKind.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMModuleFlagBehavior.$(O) LLVMModuleFlagBehavior.$(C) LLVMModuleFlagBehavior.$(H): LLVMModuleFlagBehavior.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMModuleVerificationError.$(O) LLVMModuleVerificationError.$(C) LLVMModuleVerificationError.$(H): LLVMModuleVerificationError.st $(INCLUDE_TOP)/stx/libbasic/Error.$(H) $(INCLUDE_TOP)/stx/libbasic/Exception.$(H) $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
--- a/Make.spec	Tue Aug 30 12:29:23 2016 +0100
+++ b/Make.spec	Tue Aug 30 16:57:29 2016 +0100
@@ -69,6 +69,7 @@
 	LLVMLandingPadClauseTy \
 	LLVMLinkage \
 	LLVMMCJITCompilerOptions \
+	LLVMMetadataID \
 	LLVMMetadataKind \
 	LLVMModuleFlagBehavior \
 	LLVMModuleVerificationError \
@@ -146,6 +147,7 @@
     $(OUTDIR_SLASH)LLVMLandingPadClauseTy.$(O) \
     $(OUTDIR_SLASH)LLVMLinkage.$(O) \
     $(OUTDIR_SLASH)LLVMMCJITCompilerOptions.$(O) \
+    $(OUTDIR_SLASH)LLVMMetadataID.$(O) \
     $(OUTDIR_SLASH)LLVMMetadataKind.$(O) \
     $(OUTDIR_SLASH)LLVMModuleFlagBehavior.$(O) \
     $(OUTDIR_SLASH)LLVMModuleVerificationError.$(O) \
--- a/abbrev.stc	Tue Aug 30 12:29:23 2016 +0100
+++ b/abbrev.stc	Tue Aug 30 16:57:29 2016 +0100
@@ -19,6 +19,7 @@
 LLVMLandingPadClauseTy LLVMLandingPadClauseTy jv:llvm_s 'LLVM-S-Core-Constants' 0
 LLVMLinkage LLVMLinkage jv:llvm_s 'LLVM-S-Core-Constants' 0
 LLVMMCJITCompilerOptions LLVMMCJITCompilerOptions jv:llvm_s 'LLVM-S-Core' 0
+LLVMMetadataID LLVMMetadataID jv:llvm_s 'LLVM-S-Core-Constants' 0
 LLVMMetadataKind LLVMMetadataKind jv:llvm_s 'LLVM-S-Core-Constants' 0
 LLVMModuleFlagBehavior LLVMModuleFlagBehavior jv:llvm_s 'LLVM-S-Core-Constants' 0
 LLVMModuleVerificationError LLVMModuleVerificationError jv:llvm_s 'LLVM-S-Core-Exceptions' 1
@@ -30,6 +31,7 @@
 LLVMVerifierFailureAction LLVMVerifierFailureAction jv:llvm_s 'LLVM-S-Core-Constants' 0
 LLVMVisibility LLVMVisibility jv:llvm_s 'LLVM-S-Core-Constants' 0
 jv_llvm_s jv_llvm_s jv:llvm_s '* Projects & Packages *' 3
+LLVMExamples LLVMExamples jv:llvm_s 'LLVM-S-Core-Examples' 1
 LLVMObject LLVMObject jv:llvm_s 'LLVM-S-Internal' 0
 LLVMTypeError LLVMTypeError jv:llvm_s 'LLVM-S-Core-Exceptions' 1
 LLVMBasicBlock LLVMBasicBlock jv:llvm_s 'LLVM-S-Core' 0
@@ -73,4 +75,3 @@
 LLVMTypeFloat LLVMTypeFloat jv:llvm_s 'LLVM-S-Core-Types' 0
 LLVMTypePPC_FP128 LLVMTypePPC_FP128 jv:llvm_s 'LLVM-S-Core-Types' 0
 LLVMTypeX86_FP80 LLVMTypeX86_FP80 jv:llvm_s 'LLVM-S-Core-Types' 0
-LLVMExamples LLVMExamples jv:llvm_s 'LLVM-S-Core-Examples' 1
--- a/bc.mak	Tue Aug 30 12:29:23 2016 +0100
+++ b/bc.mak	Tue Aug 30 16:57:29 2016 +0100
@@ -35,7 +35,7 @@
 
 
 
-LOCALINCLUDES= -I$(INCLUDE_TOP)\stx\libbasic
+LOCALINCLUDES= -I$(INCLUDE_TOP)\stx\goodies\sunit -I$(INCLUDE_TOP)\stx\libbasic
 LOCALDEFINES=
 
 STCLOCALOPT=-package=$(PACKAGE) -I. $(LOCALINCLUDES) -headerDir=. $(STCLOCALOPTIMIZATIONS) $(STCWARNINGS) $(LOCALDEFINES)  -varPrefix=$(LIBNAME)
@@ -86,6 +86,7 @@
 $(OUTDIR)LLVMLandingPadClauseTy.$(O) LLVMLandingPadClauseTy.$(C) LLVMLandingPadClauseTy.$(H): LLVMLandingPadClauseTy.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMLinkage.$(O) LLVMLinkage.$(C) LLVMLinkage.$(H): LLVMLinkage.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMMCJITCompilerOptions.$(O) LLVMMCJITCompilerOptions.$(C) LLVMMCJITCompilerOptions.$(H): LLVMMCJITCompilerOptions.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)LLVMMetadataID.$(O) LLVMMetadataID.$(C) LLVMMetadataID.$(H): LLVMMetadataID.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMMetadataKind.$(O) LLVMMetadataKind.$(C) LLVMMetadataKind.$(H): LLVMMetadataKind.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMModuleFlagBehavior.$(O) LLVMModuleFlagBehavior.$(C) LLVMModuleFlagBehavior.$(H): LLVMModuleFlagBehavior.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
 $(OUTDIR)LLVMModuleVerificationError.$(O) LLVMModuleVerificationError.$(C) LLVMModuleVerificationError.$(H): LLVMModuleVerificationError.st $(INCLUDE_TOP)\stx\libbasic\Error.$(H) $(INCLUDE_TOP)\stx\libbasic\Exception.$(H) $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
--- a/jv_llvm_s.st	Tue Aug 30 12:29:23 2016 +0100
+++ b/jv_llvm_s.st	Tue Aug 30 16:57:29 2016 +0100
@@ -91,6 +91,7 @@
      by searching all classes (and their packages) which are referenced by my classes."
 
     ^ #(
+        #'stx:goodies/sunit'    "TestAsserter - superclass of LLVMExamples"
     )
 !
 
@@ -155,6 +156,7 @@
         LLVMLandingPadClauseTy
         LLVMLinkage
         LLVMMCJITCompilerOptions
+        LLVMMetadataID
         LLVMMetadataKind
         LLVMModuleFlagBehavior
         LLVMModuleVerificationError
@@ -166,6 +168,7 @@
         LLVMVerifierFailureAction
         LLVMVisibility
         #'jv_llvm_s'
+        (LLVMExamples autoload)
         LLVMObject
         LLVMTypeError
         LLVMBasicBlock
@@ -209,7 +212,6 @@
         LLVMTypeFloat
         #'LLVMTypePPC_FP128'
         #'LLVMTypeX86_FP80'
-        (LLVMExamples autoload)
     )
 !
 
--- a/libInit.cc	Tue Aug 30 12:29:23 2016 +0100
+++ b/libInit.cc	Tue Aug 30 16:57:29 2016 +0100
@@ -34,6 +34,7 @@
 extern void _LLVMLandingPadClauseTy_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _LLVMLinkage_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _LLVMMCJITCompilerOptions_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
+extern void _LLVMMetadataID_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _LLVMMetadataKind_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _LLVMModuleFlagBehavior_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _LLVMModuleVerificationError_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
@@ -120,6 +121,7 @@
     _LLVMLandingPadClauseTy_Init(pass,__pRT__,snd);
     _LLVMLinkage_Init(pass,__pRT__,snd);
     _LLVMMCJITCompilerOptions_Init(pass,__pRT__,snd);
+    _LLVMMetadataID_Init(pass,__pRT__,snd);
     _LLVMMetadataKind_Init(pass,__pRT__,snd);
     _LLVMModuleFlagBehavior_Init(pass,__pRT__,snd);
     _LLVMModuleVerificationError_Init(pass,__pRT__,snd);
--- a/llvm_c_ext/include/llvm-c-ext/CoreExt.h	Tue Aug 30 12:29:23 2016 +0100
+++ b/llvm_c_ext/include/llvm-c-ext/CoreExt.h	Tue Aug 30 16:57:29 2016 +0100
@@ -57,7 +57,25 @@
 
 void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name,
                                   LLVMMetadataRef Val);
-void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD);
+
+/**
+ * Set the metadata of the specified kind to the specified
+ * node. This updates/replaces metadata if already present, or 
+ * removes it if `MD` is null. 
+ * 
+ * `Val` mist be either an instruction or a function. If it;s of 
+ *  other kind. this function is no-op
+ *
+ *  \param Val reference either an instruction or a function.
+ *  \param KindID a unique identifier of metadata kind. 
+ *         \see llvm::LLVMContext
+ *
+ *  \see llvm::LLVMContext
+ *  \see llvm::Instruction::setMetadata()
+ *  \see llvm::Function::setMetadata()
+ */
+
+void LLVMSetMetadata2(LLVMValueRef Val, unsigned KindID, LLVMMetadataRef MD);
 
 void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New);
 
--- a/llvm_c_ext/lib/CoreExt.cpp	Tue Aug 30 12:29:23 2016 +0100
+++ b/llvm_c_ext/lib/CoreExt.cpp	Tue Aug 30 16:57:29 2016 +0100
@@ -91,9 +91,18 @@
   N->addOperand(unwrap<MDNode>(Val));
 }
 
-void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) {
-  MDNode *N = MD ? unwrap<MDNode>(MD) : nullptr;
-  unwrap<Instruction>(Inst)->setMetadata(KindID, N);
+void LLVMSetMetadata2(LLVMValueRef Val, unsigned KindID, LLVMMetadataRef MD) {
+  MDNode *N = MD ? unwrap<MDNode>(MD) : nullptr;  
+  Function *F = dyn_cast<Function>(unwrap(Val));
+  if (F) {
+    F->setMetadata(KindID, N);
+    return;
+  }
+  Instruction *I = dyn_cast<Instruction>(unwrap(Val));
+  if (I) {
+    I->setMetadata(KindID, N);
+    return;
+  }
 }
 
 void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New) {