[LLVMdev] new LTO C interface

Nick Kledzik kledzik at apple.com
Fri Feb 22 22:34:12 PST 2008


Hello.  I work at Apple on our linker.  We are working to improve  
support for llvm
in our tools.  A while back Devang created <llvm/LinkTimeOptimizer.h>  
a C++
interface which allows the linker to process llvm bitcode files along  
with native
mach-o object files.

For the next step we'd like our other tools like nm, ar, and lipo to  
be able to
transparently process bitcode files too.  But those tools are all  
written in C. So, I've
reworked the LTO interface as a C interfaces and broke out the steps  
so that it
could be used by other (non-linker) tools.

Below is the proposed interface.  The project (llvm/tools/lto2 for  
now) will build
a shared object that can be used by other tools.

I'd be interested to know if any one else has use for this.

One area we know we need to augment the API is to allow various  
optimizations
to be selected on the linker command line.

-Nick


//===-- llvm-c/lto.h - LTO Public 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 provides public interface to an abstract link time  
optimization
// library.  LLVM provides an implementation of this interface for  
use with
// llvm bitcode files.
//
// 
===--------------------------------------------------------------------- 
-===//

#ifndef __LTO__H__
#define __LTO__H__

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

typedef enum {
     LTO_SYMBOL_ALIGNMENT_MASK         = 0x0000001F,    /* log2 of  
alignment */
     LTO_SYMBOL_PERMISSIONS_MASK       = 0x000000E0,
     LTO_SYMBOL_PERMISSIONS_CODE       = 0x000000A0,
     LTO_SYMBOL_PERMISSIONS_DATA       = 0x000000C0,
     LTO_SYMBOL_PERMISSIONS_RODATA     = 0x00000080,
     LTO_SYMBOL_DEFINITION_MASK        = 0x00000700,
     LTO_SYMBOL_DEFINITION_REGULAR     = 0x00000100,
     LTO_SYMBOL_DEFINITION_TENTATIVE   = 0x00000200,
     LTO_SYMBOL_DEFINITION_WEAK        = 0x00000300,
     LTO_SYMBOL_DEFINITION_UNDEFINED   = 0x00000400,
     LTO_SYMBOL_SCOPE_MASK             = 0x00001800,
     LTO_SYMBOL_SCOPE_INTERNAL         = 0x00000800,
     LTO_SYMBOL_SCOPE_HIDDEN           = 0x00001000,
     LTO_SYMBOL_SCOPE_DEFAULT          = 0x00001800
} lto_symbol_attributes;

typedef enum {
     LTO_DEBUG_MODEL_NONE         = 0,
     LTO_DEBUG_MODEL_DWARF        = 1
} lto_debug_model;

typedef enum {
     LTO_CODEGEN_PIC_MODEL_STATIC         = 0,
     LTO_CODEGEN_PIC_MODEL_DYNAMIC        = 1,
     LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC = 2
} lto_codegen_model;


// opaque reference to a loaded object module
typedef struct LTOModule*         lto_module_t;

// opaque reference to a code generator
typedef struct LTOCodeGenerator*  lto_code_gen_t;


#ifdef __cplusplus
extern "C" {
#endif

//
// returns a printable string
//
extern const char*
lto_get_version();


//
// returns the last error string or NULL if last operation was sucessful
//
extern const char*
lto_get_error_message();


//
// validates if a file is a loadable object file
//
extern bool
lto_module_is_object_file(const char* path);


//
// validates if a file is a loadable object file compilable for  
requested target
//
extern bool
lto_module_is_object_file_for_target(const char* path,
                                             const char*  
target_triplet_prefix);


//
// validates if a buffer is a loadable object file
//
extern bool
lto_module_is_object_file_in_memory(const uint8_t* mem, size_t length);


//
// validates if a buffer is a loadable object file compilable for  
requested target
//
extern bool
lto_module_is_object_file_in_memory_for_target(const uint8_t* mem,  
size_t length,
                                                const char*  
target_triplet_prefix);


//
// loads an object file from disk
// returns NULL on error (check lto_get_error_message() for details)
//
extern lto_module_t
lto_module_create(const char* path);


//
// loads an object file from memory
// returns NULL on error (check lto_get_error_message() for details)
//
extern lto_module_t
lto_module_create_from_memory(const uint8_t* mem, size_t length);


//
// frees all memory for a module
// upon return the lto_module_t is no longer valid
//
extern void
lto_module_release(lto_module_t mod);


//
// returns triplet string which the object module was compiled under
//
extern const char*
lto_module_get_target_triplet(lto_module_t mod);


//
// returns the number of symbols in the object module
//
extern uint32_t
lto_module_get_num_symbols(lto_module_t mod);


//
// returns the name of the ith symbol in the object module
//
extern const char*
lto_module_get_symbol_name(lto_module_t mod, uint32_t index);


//
// returns the attributes of the ith symbol in the object module
//
extern lto_symbol_attributes
lto_module_get_symbol_attribute(lto_module_t mod, uint32_t index);


//
// instantiates a code generator
// returns NULL if there is an error
//
extern lto_code_gen_t
lto_codegen_create();


//
// frees all memory for a code generator
// upon return the lto_code_gen_t is no longer valid
//
extern void
lto_codegen_release(lto_code_gen_t);



//
// add an object module to the set of modules for which code will be  
generated
// returns true on error (check lto_get_error_message() for details)
//
extern bool
lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod);



//
// sets what if any format of debug info should be generated
// returns true on error (check lto_get_error_message() for details)
//
extern bool
lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model);


//
// sets what code model to generated
// returns true on error (check lto_get_error_message() for details)
//
extern bool
lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model);


//
// adds to a list of all global symbols that must exist in the final
// generated code.  If a function is not listed there, it might be
// inlined into every usage and optimized away.
//
extern void
lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char*  
symbol);


//
// writes a new file at the specified path that contains the
// merged contents of all modules added so far.
// returns true on error (check lto_get_error_message() for details)
//
extern bool
lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);


//
// generates code for all added modules into one object file
// On sucess returns a pointer to a generated mach-o buffer and
// length set to the buffer size.  Client must free() the buffer
// when done.
// On failure, returns NULL (check lto_get_error_message() for details)
//
extern const uint8_t*
lto_codegen_compile(lto_code_gen_t cg, size_t* length);


#ifdef __cplusplus
}
#endif


#endif

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080222/81b5d50e/attachment.html>


More information about the llvm-dev mailing list