[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