[llvm-commits] Patch for llvm-c to expose targetmachine & allow emit obj/asm files

Carlo Kok ck at remobjects.com
Fri Apr 6 06:34:09 PDT 2012


Attached is a fairly simple patch for llvm-c that exposes:
* Target class
* TargetMachine class

To allow for emitting binary and assembly.

This is the first time I try to contribute to llvm, if there's something 
wrong with my patch, let me know.

--
Carlo Kok
-------------- next part --------------
Index: include/llvm-c/TargetMachine.h
===================================================================
--- include/llvm-c/TargetMachine.h	(revision 0)
+++ include/llvm-c/TargetMachine.h	(working copy)
@@ -0,0 +1,100 @@
+/*===-- llvm-c/TargetMachine.h - Target Machine Library C Interface - C++ -*-=*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMBitReader.a, which          *|
+|* implements input of the LLVM bitcode format.                               *|
+|*                                                                            *|
+|* Many exotic languages can interoperate with C code but have a harder time  *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages.                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TARGETMACHINE_H
+#define LLVM_C_TARGETMACHINE_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct LLVMTargetMachine *LLVMTargetMachineRef;
+typedef struct LLVMTarget *LLVMTargetRef;
+
+typedef enum {
+  LLVMCodeGenLevelNone,
+  LLVMCodeGenLevelLess,
+  LLVMCodeGenLevelDefault,
+  LLVMCodeGenLevelAggressive
+} LLVMCodeGenOptLevel;
+
+typedef enum {
+    LLVMRelocDefault 		= 0,
+	LLVMRelocStatic 		= 1,
+	LLVMRelocPIC			= 2,
+	LLVMRelocDynamicNoPic   = 3 
+} LLVMRelocMode;
+
+typedef enum {
+  LLVMCodeModelDefault,
+  LLVMCodeModelJITDefault,
+  LLVMCodeModelSmall,
+  LLVMCodeModelKernel,
+  LLVMCodeModelMedium,
+  LLVMCodeModelLarge
+} LLVMCodeModel;
+
+typedef enum {
+  LLVMAssemblyFile,
+  LLVMObjectFile
+} LLVMCodeGenFileType;
+
+LLVMTargetRef LLVMGetFirstTarget();
+LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T);
+
+// Target
+const char * LLVMGetTargetName(LLVMTargetRef T);
+const char * LLVMGetTargetDescription(LLVMTargetRef T);
+LLVMBool LLVMTargetHasJIT(LLVMTargetRef T);
+LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T);
+LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T);
+
+// Target Machine
+LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char* Triple, char* CPU, char* Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, LLVMCodeModel CodeModel);
+void LLVMDisposeTargetMachine(LLVMTargetMachineRef T);
+LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T);
+// Following 3 need to be freed with LLVMDisposeMessage
+char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T);
+char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
+char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
+LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
+LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage);
+#ifdef __cplusplus
+}
+
+namespace llvm {
+  class TargetMachine;
+  class Target;
+  
+  inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
+    return reinterpret_cast<TargetMachine *>(P);
+  }
+  inline Target *unwrap(LLVMTargetRef P) {
+    return reinterpret_cast<Target *>(P);
+  }
+  inline LLVMTargetMachineRef wrap(const TargetMachine * P) {
+    return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));
+  }
+  inline LLVMTargetRef wrap(const Target * P) {
+    return reinterpret_cast<LLVMTargetRef>(const_cast<Target *>(P));
+  }
+}
+#endif
+
+#endif
Index: lib/Target/CMakeLists.txt
===================================================================
--- lib/Target/CMakeLists.txt	(revision 153955)
+++ lib/Target/CMakeLists.txt	(working copy)
@@ -9,6 +9,7 @@
   TargetLibraryInfo.cpp
   TargetLoweringObjectFile.cpp
   TargetMachine.cpp
+  TargetMachineC.cpp
   TargetRegisterInfo.cpp
   TargetSubtargetInfo.cpp
   )
Index: lib/Target/TargetMachineC.cpp
===================================================================
--- lib/Target/TargetMachineC.cpp	(revision 0)
+++ lib/Target/TargetMachineC.cpp	(working copy)
@@ -0,0 +1,156 @@
+//===-- TargetMachine.cpp ----------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LLVM-C part of TargetMachine.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/Core.h"
+#include "llvm-c/Target.h"
+#include "llvm-c/TargetMachine.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+
+using namespace llvm;
+
+
+LLVMTargetRef LLVMGetFirstTarget()
+{
+   const Target* target = &*TargetRegistry::begin();
+   return wrap(target);
+}
+LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T)
+{
+  return wrap(unwrap(T)->getNext());
+}
+
+// Target
+const char * LLVMGetTargetName(LLVMTargetRef T) 
+{
+  return unwrap(T)->getName();
+}
+
+const char * LLVMGetTargetDescription(LLVMTargetRef T) 
+{
+  return unwrap(T)->getShortDescription();
+}
+
+LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) 
+{
+  return unwrap(T)->hasJIT();
+}
+LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) 
+{
+  return unwrap(T)->hasTargetMachine();
+}
+LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) 
+{
+  return unwrap(T)->hasMCAsmBackend();
+}
+
+// Target Machine
+LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char* Triple, char* CPU, char* Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, LLVMCodeModel CodeModel)
+{ 
+  Reloc::Model RM = (Reloc::Model)Reloc;
+  CodeModel::Model CM = (CodeModel::Model)CodeModel;
+  CodeGenOpt::Level OL = (CodeGenOpt::Level)Level;
+  TargetOptions opt;
+  return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM, OL));
+}
+
+
+void LLVMDisposeTargetMachine(LLVMTargetMachineRef T)
+{
+  delete unwrap(T);
+}
+LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T)
+{
+  const Target* target = &(unwrap(T)->getTarget());
+  return wrap(target);
+}
+
+char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T)
+{
+  std::string StringRep = unwrap(T)->getTargetTriple();
+  return strdup(StringRep.c_str());
+}
+
+char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T)
+{
+  std::string StringRep = unwrap(T)->getTargetCPU();
+  return strdup(StringRep.c_str());
+}
+
+char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T)
+{
+  std::string StringRep = unwrap(T)->getTargetFeatureString();
+  return strdup(StringRep.c_str());
+}
+
+LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T)
+{
+  return wrap(unwrap(T)->getTargetData());
+}
+
+LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage)
+{ // Inspired by the D binding 
+  TargetMachine* TM = unwrap(T);
+  Module* Mod = unwrap(M);
+
+  FunctionPassManager pass(Mod);
+
+  std::string error;
+
+  const TargetData* td = TM->getTargetData();
+
+  if (!td) {
+    error = "No TargetData in TargetMachine";
+	*ErrorMessage = strdup(error.c_str());
+	return true;
+  }
+  pass.add(new TargetData(*td));
+  
+  TargetMachine::CodeGenFileType ft = (TargetMachine::CodeGenFileType)codegen;
+  raw_fd_ostream dest(Filename, error, raw_fd_ostream::F_Binary);
+  formatted_raw_ostream destf(dest);
+  if (!error.empty()) {
+    *ErrorMessage = strdup(error.c_str());
+	return true;
+  }
+  
+  if (TM->addPassesToEmitFile(pass, destf, ft)) {
+    error = "No TargetData in TargetMachine";
+	*ErrorMessage = strdup(error.c_str());
+	return true;
+  }
+
+  pass.doInitialization();
+
+  for (llvm::Module::iterator it = Mod->begin(), end = Mod->end(); it != end; ++it){
+    errs() << "Did 1 iteration";
+    if (!it->isDeclaration()) {
+	  errs() << "Did 1 proper iterations";
+	  pass.run(*it);
+	}
+  }
+  errs() << "Done";
+  pass.doFinalization();
+  destf.flush();
+  dest.flush();
+  return false;
+}


More information about the llvm-commits mailing list