Skip to content

Commit

Permalink
[LLVM-C] [bindings/go] Add C and Golang bindings for COMDAT
Browse files Browse the repository at this point in the history
Patch by Ben Clayton

Differential Revision: https://reviews.llvm.org/D44086

llvm-svn: 327551
  • Loading branch information
rnk committed Mar 14, 2018
1 parent 5a48cf8 commit e66458a
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 10 deletions.
52 changes: 44 additions & 8 deletions llvm/bindings/go/llvm/ir.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package llvm

/*
#include "llvm-c/Core.h"
#include "llvm-c/Comdat.h"
#include "IRBindings.h"
#include <stdlib.h>
*/
Expand All @@ -37,6 +38,9 @@ type (
Value struct {
C C.LLVMValueRef
}
Comdat struct {
C C.LLVMComdatRef
}
BasicBlock struct {
C C.LLVMBasicBlockRef
}
Expand All @@ -61,14 +65,15 @@ type (
Attribute struct {
C C.LLVMAttributeRef
}
Opcode C.LLVMOpcode
TypeKind C.LLVMTypeKind
Linkage C.LLVMLinkage
Visibility C.LLVMVisibility
CallConv C.LLVMCallConv
IntPredicate C.LLVMIntPredicate
FloatPredicate C.LLVMRealPredicate
LandingPadClause C.LLVMLandingPadClauseTy
Opcode C.LLVMOpcode
TypeKind C.LLVMTypeKind
Linkage C.LLVMLinkage
Visibility C.LLVMVisibility
CallConv C.LLVMCallConv
ComdatSelectionKind C.LLVMComdatSelectionKind
IntPredicate C.LLVMIntPredicate
FloatPredicate C.LLVMRealPredicate
LandingPadClause C.LLVMLandingPadClauseTy
)

func (c Context) IsNil() bool { return c.C == nil }
Expand Down Expand Up @@ -248,6 +253,18 @@ const (
X86FastcallCallConv CallConv = C.LLVMX86FastcallCallConv
)

//-------------------------------------------------------------------------
// llvm.ComdatSelectionKind
//-------------------------------------------------------------------------

const (
AnyComdatSelectionKind ComdatSelectionKind = C.LLVMAnyComdatSelectionKind
ExactMatchComdatSelectionKind ComdatSelectionKind = C.LLVMExactMatchComdatSelectionKind
LargestComdatSelectionKind ComdatSelectionKind = C.LLVMLargestComdatSelectionKind
NoDuplicatesComdatSelectionKind ComdatSelectionKind = C.LLVMNoDuplicatesComdatSelectionKind
SameSizeComdatSelectionKind ComdatSelectionKind = C.LLVMSameSizeComdatSelectionKind
)

//-------------------------------------------------------------------------
// llvm.IntPredicate
//-------------------------------------------------------------------------
Expand Down Expand Up @@ -1029,6 +1046,25 @@ func AddAlias(m Module, t Type, aliasee Value, name string) (v Value) {
return
}

// Operations on comdat
func (m Module) Comdat(name string) (c Comdat) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
c.C = C.LLVMGetOrInsertComdat(m.C, cname)
return
}

func (v Value) Comdat() (c Comdat) { c.C = C.LLVMGetComdat(v.C); return }
func (v Value) SetComdat(c Comdat) { C.LLVMSetComdat(v.C, c.C) }

func (c Comdat) SelectionKind() ComdatSelectionKind {
return ComdatSelectionKind(C.LLVMGetComdatSelectionKind(c.C))
}

func (c Comdat) SetSelectionKind(k ComdatSelectionKind) {
C.LLVMSetComdatSelectionKind(c.C, (C.LLVMComdatSelectionKind)(k))
}

// Operations on functions
func AddFunction(m Module, name string, ft Type) (v Value) {
cname := C.CString(name)
Expand Down
75 changes: 75 additions & 0 deletions llvm/include/llvm-c/Comdat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*===-- llvm-c/Comdat.h - Module Comdat 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 file defines the C interface to COMDAT. *|
|* *|
\*===----------------------------------------------------------------------===*/

#ifndef LLVM_C_COMDAT_H
#define LLVM_C_COMDAT_H

#include "llvm-c/Types.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
LLVMAnyComdatSelectionKind, ///< The linker may choose any COMDAT.
LLVMExactMatchComdatSelectionKind, ///< The data referenced by the COMDAT must
///< be the same.
LLVMLargestComdatSelectionKind, ///< The linker will choose the largest
///< COMDAT.
LLVMNoDuplicatesComdatSelectionKind, ///< No other Module may specify this
///< COMDAT.
LLVMSameSizeComdatSelectionKind ///< The data referenced by the COMDAT must be
///< the same size.
} LLVMComdatSelectionKind;

/**
* Return the Comdat in the module with the specified name. It is created
* if it didn't already exist.
*
* @see llvm::Module::getOrInsertComdat()
*/
LLVMComdatRef LLVMGetOrInsertComdat(LLVMModuleRef M, const char *Name);

/**
* Get the Comdat assigned to the given global object.
*
* @see llvm::GlobalObject::getComdat()
*/
LLVMComdatRef LLVMGetComdat(LLVMValueRef V);

/**
* Assign the Comdat to the given global object.
*
* @see llvm::GlobalObject::setComdat()
*/
void LLVMSetComdat(LLVMValueRef V, LLVMComdatRef C);

/*
* Get the conflict resolution selection kind for the Comdat.
*
* @see llvm::Comdat::getSelectionKind()
*/
LLVMComdatSelectionKind LLVMGetComdatSelectionKind(LLVMComdatRef C);

/*
* Set the conflict resolution selection kind for the Comdat.
*
* @see llvm::Comdat::setSelectionKind()
*/
void LLVMSetComdatSelectionKind(LLVMComdatRef C, LLVMComdatSelectionKind Kind);

#ifdef __cplusplus
}
#endif

#endif
5 changes: 5 additions & 0 deletions llvm/include/llvm-c/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ typedef struct LLVMOpaqueAttributeRef *LLVMAttributeRef;
*/
typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef;

/**
* @see llvm::Comdat
*/
typedef struct LLVMComdat *LLVMComdatRef;

/**
* @}
*/
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/IR/Comdat.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#ifndef LLVM_IR_COMDAT_H
#define LLVM_IR_COMDAT_H

#include "llvm-c/Types.h"
#include "llvm/Support/CBindingWrapping.h"

namespace llvm {

class raw_ostream;
Expand Down Expand Up @@ -55,6 +58,9 @@ class Comdat {
SelectionKind SK = Any;
};

// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Comdat, LLVMComdatRef)

inline raw_ostream &operator<<(raw_ostream &OS, const Comdat &C) {
C.print(OS);
return OS;
Expand Down
58 changes: 56 additions & 2 deletions llvm/lib/IR/Comdat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
//
//===----------------------------------------------------------------------===//
//
// This file implements the Comdat class.
// This file implements the Comdat class (including the C bindings).
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Comdat.h"
#include "llvm-c/Comdat.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Comdat.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/Module.h"

using namespace llvm;

Expand All @@ -22,3 +25,54 @@ Comdat::Comdat(Comdat &&C) : Name(C.Name), SK(C.SK) {}
Comdat::Comdat() = default;

StringRef Comdat::getName() const { return Name->first(); }

LLVMComdatRef LLVMGetOrInsertComdat(LLVMModuleRef M, const char *Name) {
return wrap(unwrap(M)->getOrInsertComdat(Name));
}

LLVMComdatRef LLVMGetComdat(LLVMValueRef V) {
GlobalObject *G = unwrap<GlobalObject>(V);
return wrap(G->getComdat());
}

void LLVMSetComdat(LLVMValueRef V, LLVMComdatRef C) {
GlobalObject *G = unwrap<GlobalObject>(V);
G->setComdat(unwrap(C));
}

LLVMComdatSelectionKind LLVMGetComdatSelectionKind(LLVMComdatRef C) {
switch (unwrap(C)->getSelectionKind()) {
case Comdat::Any:
return LLVMAnyComdatSelectionKind;
case Comdat::ExactMatch:
return LLVMExactMatchComdatSelectionKind;
case Comdat::Largest:
return LLVMLargestComdatSelectionKind;
case Comdat::NoDuplicates:
return LLVMNoDuplicatesComdatSelectionKind;
case Comdat::SameSize:
return LLVMSameSizeComdatSelectionKind;
}
llvm_unreachable("Invalid Comdat SelectionKind!");
}

void LLVMSetComdatSelectionKind(LLVMComdatRef C, LLVMComdatSelectionKind kind) {
Comdat *Cd = unwrap(C);
switch (kind) {
case LLVMAnyComdatSelectionKind:
Cd->setSelectionKind(Comdat::Any);
break;
case LLVMExactMatchComdatSelectionKind:
Cd->setSelectionKind(Comdat::ExactMatch);
break;
case LLVMLargestComdatSelectionKind:
Cd->setSelectionKind(Comdat::Largest);
break;
case LLVMNoDuplicatesComdatSelectionKind:
Cd->setSelectionKind(Comdat::NoDuplicates);
break;
case LLVMSameSizeComdatSelectionKind:
Cd->setSelectionKind(Comdat::SameSize);
break;
}
}

0 comments on commit e66458a

Please sign in to comment.