2007-09-18 05:18:57 +02:00
|
|
|
//===-- Core.cpp ----------------------------------------------------------===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2007-09-18 05:18:57 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2010-10-07 21:51:21 +02:00
|
|
|
// This file implements the common infrastructure (including the C bindings)
|
|
|
|
// for libLLVMCore.a, which implements the LLVM intermediate representation.
|
2007-09-18 05:18:57 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "llvm-c/Core.h"
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/Attributes.h"
|
|
|
|
#include "llvm/IR/Constants.h"
|
2018-10-11 01:53:12 +02:00
|
|
|
#include "llvm/IR/DebugInfoMetadata.h"
|
2014-06-12 19:38:55 +02:00
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
2014-04-16 19:45:04 +02:00
|
|
|
#include "llvm/IR/DiagnosticInfo.h"
|
|
|
|
#include "llvm/IR/DiagnosticPrinter.h"
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/GlobalAlias.h"
|
|
|
|
#include "llvm/IR/GlobalVariable.h"
|
2014-01-07 12:48:04 +01:00
|
|
|
#include "llvm/IR/IRBuilder.h"
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/InlineAsm.h"
|
|
|
|
#include "llvm/IR/IntrinsicInst.h"
|
|
|
|
#include "llvm/IR/LLVMContext.h"
|
2015-02-13 11:01:29 +01:00
|
|
|
#include "llvm/IR/LegacyPassManager.h"
|
2013-05-01 22:59:00 +02:00
|
|
|
#include "llvm/IR/Module.h"
|
Sink all InitializePasses.h includes
This file lists every pass in LLVM, and is included by Pass.h, which is
very popular. Every time we add, remove, or rename a pass in LLVM, it
caused lots of recompilation.
I found this fact by looking at this table, which is sorted by the
number of times a file was changed over the last 100,000 git commits
multiplied by the number of object files that depend on it in the
current checkout:
recompiles touches affected_files header
342380 95 3604 llvm/include/llvm/ADT/STLExtras.h
314730 234 1345 llvm/include/llvm/InitializePasses.h
307036 118 2602 llvm/include/llvm/ADT/APInt.h
213049 59 3611 llvm/include/llvm/Support/MathExtras.h
170422 47 3626 llvm/include/llvm/Support/Compiler.h
162225 45 3605 llvm/include/llvm/ADT/Optional.h
158319 63 2513 llvm/include/llvm/ADT/Triple.h
140322 39 3598 llvm/include/llvm/ADT/StringRef.h
137647 59 2333 llvm/include/llvm/Support/Error.h
131619 73 1803 llvm/include/llvm/Support/FileSystem.h
Before this change, touching InitializePasses.h would cause 1345 files
to recompile. After this change, touching it only causes 550 compiles in
an incremental rebuild.
Reviewers: bkramer, asbirlea, bollu, jdoerfert
Differential Revision: https://reviews.llvm.org/D70211
2019-11-13 22:15:01 +01:00
|
|
|
#include "llvm/InitializePasses.h"
|
2010-01-27 21:34:15 +01:00
|
|
|
#include "llvm/Support/Debug.h"
|
2009-07-11 22:10:48 +02:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2014-04-30 01:26:49 +02:00
|
|
|
#include "llvm/Support/FileSystem.h"
|
2013-02-17 17:35:51 +01:00
|
|
|
#include "llvm/Support/ManagedStatic.h"
|
2010-01-27 21:34:15 +01:00
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
2014-01-07 12:48:04 +01:00
|
|
|
#include "llvm/Support/Threading.h"
|
2010-01-27 21:34:15 +01:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2007-09-18 05:18:57 +02:00
|
|
|
#include <cassert>
|
2007-12-19 23:30:40 +01:00
|
|
|
#include <cstdlib>
|
2008-02-20 12:08:44 +01:00
|
|
|
#include <cstring>
|
2014-06-12 19:38:55 +02:00
|
|
|
#include <system_error>
|
2007-09-18 05:18:57 +02:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-22 00:55:11 +02:00
|
|
|
#define DEBUG_TYPE "ir"
|
|
|
|
|
2010-10-07 21:51:21 +02:00
|
|
|
void llvm::initializeCore(PassRegistry &Registry) {
|
2014-01-13 14:07:17 +01:00
|
|
|
initializeDominatorTreeWrapperPassPass(Registry);
|
2014-01-12 13:15:39 +01:00
|
|
|
initializePrintModulePassWrapperPass(Registry);
|
|
|
|
initializePrintFunctionPassWrapperPass(Registry);
|
2017-07-05 03:16:29 +02:00
|
|
|
initializeSafepointIRVerifierPass(Registry);
|
2014-01-20 12:34:08 +01:00
|
|
|
initializeVerifierLegacyPassPass(Registry);
|
2010-10-07 21:51:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMInitializeCore(LLVMPassRegistryRef R) {
|
|
|
|
initializeCore(*unwrap(R));
|
|
|
|
}
|
2007-09-18 05:18:57 +02:00
|
|
|
|
2013-02-17 17:35:51 +01:00
|
|
|
void LLVMShutdown() {
|
|
|
|
llvm_shutdown();
|
|
|
|
}
|
|
|
|
|
2007-12-19 23:30:40 +01:00
|
|
|
/*===-- Error handling ----------------------------------------------------===*/
|
|
|
|
|
2013-05-22 04:46:43 +02:00
|
|
|
char *LLVMCreateMessage(const char *Message) {
|
|
|
|
return strdup(Message);
|
|
|
|
}
|
|
|
|
|
2007-12-19 23:30:40 +01:00
|
|
|
void LLVMDisposeMessage(char *Message) {
|
|
|
|
free(Message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-01 18:58:40 +02:00
|
|
|
/*===-- Operations on contexts --------------------------------------------===*/
|
|
|
|
|
2016-04-14 23:59:18 +02:00
|
|
|
static ManagedStatic<LLVMContext> GlobalContext;
|
|
|
|
|
2009-07-01 18:58:40 +02:00
|
|
|
LLVMContextRef LLVMContextCreate() {
|
|
|
|
return wrap(new LLVMContext());
|
|
|
|
}
|
|
|
|
|
2016-04-14 23:59:18 +02:00
|
|
|
LLVMContextRef LLVMGetGlobalContext() { return wrap(&*GlobalContext); }
|
2009-07-02 02:16:38 +02:00
|
|
|
|
2014-04-16 19:45:04 +02:00
|
|
|
void LLVMContextSetDiagnosticHandler(LLVMContextRef C,
|
|
|
|
LLVMDiagnosticHandler Handler,
|
|
|
|
void *DiagnosticContext) {
|
2017-09-15 22:10:09 +02:00
|
|
|
unwrap(C)->setDiagnosticHandlerCallBack(
|
|
|
|
LLVM_EXTENSION reinterpret_cast<DiagnosticHandler::DiagnosticHandlerTy>(
|
2016-04-08 11:19:02 +02:00
|
|
|
Handler),
|
2014-04-16 19:45:04 +02:00
|
|
|
DiagnosticContext);
|
|
|
|
}
|
|
|
|
|
2016-04-08 11:19:02 +02:00
|
|
|
LLVMDiagnosticHandler LLVMContextGetDiagnosticHandler(LLVMContextRef C) {
|
|
|
|
return LLVM_EXTENSION reinterpret_cast<LLVMDiagnosticHandler>(
|
2017-09-15 22:10:09 +02:00
|
|
|
unwrap(C)->getDiagnosticHandlerCallBack());
|
2016-04-08 11:19:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void *LLVMContextGetDiagnosticContext(LLVMContextRef C) {
|
|
|
|
return unwrap(C)->getDiagnosticContext();
|
|
|
|
}
|
|
|
|
|
2014-05-16 04:33:15 +02:00
|
|
|
void LLVMContextSetYieldCallback(LLVMContextRef C, LLVMYieldCallback Callback,
|
|
|
|
void *OpaqueHandle) {
|
|
|
|
auto YieldCallback =
|
|
|
|
LLVM_EXTENSION reinterpret_cast<LLVMContext::YieldCallbackTy>(Callback);
|
|
|
|
unwrap(C)->setYieldCallback(YieldCallback, OpaqueHandle);
|
|
|
|
}
|
|
|
|
|
2019-01-01 20:03:37 +01:00
|
|
|
LLVMBool LLVMContextShouldDiscardValueNames(LLVMContextRef C) {
|
2019-01-01 19:56:51 +01:00
|
|
|
return unwrap(C)->shouldDiscardValueNames();
|
|
|
|
}
|
|
|
|
|
2019-01-01 20:03:37 +01:00
|
|
|
void LLVMContextSetDiscardValueNames(LLVMContextRef C, LLVMBool Discard) {
|
2019-01-01 19:56:51 +01:00
|
|
|
unwrap(C)->setDiscardValueNames(Discard);
|
|
|
|
}
|
|
|
|
|
2009-07-01 18:58:40 +02:00
|
|
|
void LLVMContextDispose(LLVMContextRef C) {
|
|
|
|
delete unwrap(C);
|
|
|
|
}
|
|
|
|
|
2016-04-05 00:00:25 +02:00
|
|
|
unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char *Name,
|
2010-02-28 10:45:59 +01:00
|
|
|
unsigned SLen) {
|
|
|
|
return unwrap(C)->getMDKindID(StringRef(Name, SLen));
|
|
|
|
}
|
|
|
|
|
2016-04-05 00:00:25 +02:00
|
|
|
unsigned LLVMGetMDKindID(const char *Name, unsigned SLen) {
|
2010-02-28 10:45:59 +01:00
|
|
|
return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen);
|
|
|
|
}
|
|
|
|
|
2016-06-12 08:17:24 +02:00
|
|
|
unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen) {
|
2020-02-02 14:46:59 +01:00
|
|
|
return Attribute::getAttrKindFromName(StringRef(Name, SLen));
|
2016-04-20 03:02:12 +02:00
|
|
|
}
|
|
|
|
|
2016-06-12 09:56:21 +02:00
|
|
|
unsigned LLVMGetLastEnumAttributeKind(void) {
|
2016-06-12 08:17:24 +02:00
|
|
|
return Attribute::AttrKind::EndAttrKinds;
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID,
|
|
|
|
uint64_t Val) {
|
2019-08-28 11:21:56 +02:00
|
|
|
auto &Ctx = *unwrap(C);
|
|
|
|
auto AttrKind = (Attribute::AttrKind)KindID;
|
|
|
|
|
|
|
|
if (AttrKind == Attribute::AttrKind::ByVal) {
|
|
|
|
// After r362128, byval attributes need to have a type attribute. Provide a
|
|
|
|
// NULL one until a proper API is added for this.
|
|
|
|
return wrap(Attribute::getWithByValType(Ctx, NULL));
|
|
|
|
}
|
2020-01-09 15:28:48 +01:00
|
|
|
|
2020-09-29 15:33:55 +02:00
|
|
|
if (AttrKind == Attribute::AttrKind::StructRet) {
|
|
|
|
// Same as byval.
|
|
|
|
return wrap(Attribute::getWithStructRetType(Ctx, NULL));
|
|
|
|
}
|
|
|
|
|
2020-01-09 15:28:48 +01:00
|
|
|
return wrap(Attribute::get(Ctx, AttrKind, Val));
|
2016-06-12 08:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A) {
|
|
|
|
return unwrap(A).getKindAsEnum();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A) {
|
|
|
|
auto Attr = unwrap(A);
|
|
|
|
if (Attr.isEnumAttribute())
|
|
|
|
return 0;
|
|
|
|
return Attr.getValueAsInt();
|
|
|
|
}
|
|
|
|
|
2021-03-19 23:55:52 +01:00
|
|
|
LLVMAttributeRef LLVMCreateTypeAttribute(LLVMContextRef C, unsigned KindID,
|
|
|
|
LLVMTypeRef type_ref) {
|
|
|
|
auto &Ctx = *unwrap(C);
|
|
|
|
auto AttrKind = (Attribute::AttrKind)KindID;
|
|
|
|
return wrap(Attribute::get(Ctx, AttrKind, unwrap(type_ref)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMTypeRef LLVMGetTypeAttributeValue(LLVMAttributeRef A) {
|
|
|
|
auto Attr = unwrap(A);
|
|
|
|
return wrap(Attr.getValueAsType());
|
|
|
|
}
|
|
|
|
|
2016-06-12 08:17:24 +02:00
|
|
|
LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
|
|
|
|
const char *K, unsigned KLength,
|
|
|
|
const char *V, unsigned VLength) {
|
|
|
|
return wrap(Attribute::get(*unwrap(C), StringRef(K, KLength),
|
|
|
|
StringRef(V, VLength)));
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMGetStringAttributeKind(LLVMAttributeRef A,
|
|
|
|
unsigned *Length) {
|
|
|
|
auto S = unwrap(A).getKindAsString();
|
|
|
|
*Length = S.size();
|
|
|
|
return S.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMGetStringAttributeValue(LLVMAttributeRef A,
|
|
|
|
unsigned *Length) {
|
|
|
|
auto S = unwrap(A).getValueAsString();
|
|
|
|
*Length = S.size();
|
|
|
|
return S.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A) {
|
|
|
|
auto Attr = unwrap(A);
|
|
|
|
return Attr.isEnumAttribute() || Attr.isIntAttribute();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A) {
|
|
|
|
return unwrap(A).isStringAttribute();
|
|
|
|
}
|
|
|
|
|
2021-03-19 23:55:52 +01:00
|
|
|
LLVMBool LLVMIsTypeAttribute(LLVMAttributeRef A) {
|
|
|
|
return unwrap(A).isTypeAttribute();
|
|
|
|
}
|
|
|
|
|
2014-04-16 19:45:04 +02:00
|
|
|
char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) {
|
2014-06-27 00:52:05 +02:00
|
|
|
std::string MsgStorage;
|
|
|
|
raw_string_ostream Stream(MsgStorage);
|
|
|
|
DiagnosticPrinterRawOStream DP(Stream);
|
|
|
|
|
2014-04-16 19:45:04 +02:00
|
|
|
unwrap(DI)->print(DP);
|
2014-06-27 00:52:05 +02:00
|
|
|
Stream.flush();
|
|
|
|
|
|
|
|
return LLVMCreateMessage(MsgStorage.c_str());
|
2014-04-16 19:45:04 +02:00
|
|
|
}
|
|
|
|
|
2016-03-07 22:39:20 +01:00
|
|
|
LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI) {
|
2014-04-16 19:45:04 +02:00
|
|
|
LLVMDiagnosticSeverity severity;
|
|
|
|
|
|
|
|
switch(unwrap(DI)->getSeverity()) {
|
|
|
|
default:
|
|
|
|
severity = LLVMDSError;
|
|
|
|
break;
|
|
|
|
case DS_Warning:
|
|
|
|
severity = LLVMDSWarning;
|
|
|
|
break;
|
|
|
|
case DS_Remark:
|
|
|
|
severity = LLVMDSRemark;
|
|
|
|
break;
|
|
|
|
case DS_Note:
|
|
|
|
severity = LLVMDSNote;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return severity;
|
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*===-- Operations on modules ---------------------------------------------===*/
|
|
|
|
|
2009-07-02 09:17:57 +02:00
|
|
|
LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) {
|
2016-04-14 23:59:18 +02:00
|
|
|
return wrap(new Module(ModuleID, *GlobalContext));
|
2009-07-02 09:17:57 +02:00
|
|
|
}
|
|
|
|
|
2013-09-19 01:31:10 +02:00
|
|
|
LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID,
|
2009-07-02 09:17:57 +02:00
|
|
|
LLVMContextRef C) {
|
2009-07-01 23:22:36 +02:00
|
|
|
return wrap(new Module(ModuleID, *unwrap(C)));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMDisposeModule(LLVMModuleRef M) {
|
|
|
|
delete unwrap(M);
|
|
|
|
}
|
|
|
|
|
2016-04-05 15:56:59 +02:00
|
|
|
const char *LLVMGetModuleIdentifier(LLVMModuleRef M, size_t *Len) {
|
|
|
|
auto &Str = unwrap(M)->getModuleIdentifier();
|
|
|
|
*Len = Str.length();
|
|
|
|
return Str.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetModuleIdentifier(LLVMModuleRef M, const char *Ident, size_t Len) {
|
|
|
|
unwrap(M)->setModuleIdentifier(StringRef(Ident, Len));
|
|
|
|
}
|
|
|
|
|
2018-01-30 22:34:29 +01:00
|
|
|
const char *LLVMGetSourceFileName(LLVMModuleRef M, size_t *Len) {
|
|
|
|
auto &Str = unwrap(M)->getSourceFileName();
|
|
|
|
*Len = Str.length();
|
|
|
|
return Str.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetSourceFileName(LLVMModuleRef M, const char *Name, size_t Len) {
|
|
|
|
unwrap(M)->setSourceFileName(StringRef(Name, Len));
|
|
|
|
}
|
2016-04-05 15:56:59 +02:00
|
|
|
|
2007-12-27 21:13:47 +01:00
|
|
|
/*--.. Data layout .........................................................--*/
|
2016-02-16 01:23:52 +01:00
|
|
|
const char *LLVMGetDataLayoutStr(LLVMModuleRef M) {
|
2014-02-25 21:01:08 +01:00
|
|
|
return unwrap(M)->getDataLayoutStr().c_str();
|
2007-12-27 21:13:47 +01:00
|
|
|
}
|
|
|
|
|
2016-02-16 01:23:52 +01:00
|
|
|
const char *LLVMGetDataLayout(LLVMModuleRef M) {
|
|
|
|
return LLVMGetDataLayoutStr(M);
|
|
|
|
}
|
|
|
|
|
2016-02-16 00:40:06 +01:00
|
|
|
void LLVMSetDataLayout(LLVMModuleRef M, const char *DataLayoutStr) {
|
|
|
|
unwrap(M)->setDataLayout(DataLayoutStr);
|
2007-12-27 21:13:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Target triple .......................................................--*/
|
|
|
|
const char * LLVMGetTarget(LLVMModuleRef M) {
|
|
|
|
return unwrap(M)->getTargetTriple().c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetTarget(LLVMModuleRef M, const char *Triple) {
|
|
|
|
unwrap(M)->setTargetTriple(Triple);
|
|
|
|
}
|
|
|
|
|
2018-05-14 10:09:00 +02:00
|
|
|
/*--.. Module flags ........................................................--*/
|
|
|
|
struct LLVMOpaqueModuleFlagEntry {
|
|
|
|
LLVMModuleFlagBehavior Behavior;
|
|
|
|
const char *Key;
|
|
|
|
size_t KeyLen;
|
|
|
|
LLVMMetadataRef Metadata;
|
|
|
|
};
|
|
|
|
|
|
|
|
static Module::ModFlagBehavior
|
|
|
|
map_to_llvmModFlagBehavior(LLVMModuleFlagBehavior Behavior) {
|
|
|
|
switch (Behavior) {
|
|
|
|
case LLVMModuleFlagBehaviorError:
|
|
|
|
return Module::ModFlagBehavior::Error;
|
|
|
|
case LLVMModuleFlagBehaviorWarning:
|
|
|
|
return Module::ModFlagBehavior::Warning;
|
|
|
|
case LLVMModuleFlagBehaviorRequire:
|
|
|
|
return Module::ModFlagBehavior::Require;
|
|
|
|
case LLVMModuleFlagBehaviorOverride:
|
|
|
|
return Module::ModFlagBehavior::Override;
|
|
|
|
case LLVMModuleFlagBehaviorAppend:
|
|
|
|
return Module::ModFlagBehavior::Append;
|
|
|
|
case LLVMModuleFlagBehaviorAppendUnique:
|
|
|
|
return Module::ModFlagBehavior::AppendUnique;
|
|
|
|
}
|
2018-05-14 14:20:19 +02:00
|
|
|
llvm_unreachable("Unknown LLVMModuleFlagBehavior");
|
2018-05-14 10:09:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static LLVMModuleFlagBehavior
|
|
|
|
map_from_llvmModFlagBehavior(Module::ModFlagBehavior Behavior) {
|
|
|
|
switch (Behavior) {
|
|
|
|
case Module::ModFlagBehavior::Error:
|
|
|
|
return LLVMModuleFlagBehaviorError;
|
|
|
|
case Module::ModFlagBehavior::Warning:
|
|
|
|
return LLVMModuleFlagBehaviorWarning;
|
|
|
|
case Module::ModFlagBehavior::Require:
|
|
|
|
return LLVMModuleFlagBehaviorRequire;
|
|
|
|
case Module::ModFlagBehavior::Override:
|
|
|
|
return LLVMModuleFlagBehaviorOverride;
|
|
|
|
case Module::ModFlagBehavior::Append:
|
|
|
|
return LLVMModuleFlagBehaviorAppend;
|
|
|
|
case Module::ModFlagBehavior::AppendUnique:
|
|
|
|
return LLVMModuleFlagBehaviorAppendUnique;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unhandled Flag Behavior");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMModuleFlagEntry *LLVMCopyModuleFlagsMetadata(LLVMModuleRef M, size_t *Len) {
|
|
|
|
SmallVector<Module::ModuleFlagEntry, 8> MFEs;
|
|
|
|
unwrap(M)->getModuleFlagsMetadata(MFEs);
|
|
|
|
|
|
|
|
LLVMOpaqueModuleFlagEntry *Result = static_cast<LLVMOpaqueModuleFlagEntry *>(
|
|
|
|
safe_malloc(MFEs.size() * sizeof(LLVMOpaqueModuleFlagEntry)));
|
|
|
|
for (unsigned i = 0; i < MFEs.size(); ++i) {
|
|
|
|
const auto &ModuleFlag = MFEs[i];
|
|
|
|
Result[i].Behavior = map_from_llvmModFlagBehavior(ModuleFlag.Behavior);
|
|
|
|
Result[i].Key = ModuleFlag.Key->getString().data();
|
|
|
|
Result[i].KeyLen = ModuleFlag.Key->getString().size();
|
|
|
|
Result[i].Metadata = wrap(ModuleFlag.Val);
|
|
|
|
}
|
|
|
|
*Len = MFEs.size();
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMDisposeModuleFlagsMetadata(LLVMModuleFlagEntry *Entries) {
|
|
|
|
free(Entries);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMModuleFlagBehavior
|
|
|
|
LLVMModuleFlagEntriesGetFlagBehavior(LLVMModuleFlagEntry *Entries,
|
|
|
|
unsigned Index) {
|
|
|
|
LLVMOpaqueModuleFlagEntry MFE =
|
|
|
|
static_cast<LLVMOpaqueModuleFlagEntry>(Entries[Index]);
|
|
|
|
return MFE.Behavior;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMModuleFlagEntriesGetKey(LLVMModuleFlagEntry *Entries,
|
|
|
|
unsigned Index, size_t *Len) {
|
|
|
|
LLVMOpaqueModuleFlagEntry MFE =
|
|
|
|
static_cast<LLVMOpaqueModuleFlagEntry>(Entries[Index]);
|
|
|
|
*Len = MFE.KeyLen;
|
|
|
|
return MFE.Key;
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMMetadataRef LLVMModuleFlagEntriesGetMetadata(LLVMModuleFlagEntry *Entries,
|
|
|
|
unsigned Index) {
|
|
|
|
LLVMOpaqueModuleFlagEntry MFE =
|
|
|
|
static_cast<LLVMOpaqueModuleFlagEntry>(Entries[Index]);
|
|
|
|
return MFE.Metadata;
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMMetadataRef LLVMGetModuleFlag(LLVMModuleRef M,
|
|
|
|
const char *Key, size_t KeyLen) {
|
|
|
|
return wrap(unwrap(M)->getModuleFlag({Key, KeyLen}));
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMAddModuleFlag(LLVMModuleRef M, LLVMModuleFlagBehavior Behavior,
|
|
|
|
const char *Key, size_t KeyLen,
|
|
|
|
LLVMMetadataRef Val) {
|
|
|
|
unwrap(M)->addModuleFlag(map_to_llvmModFlagBehavior(Behavior),
|
|
|
|
{Key, KeyLen}, unwrap(Val));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Printing modules ....................................................--*/
|
|
|
|
|
2017-01-29 18:52:03 +01:00
|
|
|
void LLVMDumpModule(LLVMModuleRef M) {
|
|
|
|
unwrap(M)->print(errs(), nullptr,
|
|
|
|
/*ShouldPreserveUseListOrder=*/false, /*IsForDebug=*/true);
|
2008-03-15 00:58:56 +01:00
|
|
|
}
|
|
|
|
|
2012-05-09 18:54:17 +02:00
|
|
|
LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename,
|
|
|
|
char **ErrorMessage) {
|
2014-08-25 20:16:47 +02:00
|
|
|
std::error_code EC;
|
2021-04-06 13:22:41 +02:00
|
|
|
raw_fd_ostream dest(Filename, EC, sys::fs::OF_TextWithCRLF);
|
2014-08-25 20:16:47 +02:00
|
|
|
if (EC) {
|
|
|
|
*ErrorMessage = strdup(EC.message().c_str());
|
2012-05-09 18:54:17 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-04-09 08:08:46 +02:00
|
|
|
unwrap(M)->print(dest, nullptr);
|
2012-05-09 18:54:17 +02:00
|
|
|
|
2014-08-25 20:16:47 +02:00
|
|
|
dest.close();
|
|
|
|
|
|
|
|
if (dest.has_error()) {
|
2017-10-24 03:26:22 +02:00
|
|
|
std::string E = "Error printing to file: " + dest.error().message();
|
|
|
|
*ErrorMessage = strdup(E.c_str());
|
2012-05-09 18:54:17 +02:00
|
|
|
return true;
|
|
|
|
}
|
2014-08-25 20:16:47 +02:00
|
|
|
|
2012-05-09 18:54:17 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-10-16 20:00:54 +02:00
|
|
|
char *LLVMPrintModuleToString(LLVMModuleRef M) {
|
2014-06-27 00:52:05 +02:00
|
|
|
std::string buf;
|
|
|
|
raw_string_ostream os(buf);
|
|
|
|
|
2014-04-09 08:08:46 +02:00
|
|
|
unwrap(M)->print(os, nullptr);
|
2014-06-27 00:52:05 +02:00
|
|
|
os.flush();
|
|
|
|
|
|
|
|
return strdup(buf.c_str());
|
2013-10-16 20:00:54 +02:00
|
|
|
}
|
|
|
|
|
2010-04-10 19:52:58 +02:00
|
|
|
/*--.. Operations on inline assembler ......................................--*/
|
2018-04-06 04:31:29 +02:00
|
|
|
void LLVMSetModuleInlineAsm2(LLVMModuleRef M, const char *Asm, size_t Len) {
|
|
|
|
unwrap(M)->setModuleInlineAsm(StringRef(Asm, Len));
|
|
|
|
}
|
|
|
|
|
2010-04-10 19:52:58 +02:00
|
|
|
void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm) {
|
|
|
|
unwrap(M)->setModuleInlineAsm(StringRef(Asm));
|
|
|
|
}
|
|
|
|
|
2018-04-06 04:31:29 +02:00
|
|
|
void LLVMAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm, size_t Len) {
|
|
|
|
unwrap(M)->appendModuleInlineAsm(StringRef(Asm, Len));
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMGetModuleInlineAsm(LLVMModuleRef M, size_t *Len) {
|
|
|
|
auto &Str = unwrap(M)->getModuleInlineAsm();
|
|
|
|
*Len = Str.length();
|
|
|
|
return Str.c_str();
|
|
|
|
}
|
|
|
|
|
2021-05-13 20:05:11 +02:00
|
|
|
LLVMValueRef LLVMGetInlineAsm(LLVMTypeRef Ty, char *AsmString,
|
|
|
|
size_t AsmStringSize, char *Constraints,
|
|
|
|
size_t ConstraintsSize, LLVMBool HasSideEffects,
|
|
|
|
LLVMBool IsAlignStack,
|
|
|
|
LLVMInlineAsmDialect Dialect, LLVMBool CanThrow) {
|
2018-04-06 04:31:29 +02:00
|
|
|
InlineAsm::AsmDialect AD;
|
|
|
|
switch (Dialect) {
|
|
|
|
case LLVMInlineAsmDialectATT:
|
|
|
|
AD = InlineAsm::AD_ATT;
|
2018-04-10 20:10:10 +02:00
|
|
|
break;
|
2018-04-06 04:31:29 +02:00
|
|
|
case LLVMInlineAsmDialectIntel:
|
|
|
|
AD = InlineAsm::AD_Intel;
|
2018-04-10 20:10:10 +02:00
|
|
|
break;
|
2018-04-06 04:31:29 +02:00
|
|
|
}
|
|
|
|
return wrap(InlineAsm::get(unwrap<FunctionType>(Ty),
|
|
|
|
StringRef(AsmString, AsmStringSize),
|
|
|
|
StringRef(Constraints, ConstraintsSize),
|
2021-05-13 20:05:11 +02:00
|
|
|
HasSideEffects, IsAlignStack, AD, CanThrow));
|
2018-04-06 04:31:29 +02:00
|
|
|
}
|
|
|
|
|
2010-11-28 21:03:44 +01:00
|
|
|
/*--.. Operations on module contexts ......................................--*/
|
|
|
|
LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M) {
|
|
|
|
return wrap(&unwrap(M)->getContext());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*===-- Operations on types -----------------------------------------------===*/
|
|
|
|
|
|
|
|
/*--.. Operations on all types (mostly) ....................................--*/
|
|
|
|
|
|
|
|
LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
|
2009-07-16 00:00:31 +02:00
|
|
|
switch (unwrap(Ty)->getTypeID()) {
|
|
|
|
case Type::VoidTyID:
|
|
|
|
return LLVMVoidTypeKind;
|
2011-12-17 01:04:22 +01:00
|
|
|
case Type::HalfTyID:
|
|
|
|
return LLVMHalfTypeKind;
|
[IR][BFloat] Add BFloat IR type
Summary:
The BFloat IR type is introduced to provide support for, initially, the BFloat16
datatype introduced with the Armv8.6 architecture (optional from Armv8.2
onwards). It has an 8-bit exponent and a 7-bit mantissa and behaves like an IEEE
754 floating point IR type.
This is part of a patch series upstreaming Armv8.6 features. Subsequent patches
will upstream intrinsics support and C-lang support for BFloat.
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, sdesmalen, deadalnix, ctetreau
Subscribers: hiraditya, llvm-commits, danielkiss, arphaman, kristof.beyls, dexonsmith
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78190
2020-04-01 00:49:38 +02:00
|
|
|
case Type::BFloatTyID:
|
|
|
|
return LLVMBFloatTypeKind;
|
2009-07-16 00:00:31 +02:00
|
|
|
case Type::FloatTyID:
|
|
|
|
return LLVMFloatTypeKind;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
return LLVMDoubleTypeKind;
|
|
|
|
case Type::X86_FP80TyID:
|
|
|
|
return LLVMX86_FP80TypeKind;
|
|
|
|
case Type::FP128TyID:
|
|
|
|
return LLVMFP128TypeKind;
|
|
|
|
case Type::PPC_FP128TyID:
|
|
|
|
return LLVMPPC_FP128TypeKind;
|
|
|
|
case Type::LabelTyID:
|
|
|
|
return LLVMLabelTypeKind;
|
|
|
|
case Type::MetadataTyID:
|
|
|
|
return LLVMMetadataTypeKind;
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
return LLVMIntegerTypeKind;
|
|
|
|
case Type::FunctionTyID:
|
|
|
|
return LLVMFunctionTypeKind;
|
|
|
|
case Type::StructTyID:
|
|
|
|
return LLVMStructTypeKind;
|
|
|
|
case Type::ArrayTyID:
|
|
|
|
return LLVMArrayTypeKind;
|
|
|
|
case Type::PointerTyID:
|
|
|
|
return LLVMPointerTypeKind;
|
2020-05-15 19:45:42 +02:00
|
|
|
case Type::FixedVectorTyID:
|
|
|
|
return LLVMVectorTypeKind;
|
2010-09-10 22:55:01 +02:00
|
|
|
case Type::X86_MMXTyID:
|
|
|
|
return LLVMX86_MMXTypeKind;
|
2020-11-20 08:19:34 +01:00
|
|
|
case Type::X86_AMXTyID:
|
|
|
|
return LLVMX86_AMXTypeKind;
|
2015-08-14 07:09:07 +02:00
|
|
|
case Type::TokenTyID:
|
|
|
|
return LLVMTokenTypeKind;
|
[SVE] Add new VectorType subclasses
Summary:
Introduce new types for fixed width and scalable vectors.
Does not remove getNumElements yet so as to not break code during transition
period.
Reviewers: deadalnix, efriedma, sdesmalen, craig.topper, huntergr
Reviewed By: sdesmalen
Subscribers: jholewinski, arsenm, jvesely, nhaehnle, mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, csigg, arpith-jacob, mgester, lucyrfox, liufengdb, kerbowa, Joonsoo, grosul1, frgossen, lldb-commits, tschuett, hiraditya, rkruppe, psnobl, llvm-commits
Tags: #llvm, #lldb
Differential Revision: https://reviews.llvm.org/D77587
2020-04-22 17:02:02 +02:00
|
|
|
case Type::ScalableVectorTyID:
|
|
|
|
return LLVMScalableVectorTypeKind;
|
2009-07-16 00:00:31 +02:00
|
|
|
}
|
2013-12-07 03:27:52 +01:00
|
|
|
llvm_unreachable("Unhandled TypeID.");
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2011-10-06 14:13:28 +02:00
|
|
|
LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty)
|
|
|
|
{
|
|
|
|
return unwrap(Ty)->isSized();
|
|
|
|
}
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty) {
|
|
|
|
return wrap(&unwrap(Ty)->getContext());
|
|
|
|
}
|
|
|
|
|
2018-04-17 16:52:43 +02:00
|
|
|
void LLVMDumpType(LLVMTypeRef Ty) {
|
|
|
|
return unwrap(Ty)->print(errs(), /*IsForDebug=*/true);
|
2013-10-16 23:30:25 +02:00
|
|
|
}
|
|
|
|
|
2013-10-22 08:58:34 +02:00
|
|
|
char *LLVMPrintTypeToString(LLVMTypeRef Ty) {
|
2014-06-27 00:52:05 +02:00
|
|
|
std::string buf;
|
|
|
|
raw_string_ostream os(buf);
|
2013-10-22 08:58:34 +02:00
|
|
|
|
2014-06-21 04:43:02 +02:00
|
|
|
if (unwrap(Ty))
|
|
|
|
unwrap(Ty)->print(os);
|
|
|
|
else
|
|
|
|
os << "Printing <null> Type";
|
|
|
|
|
2014-06-27 00:52:05 +02:00
|
|
|
os.flush();
|
|
|
|
|
|
|
|
return strdup(buf.c_str());
|
2013-10-22 08:58:34 +02:00
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*--.. Operations on integer types .........................................--*/
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getInt1Ty(*unwrap(C));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMInt8TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getInt8Ty(*unwrap(C));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMInt16TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getInt16Ty(*unwrap(C));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMInt32TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getInt32Ty(*unwrap(C));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMInt64TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getInt64Ty(*unwrap(C));
|
|
|
|
}
|
2015-04-17 17:32:15 +02:00
|
|
|
LLVMTypeRef LLVMInt128TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getInt128Ty(*unwrap(C));
|
|
|
|
}
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMTypeRef LLVMIntTypeInContext(LLVMContextRef C, unsigned NumBits) {
|
|
|
|
return wrap(IntegerType::get(*unwrap(C), NumBits));
|
|
|
|
}
|
|
|
|
|
2009-08-13 23:58:54 +02:00
|
|
|
LLVMTypeRef LLVMInt1Type(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMInt1TypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMInt8Type(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMInt8TypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMInt16Type(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMInt16TypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMInt32Type(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMInt32TypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMInt64Type(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMInt64TypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
2015-04-17 17:32:15 +02:00
|
|
|
LLVMTypeRef LLVMInt128Type(void) {
|
|
|
|
return LLVMInt128TypeInContext(LLVMGetGlobalContext());
|
|
|
|
}
|
2007-10-06 18:05:20 +02:00
|
|
|
LLVMTypeRef LLVMIntType(unsigned NumBits) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMIntTypeInContext(LLVMGetGlobalContext(), NumBits);
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return unwrap<IntegerType>(IntegerTy)->getBitWidth();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Operations on real types ............................................--*/
|
|
|
|
|
2011-12-17 01:04:22 +01:00
|
|
|
LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getHalfTy(*unwrap(C));
|
|
|
|
}
|
[IR][BFloat] Add BFloat IR type
Summary:
The BFloat IR type is introduced to provide support for, initially, the BFloat16
datatype introduced with the Armv8.6 architecture (optional from Armv8.2
onwards). It has an 8-bit exponent and a 7-bit mantissa and behaves like an IEEE
754 floating point IR type.
This is part of a patch series upstreaming Armv8.6 features. Subsequent patches
will upstream intrinsics support and C-lang support for BFloat.
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, sdesmalen, deadalnix, ctetreau
Subscribers: hiraditya, llvm-commits, danielkiss, arphaman, kristof.beyls, dexonsmith
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78190
2020-04-01 00:49:38 +02:00
|
|
|
LLVMTypeRef LLVMBFloatTypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getBFloatTy(*unwrap(C));
|
|
|
|
}
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getFloatTy(*unwrap(C));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getDoubleTy(*unwrap(C));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMX86FP80TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getX86_FP80Ty(*unwrap(C));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getFP128Ty(*unwrap(C));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getPPC_FP128Ty(*unwrap(C));
|
|
|
|
}
|
2010-09-10 22:55:01 +02:00
|
|
|
LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getX86_MMXTy(*unwrap(C));
|
|
|
|
}
|
2020-11-20 08:19:34 +01:00
|
|
|
LLVMTypeRef LLVMX86AMXTypeInContext(LLVMContextRef C) {
|
|
|
|
return (LLVMTypeRef) Type::getX86_AMXTy(*unwrap(C));
|
|
|
|
}
|
2009-08-14 02:01:31 +02:00
|
|
|
|
2011-12-17 01:04:22 +01:00
|
|
|
LLVMTypeRef LLVMHalfType(void) {
|
|
|
|
return LLVMHalfTypeInContext(LLVMGetGlobalContext());
|
|
|
|
}
|
[IR][BFloat] Add BFloat IR type
Summary:
The BFloat IR type is introduced to provide support for, initially, the BFloat16
datatype introduced with the Armv8.6 architecture (optional from Armv8.2
onwards). It has an 8-bit exponent and a 7-bit mantissa and behaves like an IEEE
754 floating point IR type.
This is part of a patch series upstreaming Armv8.6 features. Subsequent patches
will upstream intrinsics support and C-lang support for BFloat.
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, sdesmalen, deadalnix, ctetreau
Subscribers: hiraditya, llvm-commits, danielkiss, arphaman, kristof.beyls, dexonsmith
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78190
2020-04-01 00:49:38 +02:00
|
|
|
LLVMTypeRef LLVMBFloatType(void) {
|
|
|
|
return LLVMBFloatTypeInContext(LLVMGetGlobalContext());
|
|
|
|
}
|
2009-08-13 23:58:54 +02:00
|
|
|
LLVMTypeRef LLVMFloatType(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMFloatTypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMDoubleType(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMDoubleTypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMX86FP80Type(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMX86FP80TypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMFP128Type(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMFP128TypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMPPCFP128Type(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMPPCFP128TypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
2010-09-10 22:55:01 +02:00
|
|
|
LLVMTypeRef LLVMX86MMXType(void) {
|
|
|
|
return LLVMX86MMXTypeInContext(LLVMGetGlobalContext());
|
|
|
|
}
|
2020-11-20 08:19:34 +01:00
|
|
|
LLVMTypeRef LLVMX86AMXType(void) {
|
|
|
|
return LLVMX86AMXTypeInContext(LLVMGetGlobalContext());
|
|
|
|
}
|
2007-09-18 05:18:57 +02:00
|
|
|
|
|
|
|
/*--.. Operations on function types ........................................--*/
|
|
|
|
|
2007-10-06 18:05:20 +02:00
|
|
|
LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType,
|
|
|
|
LLVMTypeRef *ParamTypes, unsigned ParamCount,
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool IsVarArg) {
|
2011-07-14 13:44:09 +02:00
|
|
|
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
|
2009-07-30 00:17:13 +02:00
|
|
|
return wrap(FunctionType::get(unwrap(ReturnType), Tys, IsVarArg != 0));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return unwrap<FunctionType>(FunctionTy)->isVarArg();
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return wrap(unwrap<FunctionType>(FunctionTy)->getReturnType());
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return unwrap<FunctionType>(FunctionTy)->getNumParams();
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) {
|
2007-09-18 05:18:57 +02:00
|
|
|
FunctionType *Ty = unwrap<FunctionType>(FunctionTy);
|
2021-02-27 19:09:25 +01:00
|
|
|
for (Type *T : Ty->params())
|
|
|
|
*Dest++ = wrap(T);
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Operations on struct types ..........................................--*/
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
|
2010-01-09 23:27:07 +01:00
|
|
|
unsigned ElementCount, LLVMBool Packed) {
|
2011-07-14 13:44:09 +02:00
|
|
|
ArrayRef<Type*> Tys(unwrap(ElementTypes), ElementCount);
|
2009-08-14 02:01:31 +02:00
|
|
|
return wrap(StructType::get(*unwrap(C), Tys, Packed != 0));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes,
|
2010-01-09 23:27:07 +01:00
|
|
|
unsigned ElementCount, LLVMBool Packed) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMStructTypeInContext(LLVMGetGlobalContext(), ElementTypes,
|
|
|
|
ElementCount, Packed);
|
|
|
|
}
|
|
|
|
|
2011-07-14 07:53:17 +02:00
|
|
|
LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name)
|
|
|
|
{
|
2011-08-12 20:07:07 +02:00
|
|
|
return wrap(StructType::create(*unwrap(C), Name));
|
2011-07-14 07:53:17 +02:00
|
|
|
}
|
|
|
|
|
2011-10-06 14:12:50 +02:00
|
|
|
const char *LLVMGetStructName(LLVMTypeRef Ty)
|
|
|
|
{
|
2011-10-14 22:37:42 +02:00
|
|
|
StructType *Type = unwrap<StructType>(Ty);
|
|
|
|
if (!Type->hasName())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2011-10-14 22:37:42 +02:00
|
|
|
return Type->getName().data();
|
2011-10-06 14:12:50 +02:00
|
|
|
}
|
|
|
|
|
2011-07-14 07:53:17 +02:00
|
|
|
void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes,
|
|
|
|
unsigned ElementCount, LLVMBool Packed) {
|
2011-07-14 13:44:09 +02:00
|
|
|
ArrayRef<Type*> Tys(unwrap(ElementTypes), ElementCount);
|
2011-07-14 07:53:17 +02:00
|
|
|
unwrap<StructType>(StructTy)->setBody(Tys, Packed != 0);
|
|
|
|
}
|
2009-08-14 02:01:31 +02:00
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return unwrap<StructType>(StructTy)->getNumElements();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest) {
|
|
|
|
StructType *Ty = unwrap<StructType>(StructTy);
|
2021-02-27 19:09:25 +01:00
|
|
|
for (Type *T : Ty->elements())
|
|
|
|
*Dest++ = wrap(T);
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2015-06-04 11:09:53 +02:00
|
|
|
LLVMTypeRef LLVMStructGetTypeAtIndex(LLVMTypeRef StructTy, unsigned i) {
|
|
|
|
StructType *Ty = unwrap<StructType>(StructTy);
|
|
|
|
return wrap(Ty->getTypeAtIndex(i));
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return unwrap<StructType>(StructTy)->isPacked();
|
|
|
|
}
|
|
|
|
|
2011-07-14 18:20:28 +02:00
|
|
|
LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy) {
|
|
|
|
return unwrap<StructType>(StructTy)->isOpaque();
|
|
|
|
}
|
|
|
|
|
2018-09-18 03:47:37 +02:00
|
|
|
LLVMBool LLVMIsLiteralStruct(LLVMTypeRef StructTy) {
|
|
|
|
return unwrap<StructType>(StructTy)->isLiteral();
|
|
|
|
}
|
|
|
|
|
2011-07-14 18:20:28 +02:00
|
|
|
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name) {
|
2020-11-30 20:34:12 +01:00
|
|
|
return wrap(StructType::getTypeByName(unwrap(M)->getContext(), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMTypeRef LLVMGetTypeByName2(LLVMContextRef C, const char *Name) {
|
|
|
|
return wrap(StructType::getTypeByName(*unwrap(C), Name));
|
2011-07-14 18:20:28 +02:00
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*--.. Operations on array, pointer, and vector types (sequence types) .....--*/
|
|
|
|
|
2017-06-05 13:49:52 +02:00
|
|
|
void LLVMGetSubtypes(LLVMTypeRef Tp, LLVMTypeRef *Arr) {
|
|
|
|
int i = 0;
|
|
|
|
for (auto *T : unwrap(Tp)->subtypes()) {
|
|
|
|
Arr[i] = wrap(T);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-17 17:08:32 +01:00
|
|
|
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount) {
|
2009-07-30 00:17:13 +02:00
|
|
|
return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2007-12-17 17:08:32 +01:00
|
|
|
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace) {
|
2009-07-30 00:17:13 +02:00
|
|
|
return wrap(PointerType::get(unwrap(ElementType), AddressSpace));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2007-12-17 17:08:32 +01:00
|
|
|
LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount) {
|
2020-06-03 22:35:41 +02:00
|
|
|
return wrap(FixedVectorType::get(unwrap(ElementType), ElementCount));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2020-10-28 21:48:22 +01:00
|
|
|
LLVMTypeRef LLVMScalableVectorType(LLVMTypeRef ElementType,
|
|
|
|
unsigned ElementCount) {
|
|
|
|
return wrap(ScalableVectorType::get(unwrap(ElementType), ElementCount));
|
|
|
|
}
|
|
|
|
|
2016-12-02 04:05:41 +01:00
|
|
|
LLVMTypeRef LLVMGetElementType(LLVMTypeRef WrappedTy) {
|
|
|
|
auto *Ty = unwrap<Type>(WrappedTy);
|
|
|
|
if (auto *PTy = dyn_cast<PointerType>(Ty))
|
|
|
|
return wrap(PTy->getElementType());
|
2020-04-07 02:03:49 +02:00
|
|
|
if (auto *ATy = dyn_cast<ArrayType>(Ty))
|
|
|
|
return wrap(ATy->getElementType());
|
|
|
|
return wrap(cast<VectorType>(Ty)->getElementType());
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2017-06-05 13:49:52 +02:00
|
|
|
unsigned LLVMGetNumContainedTypes(LLVMTypeRef Tp) {
|
|
|
|
return unwrap(Tp)->getNumContainedTypes();
|
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy) {
|
|
|
|
return unwrap<ArrayType>(ArrayTy)->getNumElements();
|
|
|
|
}
|
|
|
|
|
2007-12-17 17:08:32 +01:00
|
|
|
unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy) {
|
|
|
|
return unwrap<PointerType>(PointerTy)->getAddressSpace();
|
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy) {
|
2020-08-14 13:15:59 +02:00
|
|
|
return unwrap<VectorType>(VectorTy)->getElementCount().getKnownMinValue();
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Operations on other types ...........................................--*/
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C) {
|
|
|
|
return wrap(Type::getVoidTy(*unwrap(C)));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C) {
|
|
|
|
return wrap(Type::getLabelTy(*unwrap(C)));
|
|
|
|
}
|
2017-10-27 13:51:40 +02:00
|
|
|
LLVMTypeRef LLVMTokenTypeInContext(LLVMContextRef C) {
|
|
|
|
return wrap(Type::getTokenTy(*unwrap(C)));
|
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
|
|
|
|
return wrap(Type::getMetadataTy(*unwrap(C)));
|
|
|
|
}
|
2009-08-14 02:01:31 +02:00
|
|
|
|
2009-08-13 23:58:54 +02:00
|
|
|
LLVMTypeRef LLVMVoidType(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMVoidTypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
|
|
|
LLVMTypeRef LLVMLabelType(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMLabelTypeInContext(LLVMGetGlobalContext());
|
2009-08-13 23:58:54 +02:00
|
|
|
}
|
2007-09-18 05:18:57 +02:00
|
|
|
|
|
|
|
/*===-- Operations on values ----------------------------------------------===*/
|
|
|
|
|
|
|
|
/*--.. Operations on all values ............................................--*/
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMTypeRef LLVMTypeOf(LLVMValueRef Val) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return wrap(unwrap(Val)->getType());
|
|
|
|
}
|
|
|
|
|
2016-04-07 00:21:29 +02:00
|
|
|
LLVMValueKind LLVMGetValueKind(LLVMValueRef Val) {
|
|
|
|
switch(unwrap(Val)->getValueID()) {
|
2020-04-02 00:25:04 +02:00
|
|
|
#define LLVM_C_API 1
|
2016-04-07 00:21:29 +02:00
|
|
|
#define HANDLE_VALUE(Name) \
|
|
|
|
case Value::Name##Val: \
|
|
|
|
return LLVM##Name##ValueKind;
|
|
|
|
#include "llvm/IR/Value.def"
|
|
|
|
default:
|
|
|
|
return LLVMInstructionValueKind;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-19 17:08:36 +02:00
|
|
|
const char *LLVMGetValueName2(LLVMValueRef Val, size_t *Length) {
|
|
|
|
auto *V = unwrap(Val);
|
|
|
|
*Length = V->getName().size();
|
|
|
|
return V->getName().data();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetValueName2(LLVMValueRef Val, const char *Name, size_t NameLen) {
|
|
|
|
unwrap(Val)->setName(StringRef(Name, NameLen));
|
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
const char *LLVMGetValueName(LLVMValueRef Val) {
|
2009-07-26 09:49:05 +02:00
|
|
|
return unwrap(Val)->getName().data();
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetValueName(LLVMValueRef Val, const char *Name) {
|
|
|
|
unwrap(Val)->setName(Name);
|
|
|
|
}
|
|
|
|
|
2018-04-17 16:52:43 +02:00
|
|
|
void LLVMDumpValue(LLVMValueRef Val) {
|
2017-01-30 06:40:52 +01:00
|
|
|
unwrap(Val)->print(errs(), /*IsForDebug=*/true);
|
2007-10-06 02:08:49 +02:00
|
|
|
}
|
|
|
|
|
2013-11-06 10:21:01 +01:00
|
|
|
char* LLVMPrintValueToString(LLVMValueRef Val) {
|
2014-06-27 00:52:05 +02:00
|
|
|
std::string buf;
|
|
|
|
raw_string_ostream os(buf);
|
2013-11-06 10:21:01 +01:00
|
|
|
|
2014-06-21 04:43:02 +02:00
|
|
|
if (unwrap(Val))
|
|
|
|
unwrap(Val)->print(os);
|
|
|
|
else
|
|
|
|
os << "Printing <null> Value";
|
|
|
|
|
2014-06-27 00:52:05 +02:00
|
|
|
os.flush();
|
|
|
|
|
|
|
|
return strdup(buf.c_str());
|
2013-11-06 10:21:01 +01:00
|
|
|
}
|
|
|
|
|
2009-10-12 06:01:02 +02:00
|
|
|
void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) {
|
|
|
|
unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal));
|
|
|
|
}
|
2008-12-19 19:39:45 +01:00
|
|
|
|
2010-02-28 10:45:59 +01:00
|
|
|
int LLVMHasMetadata(LLVMValueRef Inst) {
|
|
|
|
return unwrap<Instruction>(Inst)->hasMetadata();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) {
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
auto *I = unwrap<Instruction>(Inst);
|
|
|
|
assert(I && "Expected instruction");
|
|
|
|
if (auto *MD = I->getMetadata(KindID))
|
|
|
|
return wrap(MetadataAsValue::get(I->getContext(), MD));
|
|
|
|
return nullptr;
|
2010-02-28 10:45:59 +01:00
|
|
|
}
|
|
|
|
|
2015-01-28 17:35:59 +01:00
|
|
|
// MetadataAsValue uses a canonical format which strips the actual MDNode for
|
|
|
|
// MDNode with just a single constant value, storing just a ConstantAsMetadata
|
|
|
|
// This undoes this canonicalization, reconstructing the MDNode.
|
|
|
|
static MDNode *extractMDNode(MetadataAsValue *MAV) {
|
|
|
|
Metadata *MD = MAV->getMetadata();
|
|
|
|
assert((isa<MDNode>(MD) || isa<ConstantAsMetadata>(MD)) &&
|
|
|
|
"Expected a metadata node or a canonicalized constant");
|
|
|
|
|
|
|
|
if (MDNode *N = dyn_cast<MDNode>(MD))
|
|
|
|
return N;
|
|
|
|
|
|
|
|
return MDNode::get(MAV->getContext(), MD);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) {
|
|
|
|
MDNode *N = Val ? extractMDNode(unwrap<MetadataAsValue>(Val)) : nullptr;
|
|
|
|
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
unwrap<Instruction>(Inst)->setMetadata(KindID, N);
|
2010-02-28 10:45:59 +01:00
|
|
|
}
|
|
|
|
|
2018-09-28 18:02:26 +02:00
|
|
|
struct LLVMOpaqueValueMetadataEntry {
|
|
|
|
unsigned Kind;
|
|
|
|
LLVMMetadataRef Metadata;
|
|
|
|
};
|
|
|
|
|
|
|
|
using MetadataEntries = SmallVectorImpl<std::pair<unsigned, MDNode *>>;
|
|
|
|
static LLVMValueMetadataEntry *
|
|
|
|
llvm_getMetadata(size_t *NumEntries,
|
|
|
|
llvm::function_ref<void(MetadataEntries &)> AccessMD) {
|
|
|
|
SmallVector<std::pair<unsigned, MDNode *>, 8> MVEs;
|
|
|
|
AccessMD(MVEs);
|
|
|
|
|
|
|
|
LLVMOpaqueValueMetadataEntry *Result =
|
|
|
|
static_cast<LLVMOpaqueValueMetadataEntry *>(
|
|
|
|
safe_malloc(MVEs.size() * sizeof(LLVMOpaqueValueMetadataEntry)));
|
|
|
|
for (unsigned i = 0; i < MVEs.size(); ++i) {
|
|
|
|
const auto &ModuleFlag = MVEs[i];
|
|
|
|
Result[i].Kind = ModuleFlag.first;
|
|
|
|
Result[i].Metadata = wrap(ModuleFlag.second);
|
|
|
|
}
|
|
|
|
*NumEntries = MVEs.size();
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2018-09-28 17:35:18 +02:00
|
|
|
LLVMValueMetadataEntry *
|
|
|
|
LLVMInstructionGetAllMetadataOtherThanDebugLoc(LLVMValueRef Value,
|
|
|
|
size_t *NumEntries) {
|
|
|
|
return llvm_getMetadata(NumEntries, [&Value](MetadataEntries &Entries) {
|
2019-09-13 19:21:24 +02:00
|
|
|
Entries.clear();
|
2018-09-28 17:35:18 +02:00
|
|
|
unwrap<Instruction>(Value)->getAllMetadata(Entries);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2008-12-19 19:39:45 +01:00
|
|
|
/*--.. Conversion functions ................................................--*/
|
|
|
|
|
|
|
|
#define LLVM_DEFINE_VALUE_CAST(name) \
|
|
|
|
LLVMValueRef LLVMIsA##name(LLVMValueRef Val) { \
|
|
|
|
return wrap(static_cast<Value*>(dyn_cast_or_null<name>(unwrap(Val)))); \
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DEFINE_VALUE_CAST)
|
|
|
|
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val) {
|
|
|
|
if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val)))
|
|
|
|
if (isa<MDNode>(MD->getMetadata()) ||
|
|
|
|
isa<ValueAsMetadata>(MD->getMetadata()))
|
|
|
|
return Val;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMIsAMDString(LLVMValueRef Val) {
|
|
|
|
if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val)))
|
|
|
|
if (isa<MDString>(MD->getMetadata()))
|
|
|
|
return Val;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2009-10-12 06:01:02 +02:00
|
|
|
/*--.. Operations on Uses ..................................................--*/
|
2010-03-02 21:32:28 +01:00
|
|
|
LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) {
|
2009-10-12 06:01:02 +02:00
|
|
|
Value *V = unwrap(Val);
|
|
|
|
Value::use_iterator I = V->use_begin();
|
|
|
|
if (I == V->use_end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2014-03-09 04:16:01 +01:00
|
|
|
return wrap(&*I);
|
2009-10-12 06:01:02 +02:00
|
|
|
}
|
|
|
|
|
2010-03-02 21:32:28 +01:00
|
|
|
LLVMUseRef LLVMGetNextUse(LLVMUseRef U) {
|
|
|
|
Use *Next = unwrap(U)->getNext();
|
|
|
|
if (Next)
|
|
|
|
return wrap(Next);
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2009-10-12 06:01:02 +02:00
|
|
|
}
|
|
|
|
|
2010-03-02 21:32:28 +01:00
|
|
|
LLVMValueRef LLVMGetUser(LLVMUseRef U) {
|
|
|
|
return wrap(unwrap(U)->getUser());
|
2009-10-12 06:01:02 +02:00
|
|
|
}
|
|
|
|
|
2010-03-02 21:32:28 +01:00
|
|
|
LLVMValueRef LLVMGetUsedValue(LLVMUseRef U) {
|
|
|
|
return wrap(unwrap(U)->get());
|
2009-10-12 06:01:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Operations on Users .................................................--*/
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
|
|
|
|
static LLVMValueRef getMDNodeOperandImpl(LLVMContext &Context, const MDNode *N,
|
|
|
|
unsigned Index) {
|
|
|
|
Metadata *Op = N->getOperand(Index);
|
|
|
|
if (!Op)
|
|
|
|
return nullptr;
|
|
|
|
if (auto *C = dyn_cast<ConstantAsMetadata>(Op))
|
|
|
|
return wrap(C->getValue());
|
|
|
|
return wrap(MetadataAsValue::get(Context, Op));
|
|
|
|
}
|
|
|
|
|
2009-10-12 06:01:02 +02:00
|
|
|
LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index) {
|
2011-10-06 14:13:11 +02:00
|
|
|
Value *V = unwrap(Val);
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
|
|
|
|
if (auto *L = dyn_cast<ValueAsMetadata>(MD->getMetadata())) {
|
|
|
|
assert(Index == 0 && "Function-local metadata can only have one operand");
|
|
|
|
return wrap(L->getValue());
|
|
|
|
}
|
|
|
|
return getMDNodeOperandImpl(V->getContext(),
|
|
|
|
cast<MDNode>(MD->getMetadata()), Index);
|
|
|
|
}
|
|
|
|
|
2011-10-06 14:13:11 +02:00
|
|
|
return wrap(cast<User>(V)->getOperand(Index));
|
2009-10-12 06:01:02 +02:00
|
|
|
}
|
2008-12-19 19:39:45 +01:00
|
|
|
|
2014-08-12 04:55:40 +02:00
|
|
|
LLVMUseRef LLVMGetOperandUse(LLVMValueRef Val, unsigned Index) {
|
|
|
|
Value *V = unwrap(Val);
|
|
|
|
return wrap(&cast<User>(V)->getOperandUse(Index));
|
|
|
|
}
|
|
|
|
|
2010-08-20 16:51:22 +02:00
|
|
|
void LLVMSetOperand(LLVMValueRef Val, unsigned Index, LLVMValueRef Op) {
|
|
|
|
unwrap<User>(Val)->setOperand(Index, unwrap(Op));
|
|
|
|
}
|
|
|
|
|
|
|
|
int LLVMGetNumOperands(LLVMValueRef Val) {
|
2011-10-06 14:13:11 +02:00
|
|
|
Value *V = unwrap(Val);
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
if (isa<MetadataAsValue>(V))
|
|
|
|
return LLVMGetMDNodeNumOperands(Val);
|
|
|
|
|
2011-10-06 14:13:11 +02:00
|
|
|
return cast<User>(V)->getNumOperands();
|
2010-08-20 16:51:22 +02:00
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*--.. Operations on constants of any type .................................--*/
|
|
|
|
|
2007-10-06 17:11:06 +02:00
|
|
|
LLVMValueRef LLVMConstNull(LLVMTypeRef Ty) {
|
2009-07-31 22:28:14 +02:00
|
|
|
return wrap(Constant::getNullValue(unwrap(Ty)));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2007-10-06 17:11:06 +02:00
|
|
|
LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty) {
|
2009-07-31 22:28:14 +02:00
|
|
|
return wrap(Constant::getAllOnesValue(unwrap(Ty)));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty) {
|
2009-07-31 01:03:37 +02:00
|
|
|
return wrap(UndefValue::get(unwrap(Ty)));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2020-11-24 22:55:24 +01:00
|
|
|
LLVMValueRef LLVMGetPoison(LLVMTypeRef Ty) {
|
|
|
|
return wrap(PoisonValue::get(unwrap(Ty)));
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsConstant(LLVMValueRef Ty) {
|
2007-09-18 20:07:51 +02:00
|
|
|
return isa<Constant>(unwrap(Ty));
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsNull(LLVMValueRef Val) {
|
2007-09-18 05:18:57 +02:00
|
|
|
if (Constant *C = dyn_cast<Constant>(unwrap(Val)))
|
|
|
|
return C->isNullValue();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsUndef(LLVMValueRef Val) {
|
2007-09-18 20:07:51 +02:00
|
|
|
return isa<UndefValue>(unwrap(Val));
|
|
|
|
}
|
|
|
|
|
2020-11-24 22:55:24 +01:00
|
|
|
LLVMBool LLVMIsPoison(LLVMValueRef Val) {
|
|
|
|
return isa<PoisonValue>(unwrap(Val));
|
|
|
|
}
|
|
|
|
|
2009-07-06 19:29:59 +02:00
|
|
|
LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) {
|
2016-04-26 00:23:35 +02:00
|
|
|
return wrap(ConstantPointerNull::get(unwrap<PointerType>(Ty)));
|
2009-07-06 19:29:59 +02:00
|
|
|
}
|
|
|
|
|
2010-02-28 10:45:59 +01:00
|
|
|
/*--.. Operations on metadata nodes ........................................--*/
|
|
|
|
|
2019-04-24 19:05:08 +02:00
|
|
|
LLVMMetadataRef LLVMMDStringInContext2(LLVMContextRef C, const char *Str,
|
|
|
|
size_t SLen) {
|
|
|
|
return wrap(MDString::get(*unwrap(C), StringRef(Str, SLen)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMMetadataRef LLVMMDNodeInContext2(LLVMContextRef C, LLVMMetadataRef *MDs,
|
|
|
|
size_t Count) {
|
|
|
|
return wrap(MDNode::get(*unwrap(C), ArrayRef<Metadata*>(unwrap(MDs), Count)));
|
|
|
|
}
|
|
|
|
|
2010-02-28 10:45:59 +01:00
|
|
|
LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str,
|
|
|
|
unsigned SLen) {
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
LLVMContext &Context = *unwrap(C);
|
|
|
|
return wrap(MetadataAsValue::get(
|
|
|
|
Context, MDString::get(Context, StringRef(Str, SLen))));
|
2010-02-28 10:45:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) {
|
|
|
|
return LLVMMDStringInContext(LLVMGetGlobalContext(), Str, SLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
|
|
|
|
unsigned Count) {
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
LLVMContext &Context = *unwrap(C);
|
|
|
|
SmallVector<Metadata *, 8> MDs;
|
|
|
|
for (auto *OV : makeArrayRef(Vals, Count)) {
|
|
|
|
Value *V = unwrap(OV);
|
|
|
|
Metadata *MD;
|
|
|
|
if (!V)
|
|
|
|
MD = nullptr;
|
|
|
|
else if (auto *C = dyn_cast<Constant>(V))
|
|
|
|
MD = ConstantAsMetadata::get(C);
|
|
|
|
else if (auto *MDV = dyn_cast<MetadataAsValue>(V)) {
|
|
|
|
MD = MDV->getMetadata();
|
|
|
|
assert(!isa<LocalAsMetadata>(MD) && "Unexpected function-local metadata "
|
|
|
|
"outside of direct argument to call");
|
|
|
|
} else {
|
|
|
|
// This is function-local metadata. Pretend to make an MDNode.
|
|
|
|
assert(Count == 1 &&
|
|
|
|
"Expected only one operand to function-local metadata");
|
|
|
|
return wrap(MetadataAsValue::get(Context, LocalAsMetadata::get(V)));
|
|
|
|
}
|
|
|
|
|
|
|
|
MDs.push_back(MD);
|
|
|
|
}
|
|
|
|
return wrap(MetadataAsValue::get(Context, MDNode::get(Context, MDs)));
|
2010-02-28 10:45:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) {
|
|
|
|
return LLVMMDNodeInContext(LLVMGetGlobalContext(), Vals, Count);
|
|
|
|
}
|
|
|
|
|
2017-04-17 13:52:54 +02:00
|
|
|
LLVMValueRef LLVMMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
|
|
|
|
return wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val) {
|
|
|
|
auto *V = unwrap(Val);
|
|
|
|
if (auto *C = dyn_cast<Constant>(V))
|
|
|
|
return wrap(ConstantAsMetadata::get(C));
|
|
|
|
if (auto *MAV = dyn_cast<MetadataAsValue>(V))
|
|
|
|
return wrap(MAV->getMetadata());
|
|
|
|
return wrap(ValueAsMetadata::get(V));
|
|
|
|
}
|
|
|
|
|
2016-04-03 23:06:04 +02:00
|
|
|
const char *LLVMGetMDString(LLVMValueRef V, unsigned *Length) {
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
if (const auto *MD = dyn_cast<MetadataAsValue>(unwrap(V)))
|
|
|
|
if (const MDString *S = dyn_cast<MDString>(MD->getMetadata())) {
|
2016-04-03 23:06:04 +02:00
|
|
|
*Length = S->getString().size();
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
return S->getString().data();
|
|
|
|
}
|
2016-04-03 23:06:04 +02:00
|
|
|
*Length = 0;
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2011-10-06 14:13:11 +02:00
|
|
|
}
|
|
|
|
|
2016-04-23 02:12:45 +02:00
|
|
|
unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) {
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
auto *MD = cast<MetadataAsValue>(unwrap(V));
|
|
|
|
if (isa<ValueAsMetadata>(MD->getMetadata()))
|
|
|
|
return 1;
|
|
|
|
return cast<MDNode>(MD->getMetadata())->getNumOperands();
|
2012-09-19 22:29:39 +02:00
|
|
|
}
|
|
|
|
|
2018-08-30 19:09:43 +02:00
|
|
|
LLVMNamedMDNodeRef LLVMGetFirstNamedMetadata(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::named_metadata_iterator I = Mod->named_metadata_begin();
|
|
|
|
if (I == Mod->named_metadata_end())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMNamedMDNodeRef LLVMGetLastNamedMetadata(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::named_metadata_iterator I = Mod->named_metadata_end();
|
|
|
|
if (I == Mod->named_metadata_begin())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*--I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMNamedMDNodeRef LLVMGetNextNamedMetadata(LLVMNamedMDNodeRef NMD) {
|
|
|
|
NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
|
|
|
|
Module::named_metadata_iterator I(NamedNode);
|
|
|
|
if (++I == NamedNode->getParent()->named_metadata_end())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMNamedMDNodeRef LLVMGetPreviousNamedMetadata(LLVMNamedMDNodeRef NMD) {
|
|
|
|
NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
|
|
|
|
Module::named_metadata_iterator I(NamedNode);
|
|
|
|
if (I == NamedNode->getParent()->named_metadata_begin())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*--I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMNamedMDNodeRef LLVMGetNamedMetadata(LLVMModuleRef M,
|
|
|
|
const char *Name, size_t NameLen) {
|
|
|
|
return wrap(unwrap(M)->getNamedMetadata(StringRef(Name, NameLen)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMNamedMDNodeRef LLVMGetOrInsertNamedMetadata(LLVMModuleRef M,
|
|
|
|
const char *Name, size_t NameLen) {
|
|
|
|
return wrap(unwrap(M)->getOrInsertNamedMetadata({Name, NameLen}));
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMGetNamedMetadataName(LLVMNamedMDNodeRef NMD, size_t *NameLen) {
|
|
|
|
NamedMDNode *NamedNode = unwrap<NamedMDNode>(NMD);
|
|
|
|
*NameLen = NamedNode->getName().size();
|
|
|
|
return NamedNode->getName().data();
|
|
|
|
}
|
|
|
|
|
2016-04-23 02:12:45 +02:00
|
|
|
void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest) {
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
auto *MD = cast<MetadataAsValue>(unwrap(V));
|
|
|
|
if (auto *MDV = dyn_cast<ValueAsMetadata>(MD->getMetadata())) {
|
|
|
|
*Dest = wrap(MDV->getValue());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const auto *N = cast<MDNode>(MD->getMetadata());
|
2012-09-19 22:29:39 +02:00
|
|
|
const unsigned numOperands = N->getNumOperands();
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
LLVMContext &Context = unwrap(V)->getContext();
|
2012-09-19 22:29:39 +02:00
|
|
|
for (unsigned i = 0; i < numOperands; i++)
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
Dest[i] = getMDNodeOperandImpl(Context, N, i);
|
2012-09-19 22:29:39 +02:00
|
|
|
}
|
|
|
|
|
2016-04-23 02:12:45 +02:00
|
|
|
unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char *Name) {
|
|
|
|
if (NamedMDNode *N = unwrap(M)->getNamedMetadata(Name)) {
|
2011-10-14 22:37:42 +02:00
|
|
|
return N->getNumOperands();
|
|
|
|
}
|
|
|
|
return 0;
|
2011-10-06 14:13:11 +02:00
|
|
|
}
|
|
|
|
|
2016-04-23 02:12:45 +02:00
|
|
|
void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char *Name,
|
|
|
|
LLVMValueRef *Dest) {
|
|
|
|
NamedMDNode *N = unwrap(M)->getNamedMetadata(Name);
|
2011-10-14 22:37:42 +02:00
|
|
|
if (!N)
|
|
|
|
return;
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
LLVMContext &Context = unwrap(M)->getContext();
|
2011-10-14 22:37:42 +02:00
|
|
|
for (unsigned i=0;i<N->getNumOperands();i++)
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
Dest[i] = wrap(MetadataAsValue::get(Context, N->getOperand(i)));
|
2011-10-06 14:13:11 +02:00
|
|
|
}
|
|
|
|
|
2016-04-23 02:12:45 +02:00
|
|
|
void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char *Name,
|
|
|
|
LLVMValueRef Val) {
|
|
|
|
NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(Name);
|
2011-12-20 20:29:36 +01:00
|
|
|
if (!N)
|
|
|
|
return;
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
if (!Val)
|
|
|
|
return;
|
2015-01-28 17:35:59 +01:00
|
|
|
N->addOperand(extractMDNode(unwrap<MetadataAsValue>(Val)));
|
2011-12-20 20:29:36 +01:00
|
|
|
}
|
|
|
|
|
2018-10-11 01:53:12 +02:00
|
|
|
const char *LLVMGetDebugLocDirectory(LLVMValueRef Val, unsigned *Length) {
|
|
|
|
if (!Length) return nullptr;
|
|
|
|
StringRef S;
|
2019-04-24 15:30:03 +02:00
|
|
|
if (const auto *I = dyn_cast<Instruction>(unwrap(Val))) {
|
|
|
|
if (const auto &DL = I->getDebugLoc()) {
|
|
|
|
S = DL->getDirectory();
|
|
|
|
}
|
|
|
|
} else if (const auto *GV = dyn_cast<GlobalVariable>(unwrap(Val))) {
|
2018-10-11 01:53:12 +02:00
|
|
|
SmallVector<DIGlobalVariableExpression *, 1> GVEs;
|
|
|
|
GV->getDebugInfo(GVEs);
|
|
|
|
if (GVEs.size())
|
|
|
|
if (const DIGlobalVariable *DGV = GVEs[0]->getVariable())
|
|
|
|
S = DGV->getDirectory();
|
2019-04-24 15:30:03 +02:00
|
|
|
} else if (const auto *F = dyn_cast<Function>(unwrap(Val))) {
|
2018-10-11 01:53:12 +02:00
|
|
|
if (const DISubprogram *DSP = F->getSubprogram())
|
|
|
|
S = DSP->getDirectory();
|
|
|
|
} else {
|
|
|
|
assert(0 && "Expected Instruction, GlobalVariable or Function");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
*Length = S.size();
|
|
|
|
return S.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMGetDebugLocFilename(LLVMValueRef Val, unsigned *Length) {
|
|
|
|
if (!Length) return nullptr;
|
|
|
|
StringRef S;
|
2019-04-24 15:30:03 +02:00
|
|
|
if (const auto *I = dyn_cast<Instruction>(unwrap(Val))) {
|
|
|
|
if (const auto &DL = I->getDebugLoc()) {
|
|
|
|
S = DL->getFilename();
|
|
|
|
}
|
|
|
|
} else if (const auto *GV = dyn_cast<GlobalVariable>(unwrap(Val))) {
|
2018-10-11 01:53:12 +02:00
|
|
|
SmallVector<DIGlobalVariableExpression *, 1> GVEs;
|
|
|
|
GV->getDebugInfo(GVEs);
|
|
|
|
if (GVEs.size())
|
|
|
|
if (const DIGlobalVariable *DGV = GVEs[0]->getVariable())
|
|
|
|
S = DGV->getFilename();
|
2019-04-24 15:30:03 +02:00
|
|
|
} else if (const auto *F = dyn_cast<Function>(unwrap(Val))) {
|
2018-10-11 01:53:12 +02:00
|
|
|
if (const DISubprogram *DSP = F->getSubprogram())
|
|
|
|
S = DSP->getFilename();
|
|
|
|
} else {
|
|
|
|
assert(0 && "Expected Instruction, GlobalVariable or Function");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
*Length = S.size();
|
|
|
|
return S.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned LLVMGetDebugLocLine(LLVMValueRef Val) {
|
|
|
|
unsigned L = 0;
|
2019-04-24 15:30:03 +02:00
|
|
|
if (const auto *I = dyn_cast<Instruction>(unwrap(Val))) {
|
|
|
|
if (const auto &DL = I->getDebugLoc()) {
|
|
|
|
L = DL->getLine();
|
|
|
|
}
|
|
|
|
} else if (const auto *GV = dyn_cast<GlobalVariable>(unwrap(Val))) {
|
2018-10-11 01:53:12 +02:00
|
|
|
SmallVector<DIGlobalVariableExpression *, 1> GVEs;
|
|
|
|
GV->getDebugInfo(GVEs);
|
|
|
|
if (GVEs.size())
|
|
|
|
if (const DIGlobalVariable *DGV = GVEs[0]->getVariable())
|
|
|
|
L = DGV->getLine();
|
2019-04-24 15:30:03 +02:00
|
|
|
} else if (const auto *F = dyn_cast<Function>(unwrap(Val))) {
|
2018-10-11 01:53:12 +02:00
|
|
|
if (const DISubprogram *DSP = F->getSubprogram())
|
|
|
|
L = DSP->getLine();
|
|
|
|
} else {
|
|
|
|
assert(0 && "Expected Instruction, GlobalVariable or Function");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return L;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned LLVMGetDebugLocColumn(LLVMValueRef Val) {
|
|
|
|
unsigned C = 0;
|
2019-04-24 15:30:03 +02:00
|
|
|
if (const auto *I = dyn_cast<Instruction>(unwrap(Val)))
|
|
|
|
if (const auto &DL = I->getDebugLoc())
|
|
|
|
C = DL->getColumn();
|
2018-10-11 01:53:12 +02:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*--.. Operations on scalar constants ......................................--*/
|
|
|
|
|
2007-10-06 17:11:06 +02:00
|
|
|
LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool SignExtend) {
|
2009-07-25 01:12:02 +02:00
|
|
|
return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), N, SignExtend != 0));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2010-11-23 03:47:22 +01:00
|
|
|
LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy,
|
|
|
|
unsigned NumWords,
|
|
|
|
const uint64_t Words[]) {
|
|
|
|
IntegerType *Ty = unwrap<IntegerType>(IntTy);
|
|
|
|
return wrap(ConstantInt::get(Ty->getContext(),
|
2011-07-18 23:45:40 +02:00
|
|
|
APInt(Ty->getBitWidth(),
|
|
|
|
makeArrayRef(Words, NumWords))));
|
2010-11-23 03:47:22 +01:00
|
|
|
}
|
|
|
|
|
2009-08-17 01:36:46 +02:00
|
|
|
LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char Str[],
|
|
|
|
uint8_t Radix) {
|
|
|
|
return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), StringRef(Str),
|
|
|
|
Radix));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char Str[],
|
|
|
|
unsigned SLen, uint8_t Radix) {
|
|
|
|
return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), StringRef(Str, SLen),
|
|
|
|
Radix));
|
2008-02-02 02:07:50 +01:00
|
|
|
}
|
|
|
|
|
2007-10-06 17:11:06 +02:00
|
|
|
LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N) {
|
2009-08-17 01:36:46 +02:00
|
|
|
return wrap(ConstantFP::get(unwrap(RealTy), N));
|
2008-02-02 02:07:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, const char *Text) {
|
2009-08-17 01:36:46 +02:00
|
|
|
return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Text)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char Str[],
|
|
|
|
unsigned SLen) {
|
|
|
|
return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Str, SLen)));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2009-10-12 06:01:02 +02:00
|
|
|
unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal) {
|
|
|
|
return unwrap<ConstantInt>(ConstantVal)->getZExtValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal) {
|
|
|
|
return unwrap<ConstantInt>(ConstantVal)->getSExtValue();
|
|
|
|
}
|
|
|
|
|
2014-10-28 20:46:44 +01:00
|
|
|
double LLVMConstRealGetDouble(LLVMValueRef ConstantVal, LLVMBool *LosesInfo) {
|
|
|
|
ConstantFP *cFP = unwrap<ConstantFP>(ConstantVal) ;
|
|
|
|
Type *Ty = cFP->getType();
|
|
|
|
|
2021-05-06 21:17:42 +02:00
|
|
|
if (Ty->isHalfTy() || Ty->isBFloatTy() || Ty->isFloatTy() ||
|
|
|
|
Ty->isDoubleTy()) {
|
2014-10-28 20:46:44 +01:00
|
|
|
*LosesInfo = false;
|
|
|
|
return cFP->getValueAPF().convertToDouble();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool APFLosesInfo;
|
|
|
|
APFloat APF = cFP->getValueAPF();
|
2016-12-14 12:57:17 +01:00
|
|
|
APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &APFLosesInfo);
|
2014-10-28 20:46:44 +01:00
|
|
|
*LosesInfo = APFLosesInfo;
|
|
|
|
return APF.convertToDouble();
|
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*--.. Operations on composite constants ...................................--*/
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str,
|
2010-01-09 23:27:07 +01:00
|
|
|
unsigned Length,
|
|
|
|
LLVMBool DontNullTerminate) {
|
2007-09-18 05:18:57 +02:00
|
|
|
/* Inverted the sense of AddNull because ', 0)' is a
|
|
|
|
better mnemonic for null termination than ', 1)'. */
|
2012-02-05 03:29:43 +01:00
|
|
|
return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length),
|
|
|
|
DontNullTerminate == 0));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
2016-03-13 01:54:40 +01:00
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMValueRef LLVMConstString(const char *Str, unsigned Length,
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool DontNullTerminate) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMConstStringInContext(LLVMGetGlobalContext(), Str, Length,
|
|
|
|
DontNullTerminate);
|
|
|
|
}
|
2014-08-04 01:54:16 +02:00
|
|
|
|
2016-03-13 01:54:40 +01:00
|
|
|
LLVMValueRef LLVMGetElementAsConstant(LLVMValueRef C, unsigned idx) {
|
|
|
|
return wrap(unwrap<ConstantDataSequential>(C)->getElementAsConstant(idx));
|
2014-08-04 01:54:16 +02:00
|
|
|
}
|
|
|
|
|
2016-03-13 01:54:40 +01:00
|
|
|
LLVMBool LLVMIsConstantString(LLVMValueRef C) {
|
|
|
|
return unwrap<ConstantDataSequential>(C)->isString();
|
2014-08-04 01:54:16 +02:00
|
|
|
}
|
|
|
|
|
2016-04-03 23:06:04 +02:00
|
|
|
const char *LLVMGetAsString(LLVMValueRef C, size_t *Length) {
|
|
|
|
StringRef Str = unwrap<ConstantDataSequential>(C)->getAsString();
|
|
|
|
*Length = Str.size();
|
|
|
|
return Str.data();
|
2014-08-04 01:54:16 +02:00
|
|
|
}
|
|
|
|
|
2007-10-06 17:11:06 +02:00
|
|
|
LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
|
|
|
|
LLVMValueRef *ConstantVals, unsigned Length) {
|
2011-06-22 11:24:39 +02:00
|
|
|
ArrayRef<Constant*> V(unwrap<Constant>(ConstantVals, Length), Length);
|
|
|
|
return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
2014-08-04 01:54:16 +02:00
|
|
|
|
2016-03-13 01:40:12 +01:00
|
|
|
LLVMValueRef LLVMConstStructInContext(LLVMContextRef C,
|
|
|
|
LLVMValueRef *ConstantVals,
|
|
|
|
unsigned Count, LLVMBool Packed) {
|
|
|
|
Constant **Elements = unwrap<Constant>(ConstantVals, Count);
|
|
|
|
return wrap(ConstantStruct::getAnon(*unwrap(C), makeArrayRef(Elements, Count),
|
|
|
|
Packed != 0));
|
|
|
|
}
|
|
|
|
|
2007-10-06 17:11:06 +02:00
|
|
|
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool Packed) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMConstStructInContext(LLVMGetGlobalContext(), ConstantVals, Count,
|
|
|
|
Packed);
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
2011-07-14 21:09:08 +02:00
|
|
|
|
|
|
|
LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy,
|
|
|
|
LLVMValueRef *ConstantVals,
|
|
|
|
unsigned Count) {
|
|
|
|
Constant **Elements = unwrap<Constant>(ConstantVals, Count);
|
2011-07-18 06:54:35 +02:00
|
|
|
StructType *Ty = cast<StructType>(unwrap(StructTy));
|
2011-07-14 21:09:08 +02:00
|
|
|
|
2011-07-18 14:00:32 +02:00
|
|
|
return wrap(ConstantStruct::get(Ty, makeArrayRef(Elements, Count)));
|
2011-07-14 21:09:08 +02:00
|
|
|
}
|
|
|
|
|
2007-10-06 17:11:06 +02:00
|
|
|
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) {
|
2011-07-18 14:00:32 +02:00
|
|
|
return wrap(ConstantVector::get(makeArrayRef(
|
2011-02-15 01:14:00 +01:00
|
|
|
unwrap<Constant>(ScalarConstantVals, Size), Size)));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
2011-10-06 14:39:34 +02:00
|
|
|
|
|
|
|
/*-- Opcode mapping */
|
|
|
|
|
|
|
|
static LLVMOpcode map_to_llvmopcode(int opcode)
|
|
|
|
{
|
|
|
|
switch (opcode) {
|
2012-02-05 23:14:15 +01:00
|
|
|
default: llvm_unreachable("Unhandled Opcode.");
|
2011-10-06 14:39:34 +02:00
|
|
|
#define HANDLE_INST(num, opc, clas) case num: return LLVM##opc;
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/Instruction.def"
|
2011-10-06 14:39:34 +02:00
|
|
|
#undef HANDLE_INST
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int map_from_llvmopcode(LLVMOpcode code)
|
|
|
|
{
|
|
|
|
switch (code) {
|
|
|
|
#define HANDLE_INST(num, opc, clas) case LLVM##opc: return num;
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/Instruction.def"
|
2011-10-06 14:39:34 +02:00
|
|
|
#undef HANDLE_INST
|
|
|
|
}
|
2012-01-17 00:24:27 +01:00
|
|
|
llvm_unreachable("Unhandled Opcode.");
|
2011-10-06 14:39:34 +02:00
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
/*--.. Constant expressions ................................................--*/
|
|
|
|
|
2009-10-12 06:01:02 +02:00
|
|
|
LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal) {
|
2011-10-06 14:39:34 +02:00
|
|
|
return map_to_llvmopcode(unwrap<ConstantExpr>(ConstantVal)->getOpcode());
|
2009-10-12 06:01:02 +02:00
|
|
|
}
|
|
|
|
|
2009-05-21 17:52:21 +02:00
|
|
|
LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty) {
|
2009-07-29 20:55:55 +02:00
|
|
|
return wrap(ConstantExpr::getAlignOf(unwrap(Ty)));
|
2009-05-21 17:52:21 +02:00
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty) {
|
2009-07-29 20:55:55 +02:00
|
|
|
return wrap(ConstantExpr::getSizeOf(unwrap(Ty)));
|
2007-10-06 16:29:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNeg(unwrap<Constant>(ConstantVal)));
|
2009-08-16 04:20:12 +02:00
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:43 +01:00
|
|
|
LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNSWNeg(unwrap<Constant>(ConstantVal)));
|
2010-02-28 06:51:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNUWNeg(unwrap<Constant>(ConstantVal)));
|
2010-02-28 06:51:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-16 04:20:12 +02:00
|
|
|
LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFNeg(unwrap<Constant>(ConstantVal)));
|
2007-10-06 16:29:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNot(unwrap<Constant>(ConstantVal)));
|
2007-10-06 16:29:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getAdd(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2009-09-04 01:34:49 +02:00
|
|
|
LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant,
|
|
|
|
LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNSWAdd(unwrap<Constant>(LHSConstant),
|
2009-09-04 01:34:49 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:43 +01:00
|
|
|
LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant,
|
|
|
|
LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNUWAdd(unwrap<Constant>(LHSConstant),
|
2010-02-28 06:51:43 +01:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:20:12 +02:00
|
|
|
LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFAdd(unwrap<Constant>(LHSConstant),
|
2009-08-16 04:20:12 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getSub(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:43 +01:00
|
|
|
LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant,
|
|
|
|
LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNSWSub(unwrap<Constant>(LHSConstant),
|
2010-02-28 06:51:43 +01:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant,
|
|
|
|
LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNUWSub(unwrap<Constant>(LHSConstant),
|
2010-02-28 06:51:43 +01:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:20:12 +02:00
|
|
|
LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
|
|
|
return wrap(ConstantExpr::getFSub(unwrap<Constant>(LHSConstant),
|
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getMul(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:43 +01:00
|
|
|
LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant,
|
|
|
|
LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNSWMul(unwrap<Constant>(LHSConstant),
|
2010-02-28 06:51:43 +01:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant,
|
|
|
|
LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getNUWMul(unwrap<Constant>(LHSConstant),
|
2010-02-28 06:51:43 +01:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:20:12 +02:00
|
|
|
LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFMul(unwrap<Constant>(LHSConstant),
|
2009-08-16 04:20:12 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getUDiv(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2016-10-05 01:32:42 +02:00
|
|
|
LLVMValueRef LLVMConstExactUDiv(LLVMValueRef LHSConstant,
|
|
|
|
LLVMValueRef RHSConstant) {
|
|
|
|
return wrap(ConstantExpr::getExactUDiv(unwrap<Constant>(LHSConstant),
|
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getSDiv(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2009-09-04 01:34:49 +02:00
|
|
|
LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant,
|
|
|
|
LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getExactSDiv(unwrap<Constant>(LHSConstant),
|
2009-09-04 01:34:49 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFDiv(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getURem(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getSRem(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFRem(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getAnd(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getOr(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getXor(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstICmp(LLVMIntPredicate Predicate,
|
|
|
|
LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2009-07-29 20:55:55 +02:00
|
|
|
return wrap(ConstantExpr::getICmp(Predicate,
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(LHSConstant),
|
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate,
|
|
|
|
LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2009-07-29 20:55:55 +02:00
|
|
|
return wrap(ConstantExpr::getFCmp(Predicate,
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(LHSConstant),
|
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getShl(unwrap<Constant>(LHSConstant),
|
|
|
|
unwrap<Constant>(RHSConstant)));
|
2007-10-06 16:29:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getLShr(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getAShr(unwrap<Constant>(LHSConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(RHSConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal,
|
|
|
|
LLVMValueRef *ConstantIndices, unsigned NumIndices) {
|
2011-07-21 16:31:17 +02:00
|
|
|
ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
|
|
|
|
NumIndices);
|
2019-01-14 22:39:35 +01:00
|
|
|
Constant *Val = unwrap<Constant>(ConstantVal);
|
|
|
|
Type *Ty =
|
|
|
|
cast<PointerType>(Val->getType()->getScalarType())->getElementType();
|
|
|
|
return wrap(ConstantExpr::getGetElementPtr(Ty, Val, IdxList));
|
2007-10-06 16:29:36 +02:00
|
|
|
}
|
|
|
|
|
2009-09-04 01:34:49 +02:00
|
|
|
LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal,
|
|
|
|
LLVMValueRef *ConstantIndices,
|
|
|
|
unsigned NumIndices) {
|
2011-07-21 16:31:17 +02:00
|
|
|
ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices),
|
|
|
|
NumIndices);
|
2019-01-14 22:39:35 +01:00
|
|
|
Constant *Val = unwrap<Constant>(ConstantVal);
|
|
|
|
Type *Ty =
|
|
|
|
cast<PointerType>(Val->getType()->getScalarType())->getElementType();
|
|
|
|
return wrap(ConstantExpr::getInBoundsGetElementPtr(Ty, Val, IdxList));
|
2009-09-04 01:34:49 +02:00
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getTrunc(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getSExt(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getZExt(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFPTrunc(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFPExtend(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getUIToFP(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2009-07-29 20:55:55 +02:00
|
|
|
return wrap(ConstantExpr::getSIToFP(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2009-07-29 20:55:55 +02:00
|
|
|
return wrap(ConstantExpr::getFPToUI(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFPToSI(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getPtrToInt(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getIntToPtr(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getBitCast(unwrap<Constant>(ConstantVal),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
2013-11-15 02:34:59 +01:00
|
|
|
LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal,
|
|
|
|
LLVMTypeRef ToType) {
|
|
|
|
return wrap(ConstantExpr::getAddrSpaceCast(unwrap<Constant>(ConstantVal),
|
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:20:12 +02:00
|
|
|
LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal,
|
|
|
|
LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getZExtOrBitCast(unwrap<Constant>(ConstantVal),
|
2009-08-16 04:20:12 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal,
|
|
|
|
LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getSExtOrBitCast(unwrap<Constant>(ConstantVal),
|
2009-08-16 04:20:12 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal,
|
|
|
|
LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getTruncOrBitCast(unwrap<Constant>(ConstantVal),
|
2009-08-16 04:20:12 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal,
|
|
|
|
LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getPointerCast(unwrap<Constant>(ConstantVal),
|
2009-08-16 04:20:12 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType,
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool isSigned) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getIntegerCast(unwrap<Constant>(ConstantVal),
|
|
|
|
unwrap(ToType), isSigned));
|
2009-08-16 04:20:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getFPCast(unwrap<Constant>(ConstantVal),
|
2009-08-16 04:20:12 +02:00
|
|
|
unwrap(ToType)));
|
|
|
|
}
|
|
|
|
|
2007-10-06 16:29:36 +02:00
|
|
|
LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition,
|
|
|
|
LLVMValueRef ConstantIfTrue,
|
|
|
|
LLVMValueRef ConstantIfFalse) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getSelect(unwrap<Constant>(ConstantCondition),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(ConstantIfTrue),
|
|
|
|
unwrap<Constant>(ConstantIfFalse)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant,
|
|
|
|
LLVMValueRef IndexConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getExtractElement(unwrap<Constant>(VectorConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(IndexConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant,
|
|
|
|
LLVMValueRef ElementValueConstant,
|
|
|
|
LLVMValueRef IndexConstant) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getInsertElement(unwrap<Constant>(VectorConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(ElementValueConstant),
|
|
|
|
unwrap<Constant>(IndexConstant)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant,
|
|
|
|
LLVMValueRef VectorBConstant,
|
|
|
|
LLVMValueRef MaskConstant) {
|
2020-03-31 22:08:59 +02:00
|
|
|
SmallVector<int, 16> IntMask;
|
|
|
|
ShuffleVectorInst::getShuffleMask(unwrap<Constant>(MaskConstant), IntMask);
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getShuffleVector(unwrap<Constant>(VectorAConstant),
|
2007-10-06 16:29:36 +02:00
|
|
|
unwrap<Constant>(VectorBConstant),
|
2020-03-31 22:08:59 +02:00
|
|
|
IntMask));
|
2007-10-06 16:29:36 +02:00
|
|
|
}
|
2007-09-18 05:18:57 +02:00
|
|
|
|
2008-11-03 23:55:43 +01:00
|
|
|
LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
|
|
|
|
unsigned NumIdx) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getExtractValue(unwrap<Constant>(AggConstant),
|
2011-07-18 14:00:32 +02:00
|
|
|
makeArrayRef(IdxList, NumIdx)));
|
2008-11-03 23:55:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
|
|
|
|
LLVMValueRef ElementValueConstant,
|
|
|
|
unsigned *IdxList, unsigned NumIdx) {
|
2011-02-15 01:14:00 +01:00
|
|
|
return wrap(ConstantExpr::getInsertValue(unwrap<Constant>(AggConstant),
|
2008-11-03 23:55:43 +01:00
|
|
|
unwrap<Constant>(ElementValueConstant),
|
2011-07-18 14:00:32 +02:00
|
|
|
makeArrayRef(IdxList, NumIdx)));
|
2008-11-03 23:55:43 +01:00
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString,
|
|
|
|
const char *Constraints,
|
|
|
|
LLVMBool HasSideEffects,
|
2012-09-10 13:52:00 +02:00
|
|
|
LLVMBool IsAlignStack) {
|
2010-01-09 23:27:07 +01:00
|
|
|
return wrap(InlineAsm::get(dyn_cast<FunctionType>(unwrap(Ty)), AsmString,
|
2012-09-10 13:52:00 +02:00
|
|
|
Constraints, HasSideEffects, IsAlignStack));
|
2008-12-17 22:39:50 +01:00
|
|
|
}
|
|
|
|
|
2010-02-28 10:46:06 +01:00
|
|
|
LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB) {
|
|
|
|
return wrap(BlockAddress::get(unwrap<Function>(F), unwrap(BB)));
|
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*--.. Operations on global variables, functions, and aliases (globals) ....--*/
|
|
|
|
|
2008-03-19 02:11:35 +01:00
|
|
|
LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global) {
|
|
|
|
return wrap(unwrap<GlobalValue>(Global)->getParent());
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsDeclaration(LLVMValueRef Global) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return unwrap<GlobalValue>(Global)->isDeclaration();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) {
|
2009-07-20 22:34:46 +02:00
|
|
|
switch (unwrap<GlobalValue>(Global)->getLinkage()) {
|
|
|
|
case GlobalValue::ExternalLinkage:
|
|
|
|
return LLVMExternalLinkage;
|
|
|
|
case GlobalValue::AvailableExternallyLinkage:
|
|
|
|
return LLVMAvailableExternallyLinkage;
|
|
|
|
case GlobalValue::LinkOnceAnyLinkage:
|
|
|
|
return LLVMLinkOnceAnyLinkage;
|
|
|
|
case GlobalValue::LinkOnceODRLinkage:
|
|
|
|
return LLVMLinkOnceODRLinkage;
|
|
|
|
case GlobalValue::WeakAnyLinkage:
|
|
|
|
return LLVMWeakAnyLinkage;
|
|
|
|
case GlobalValue::WeakODRLinkage:
|
|
|
|
return LLVMWeakODRLinkage;
|
|
|
|
case GlobalValue::AppendingLinkage:
|
|
|
|
return LLVMAppendingLinkage;
|
|
|
|
case GlobalValue::InternalLinkage:
|
|
|
|
return LLVMInternalLinkage;
|
|
|
|
case GlobalValue::PrivateLinkage:
|
|
|
|
return LLVMPrivateLinkage;
|
|
|
|
case GlobalValue::ExternalWeakLinkage:
|
|
|
|
return LLVMExternalWeakLinkage;
|
|
|
|
case GlobalValue::CommonLinkage:
|
|
|
|
return LLVMCommonLinkage;
|
|
|
|
}
|
|
|
|
|
2012-01-17 08:00:13 +01:00
|
|
|
llvm_unreachable("Invalid GlobalValue linkage!");
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) {
|
2009-07-20 22:34:46 +02:00
|
|
|
GlobalValue *GV = unwrap<GlobalValue>(Global);
|
|
|
|
|
|
|
|
switch (Linkage) {
|
|
|
|
case LLVMExternalLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::ExternalLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMAvailableExternallyLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::AvailableExternallyLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMLinkOnceAnyLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::LinkOnceAnyLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMLinkOnceODRLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
|
|
|
|
break;
|
2012-08-17 20:33:14 +02:00
|
|
|
case LLVMLinkOnceODRAutoHideLinkage:
|
2018-05-14 14:53:11 +02:00
|
|
|
LLVM_DEBUG(
|
|
|
|
errs() << "LLVMSetLinkage(): LLVMLinkOnceODRAutoHideLinkage is no "
|
|
|
|
"longer supported.");
|
2012-08-17 20:33:14 +02:00
|
|
|
break;
|
2009-07-20 22:34:46 +02:00
|
|
|
case LLVMWeakAnyLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::WeakAnyLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMWeakODRLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::WeakODRLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMAppendingLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::AppendingLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMInternalLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::InternalLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMPrivateLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::PrivateLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMLinkerPrivateLinkage:
|
Remove the linker_private and linker_private_weak linkages.
These linkages were introduced some time ago, but it was never very
clear what exactly their semantics were or what they should be used
for. Some investigation found these uses:
* utf-16 strings in clang.
* non-unnamed_addr strings produced by the sanitizers.
It turns out they were just working around a more fundamental problem.
For some sections a MachO linker needs a symbol in order to split the
section into atoms, and llvm had no idea that was the case. I fixed
that in r201700 and it is now safe to use the private linkage. When
the object ends up in a section that requires symbols, llvm will use a
'l' prefix instead of a 'L' prefix and things just work.
With that, these linkages were already dead, but there was a potential
future user in the objc metadata information. I am still looking at
CGObjcMac.cpp, but at this point I am convinced that linker_private
and linker_private_weak are not what they need.
The objc uses are currently split in
* Regular symbols (no '\01' prefix). LLVM already directly provides
whatever semantics they need.
* Uses of a private name (start with "\01L" or "\01l") and private
linkage. We can drop the "\01L" and "\01l" prefixes as soon as llvm
agrees with clang on L being ok or not for a given section. I have two
patches in code review for this.
* Uses of private name and weak linkage.
The last case is the one that one could think would fit one of these
linkages. That is not the case. The semantics are
* the linker will merge these symbol by *name*.
* the linker will hide them in the final DSO.
Given that the merging is done by name, any of the private (or
internal) linkages would be a bad match. They allow llvm to rename the
symbols, and that is really not what we want. From the llvm point of
view, these objects should really be (linkonce|weak)(_odr)?.
For now, just keeping the "\01l" prefix is probably the best for these
symbols. If we one day want to have a more direct support in llvm,
IMHO what we should add is not a linkage, it is just a hidden_symbol
attribute. It would be applicable to multiple linkages. For example,
on weak it would produce the current behavior we have for objc
metadata. On internal, it would be equivalent to private (and we
should then remove private).
llvm-svn: 203866
2014-03-14 00:18:37 +01:00
|
|
|
GV->setLinkage(GlobalValue::PrivateLinkage);
|
2009-07-20 22:34:46 +02:00
|
|
|
break;
|
2010-07-01 23:55:59 +02:00
|
|
|
case LLVMLinkerPrivateWeakLinkage:
|
Remove the linker_private and linker_private_weak linkages.
These linkages were introduced some time ago, but it was never very
clear what exactly their semantics were or what they should be used
for. Some investigation found these uses:
* utf-16 strings in clang.
* non-unnamed_addr strings produced by the sanitizers.
It turns out they were just working around a more fundamental problem.
For some sections a MachO linker needs a symbol in order to split the
section into atoms, and llvm had no idea that was the case. I fixed
that in r201700 and it is now safe to use the private linkage. When
the object ends up in a section that requires symbols, llvm will use a
'l' prefix instead of a 'L' prefix and things just work.
With that, these linkages were already dead, but there was a potential
future user in the objc metadata information. I am still looking at
CGObjcMac.cpp, but at this point I am convinced that linker_private
and linker_private_weak are not what they need.
The objc uses are currently split in
* Regular symbols (no '\01' prefix). LLVM already directly provides
whatever semantics they need.
* Uses of a private name (start with "\01L" or "\01l") and private
linkage. We can drop the "\01L" and "\01l" prefixes as soon as llvm
agrees with clang on L being ok or not for a given section. I have two
patches in code review for this.
* Uses of private name and weak linkage.
The last case is the one that one could think would fit one of these
linkages. That is not the case. The semantics are
* the linker will merge these symbol by *name*.
* the linker will hide them in the final DSO.
Given that the merging is done by name, any of the private (or
internal) linkages would be a bad match. They allow llvm to rename the
symbols, and that is really not what we want. From the llvm point of
view, these objects should really be (linkonce|weak)(_odr)?.
For now, just keeping the "\01l" prefix is probably the best for these
symbols. If we one day want to have a more direct support in llvm,
IMHO what we should add is not a linkage, it is just a hidden_symbol
attribute. It would be applicable to multiple linkages. For example,
on weak it would produce the current behavior we have for objc
metadata. On internal, it would be equivalent to private (and we
should then remove private).
llvm-svn: 203866
2014-03-14 00:18:37 +01:00
|
|
|
GV->setLinkage(GlobalValue::PrivateLinkage);
|
2010-07-01 23:55:59 +02:00
|
|
|
break;
|
2009-07-20 22:34:46 +02:00
|
|
|
case LLVMDLLImportLinkage:
|
2018-05-14 14:53:11 +02:00
|
|
|
LLVM_DEBUG(
|
|
|
|
errs()
|
|
|
|
<< "LLVMSetLinkage(): LLVMDLLImportLinkage is no longer supported.");
|
2009-07-20 22:34:46 +02:00
|
|
|
break;
|
|
|
|
case LLVMDLLExportLinkage:
|
2018-05-14 14:53:11 +02:00
|
|
|
LLVM_DEBUG(
|
|
|
|
errs()
|
|
|
|
<< "LLVMSetLinkage(): LLVMDLLExportLinkage is no longer supported.");
|
2009-07-20 22:34:46 +02:00
|
|
|
break;
|
|
|
|
case LLVMExternalWeakLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::ExternalWeakLinkage);
|
|
|
|
break;
|
|
|
|
case LLVMGhostLinkage:
|
2018-05-14 14:53:11 +02:00
|
|
|
LLVM_DEBUG(
|
|
|
|
errs() << "LLVMSetLinkage(): LLVMGhostLinkage is no longer supported.");
|
2009-07-20 22:34:46 +02:00
|
|
|
break;
|
|
|
|
case LLVMCommonLinkage:
|
|
|
|
GV->setLinkage(GlobalValue::CommonLinkage);
|
|
|
|
break;
|
|
|
|
}
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMGetSection(LLVMValueRef Global) {
|
2016-05-11 20:21:59 +02:00
|
|
|
// Using .data() is safe because of how GlobalObject::setSection is
|
|
|
|
// implemented.
|
|
|
|
return unwrap<GlobalValue>(Global)->getSection().data();
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetSection(LLVMValueRef Global, const char *Section) {
|
2014-05-13 20:45:48 +02:00
|
|
|
unwrap<GlobalObject>(Global)->setSection(Section);
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMVisibility LLVMGetVisibility(LLVMValueRef Global) {
|
|
|
|
return static_cast<LLVMVisibility>(
|
|
|
|
unwrap<GlobalValue>(Global)->getVisibility());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz) {
|
|
|
|
unwrap<GlobalValue>(Global)
|
|
|
|
->setVisibility(static_cast<GlobalValue::VisibilityTypes>(Viz));
|
|
|
|
}
|
|
|
|
|
2014-03-05 03:34:23 +01:00
|
|
|
LLVMDLLStorageClass LLVMGetDLLStorageClass(LLVMValueRef Global) {
|
|
|
|
return static_cast<LLVMDLLStorageClass>(
|
|
|
|
unwrap<GlobalValue>(Global)->getDLLStorageClass());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) {
|
|
|
|
unwrap<GlobalValue>(Global)->setDLLStorageClass(
|
|
|
|
static_cast<GlobalValue::DLLStorageClassTypes>(Class));
|
|
|
|
}
|
|
|
|
|
2018-03-14 07:45:51 +01:00
|
|
|
LLVMUnnamedAddr LLVMGetUnnamedAddress(LLVMValueRef Global) {
|
|
|
|
switch (unwrap<GlobalValue>(Global)->getUnnamedAddr()) {
|
|
|
|
case GlobalVariable::UnnamedAddr::None:
|
|
|
|
return LLVMNoUnnamedAddr;
|
|
|
|
case GlobalVariable::UnnamedAddr::Local:
|
|
|
|
return LLVMLocalUnnamedAddr;
|
|
|
|
case GlobalVariable::UnnamedAddr::Global:
|
|
|
|
return LLVMGlobalUnnamedAddr;
|
|
|
|
}
|
2018-03-14 13:04:51 +01:00
|
|
|
llvm_unreachable("Unknown UnnamedAddr kind!");
|
2018-03-14 07:45:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetUnnamedAddress(LLVMValueRef Global, LLVMUnnamedAddr UnnamedAddr) {
|
|
|
|
GlobalValue *GV = unwrap<GlobalValue>(Global);
|
|
|
|
|
|
|
|
switch (UnnamedAddr) {
|
|
|
|
case LLVMNoUnnamedAddr:
|
|
|
|
return GV->setUnnamedAddr(GlobalVariable::UnnamedAddr::None);
|
|
|
|
case LLVMLocalUnnamedAddr:
|
|
|
|
return GV->setUnnamedAddr(GlobalVariable::UnnamedAddr::Local);
|
|
|
|
case LLVMGlobalUnnamedAddr:
|
|
|
|
return GV->setUnnamedAddr(GlobalVariable::UnnamedAddr::Global);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-10 20:24:35 +01:00
|
|
|
LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) {
|
2016-06-14 23:01:22 +02:00
|
|
|
return unwrap<GlobalValue>(Global)->hasGlobalUnnamedAddr();
|
2014-03-10 20:24:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) {
|
2016-06-14 23:01:22 +02:00
|
|
|
unwrap<GlobalValue>(Global)->setUnnamedAddr(
|
|
|
|
HasUnnamedAddr ? GlobalValue::UnnamedAddr::Global
|
|
|
|
: GlobalValue::UnnamedAddr::None);
|
2014-03-10 20:24:35 +01:00
|
|
|
}
|
|
|
|
|
2018-09-28 22:54:29 +02:00
|
|
|
LLVMTypeRef LLVMGlobalGetValueType(LLVMValueRef Global) {
|
|
|
|
return wrap(unwrap<GlobalValue>(Global)->getValueType());
|
|
|
|
}
|
|
|
|
|
2013-10-29 10:02:02 +01:00
|
|
|
/*--.. Operations on global variables, load and store instructions .........--*/
|
|
|
|
|
|
|
|
unsigned LLVMGetAlignment(LLVMValueRef V) {
|
|
|
|
Value *P = unwrap<Value>(V);
|
2020-05-19 05:38:13 +02:00
|
|
|
if (GlobalObject *GV = dyn_cast<GlobalObject>(P))
|
2013-10-29 10:02:02 +01:00
|
|
|
return GV->getAlignment();
|
2014-03-05 06:05:34 +01:00
|
|
|
if (AllocaInst *AI = dyn_cast<AllocaInst>(P))
|
|
|
|
return AI->getAlignment();
|
2013-10-29 10:02:02 +01:00
|
|
|
if (LoadInst *LI = dyn_cast<LoadInst>(P))
|
|
|
|
return LI->getAlignment();
|
|
|
|
if (StoreInst *SI = dyn_cast<StoreInst>(P))
|
|
|
|
return SI->getAlignment();
|
2021-02-12 23:09:18 +01:00
|
|
|
if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(P))
|
|
|
|
return RMWI->getAlign().value();
|
|
|
|
if (AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(P))
|
|
|
|
return CXI->getAlign().value();
|
2013-10-29 10:02:02 +01:00
|
|
|
|
2014-03-05 06:05:34 +01:00
|
|
|
llvm_unreachable(
|
2021-02-12 23:09:18 +01:00
|
|
|
"only GlobalValue, AllocaInst, LoadInst, StoreInst, AtomicRMWInst, "
|
|
|
|
"and AtomicCmpXchgInst have alignment");
|
2013-10-29 10:02:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) {
|
|
|
|
Value *P = unwrap<Value>(V);
|
2014-05-13 20:45:48 +02:00
|
|
|
if (GlobalObject *GV = dyn_cast<GlobalObject>(P))
|
2019-10-15 13:24:36 +02:00
|
|
|
GV->setAlignment(MaybeAlign(Bytes));
|
2014-03-05 06:05:34 +01:00
|
|
|
else if (AllocaInst *AI = dyn_cast<AllocaInst>(P))
|
2020-05-15 22:23:14 +02:00
|
|
|
AI->setAlignment(Align(Bytes));
|
2013-10-29 10:02:02 +01:00
|
|
|
else if (LoadInst *LI = dyn_cast<LoadInst>(P))
|
2020-04-04 06:56:20 +02:00
|
|
|
LI->setAlignment(Align(Bytes));
|
2013-10-29 10:02:02 +01:00
|
|
|
else if (StoreInst *SI = dyn_cast<StoreInst>(P))
|
2020-05-14 23:48:10 +02:00
|
|
|
SI->setAlignment(Align(Bytes));
|
2021-02-12 23:09:18 +01:00
|
|
|
else if (AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(P))
|
|
|
|
RMWI->setAlignment(Align(Bytes));
|
|
|
|
else if (AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(P))
|
|
|
|
CXI->setAlignment(Align(Bytes));
|
2013-10-29 10:37:28 +01:00
|
|
|
else
|
2014-03-05 06:05:34 +01:00
|
|
|
llvm_unreachable(
|
2021-02-12 23:09:18 +01:00
|
|
|
"only GlobalValue, AllocaInst, LoadInst, StoreInst, AtomicRMWInst, and "
|
|
|
|
"and AtomicCmpXchgInst have alignment");
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2018-09-28 17:35:18 +02:00
|
|
|
LLVMValueMetadataEntry *LLVMGlobalCopyAllMetadata(LLVMValueRef Value,
|
|
|
|
size_t *NumEntries) {
|
|
|
|
return llvm_getMetadata(NumEntries, [&Value](MetadataEntries &Entries) {
|
2019-09-13 19:21:24 +02:00
|
|
|
Entries.clear();
|
2018-09-28 17:35:18 +02:00
|
|
|
if (Instruction *Instr = dyn_cast<Instruction>(unwrap(Value))) {
|
|
|
|
Instr->getAllMetadata(Entries);
|
|
|
|
} else {
|
|
|
|
unwrap<GlobalObject>(Value)->getAllMetadata(Entries);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned LLVMValueMetadataEntriesGetKind(LLVMValueMetadataEntry *Entries,
|
|
|
|
unsigned Index) {
|
|
|
|
LLVMOpaqueValueMetadataEntry MVE =
|
|
|
|
static_cast<LLVMOpaqueValueMetadataEntry>(Entries[Index]);
|
|
|
|
return MVE.Kind;
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMMetadataRef
|
|
|
|
LLVMValueMetadataEntriesGetMetadata(LLVMValueMetadataEntry *Entries,
|
|
|
|
unsigned Index) {
|
|
|
|
LLVMOpaqueValueMetadataEntry MVE =
|
|
|
|
static_cast<LLVMOpaqueValueMetadataEntry>(Entries[Index]);
|
|
|
|
return MVE.Metadata;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMDisposeValueMetadataEntries(LLVMValueMetadataEntry *Entries) {
|
|
|
|
free(Entries);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGlobalSetMetadata(LLVMValueRef Global, unsigned Kind,
|
|
|
|
LLVMMetadataRef MD) {
|
2018-09-28 18:02:26 +02:00
|
|
|
unwrap<GlobalObject>(Global)->setMetadata(Kind, unwrap<MDNode>(MD));
|
2018-09-28 17:35:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGlobalEraseMetadata(LLVMValueRef Global, unsigned Kind) {
|
|
|
|
unwrap<GlobalObject>(Global)->eraseMetadata(Kind);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGlobalClearMetadata(LLVMValueRef Global) {
|
|
|
|
unwrap<GlobalObject>(Global)->clearMetadata();
|
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
/*--.. Operations on global variables ......................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) {
|
2009-07-08 21:03:57 +02:00
|
|
|
return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false,
|
2014-04-09 08:08:46 +02:00
|
|
|
GlobalValue::ExternalLinkage, nullptr, Name));
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
2010-02-28 10:46:13 +01:00
|
|
|
LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
|
|
|
|
const char *Name,
|
|
|
|
unsigned AddressSpace) {
|
|
|
|
return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false,
|
2014-04-09 08:08:46 +02:00
|
|
|
GlobalValue::ExternalLinkage, nullptr, Name,
|
|
|
|
nullptr, GlobalVariable::NotThreadLocal,
|
|
|
|
AddressSpace));
|
2010-02-28 10:46:13 +01:00
|
|
|
}
|
|
|
|
|
2007-10-08 05:45:09 +02:00
|
|
|
LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name) {
|
|
|
|
return wrap(unwrap(M)->getNamedGlobal(Name));
|
|
|
|
}
|
|
|
|
|
2008-03-19 04:47:18 +01:00
|
|
|
LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::global_iterator I = Mod->global_begin();
|
|
|
|
if (I == Mod->global_end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::global_iterator I = Mod->global_end();
|
|
|
|
if (I == Mod->global_begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar) {
|
|
|
|
GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar);
|
2015-10-09 01:49:46 +02:00
|
|
|
Module::global_iterator I(GV);
|
2008-03-19 04:47:18 +01:00
|
|
|
if (++I == GV->getParent()->global_end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar) {
|
|
|
|
GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar);
|
2015-10-09 01:49:46 +02:00
|
|
|
Module::global_iterator I(GV);
|
2008-03-23 23:21:29 +01:00
|
|
|
if (I == GV->getParent()->global_begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
2007-09-18 05:18:57 +02:00
|
|
|
void LLVMDeleteGlobal(LLVMValueRef GlobalVar) {
|
|
|
|
unwrap<GlobalVariable>(GlobalVar)->eraseFromParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar) {
|
2009-10-12 06:01:02 +02:00
|
|
|
GlobalVariable* GV = unwrap<GlobalVariable>(GlobalVar);
|
|
|
|
if ( !GV->hasInitializer() )
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2009-10-12 06:01:02 +02:00
|
|
|
return wrap(GV->getInitializer());
|
2007-09-18 05:18:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal) {
|
|
|
|
unwrap<GlobalVariable>(GlobalVar)
|
|
|
|
->setInitializer(unwrap<Constant>(ConstantVal));
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar) {
|
2007-09-18 05:18:57 +02:00
|
|
|
return unwrap<GlobalVariable>(GlobalVar)->isThreadLocal();
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal) {
|
2007-09-18 05:18:57 +02:00
|
|
|
unwrap<GlobalVariable>(GlobalVar)->setThreadLocal(IsThreadLocal != 0);
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar) {
|
2007-10-07 19:31:42 +02:00
|
|
|
return unwrap<GlobalVariable>(GlobalVar)->isConstant();
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant) {
|
2007-10-07 19:31:42 +02:00
|
|
|
unwrap<GlobalVariable>(GlobalVar)->setConstant(IsConstant != 0);
|
|
|
|
}
|
|
|
|
|
2013-04-16 10:58:59 +02:00
|
|
|
LLVMThreadLocalMode LLVMGetThreadLocalMode(LLVMValueRef GlobalVar) {
|
|
|
|
switch (unwrap<GlobalVariable>(GlobalVar)->getThreadLocalMode()) {
|
|
|
|
case GlobalVariable::NotThreadLocal:
|
|
|
|
return LLVMNotThreadLocal;
|
|
|
|
case GlobalVariable::GeneralDynamicTLSModel:
|
|
|
|
return LLVMGeneralDynamicTLSModel;
|
|
|
|
case GlobalVariable::LocalDynamicTLSModel:
|
|
|
|
return LLVMLocalDynamicTLSModel;
|
|
|
|
case GlobalVariable::InitialExecTLSModel:
|
|
|
|
return LLVMInitialExecTLSModel;
|
|
|
|
case GlobalVariable::LocalExecTLSModel:
|
|
|
|
return LLVMLocalExecTLSModel;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Invalid GlobalVariable thread local mode");
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetThreadLocalMode(LLVMValueRef GlobalVar, LLVMThreadLocalMode Mode) {
|
|
|
|
GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar);
|
|
|
|
|
|
|
|
switch (Mode) {
|
|
|
|
case LLVMNotThreadLocal:
|
|
|
|
GV->setThreadLocalMode(GlobalVariable::NotThreadLocal);
|
|
|
|
break;
|
|
|
|
case LLVMGeneralDynamicTLSModel:
|
|
|
|
GV->setThreadLocalMode(GlobalVariable::GeneralDynamicTLSModel);
|
|
|
|
break;
|
|
|
|
case LLVMLocalDynamicTLSModel:
|
|
|
|
GV->setThreadLocalMode(GlobalVariable::LocalDynamicTLSModel);
|
|
|
|
break;
|
|
|
|
case LLVMInitialExecTLSModel:
|
|
|
|
GV->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
|
|
|
|
break;
|
|
|
|
case LLVMLocalExecTLSModel:
|
|
|
|
GV->setThreadLocalMode(GlobalVariable::LocalExecTLSModel);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMIsExternallyInitialized(LLVMValueRef GlobalVar) {
|
|
|
|
return unwrap<GlobalVariable>(GlobalVar)->isExternallyInitialized();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit) {
|
|
|
|
unwrap<GlobalVariable>(GlobalVar)->setExternallyInitialized(IsExtInit);
|
|
|
|
}
|
|
|
|
|
2008-12-17 22:39:50 +01:00
|
|
|
/*--.. Operations on aliases ......................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
|
|
|
|
const char *Name) {
|
2014-05-16 15:34:04 +02:00
|
|
|
auto *PTy = cast<PointerType>(unwrap(Ty));
|
2015-09-14 20:01:59 +02:00
|
|
|
return wrap(GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),
|
|
|
|
GlobalValue::ExternalLinkage, Name,
|
2015-02-23 22:51:06 +01:00
|
|
|
unwrap<Constant>(Aliasee), unwrap(M)));
|
2008-12-17 22:39:50 +01:00
|
|
|
}
|
|
|
|
|
2018-05-21 01:49:08 +02:00
|
|
|
LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M,
|
|
|
|
const char *Name, size_t NameLen) {
|
|
|
|
return wrap(unwrap(M)->getNamedAlias(Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::alias_iterator I = Mod->alias_begin();
|
|
|
|
if (I == Mod->alias_end())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::alias_iterator I = Mod->alias_end();
|
|
|
|
if (I == Mod->alias_begin())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*--I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA) {
|
|
|
|
GlobalAlias *Alias = unwrap<GlobalAlias>(GA);
|
|
|
|
Module::alias_iterator I(Alias);
|
|
|
|
if (++I == Alias->getParent()->alias_end())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA) {
|
|
|
|
GlobalAlias *Alias = unwrap<GlobalAlias>(GA);
|
|
|
|
Module::alias_iterator I(Alias);
|
|
|
|
if (I == Alias->getParent()->alias_begin())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*--I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias) {
|
|
|
|
return wrap(unwrap<GlobalAlias>(Alias)->getAliasee());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee) {
|
|
|
|
unwrap<GlobalAlias>(Alias)->setAliasee(unwrap<Constant>(Aliasee));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
/*--.. Operations on functions .............................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,
|
|
|
|
LLVMTypeRef FunctionTy) {
|
2008-04-06 22:25:17 +02:00
|
|
|
return wrap(Function::Create(unwrap<FunctionType>(FunctionTy),
|
|
|
|
GlobalValue::ExternalLinkage, Name, unwrap(M)));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2007-10-08 05:45:09 +02:00
|
|
|
LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name) {
|
|
|
|
return wrap(unwrap(M)->getFunction(Name));
|
|
|
|
}
|
|
|
|
|
2008-03-19 04:47:18 +01:00
|
|
|
LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::iterator I = Mod->begin();
|
|
|
|
if (I == Mod->end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::iterator I = Mod->end();
|
|
|
|
if (I == Mod->begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn) {
|
|
|
|
Function *Func = unwrap<Function>(Fn);
|
2015-10-09 01:49:46 +02:00
|
|
|
Module::iterator I(Func);
|
2008-03-19 04:47:18 +01:00
|
|
|
if (++I == Func->getParent()->end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn) {
|
|
|
|
Function *Func = unwrap<Function>(Fn);
|
2015-10-09 01:49:46 +02:00
|
|
|
Module::iterator I(Func);
|
2008-03-23 23:21:29 +01:00
|
|
|
if (I == Func->getParent()->begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
void LLVMDeleteFunction(LLVMValueRef Fn) {
|
|
|
|
unwrap<Function>(Fn)->eraseFromParent();
|
|
|
|
}
|
|
|
|
|
2016-02-18 21:38:32 +01:00
|
|
|
LLVMBool LLVMHasPersonalityFn(LLVMValueRef Fn) {
|
|
|
|
return unwrap<Function>(Fn)->hasPersonalityFn();
|
|
|
|
}
|
|
|
|
|
2015-07-14 03:23:06 +02:00
|
|
|
LLVMValueRef LLVMGetPersonalityFn(LLVMValueRef Fn) {
|
|
|
|
return wrap(unwrap<Function>(Fn)->getPersonalityFn());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn) {
|
|
|
|
unwrap<Function>(Fn)->setPersonalityFn(unwrap<Constant>(PersonalityFn));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) {
|
|
|
|
if (Function *F = dyn_cast<Function>(unwrap(Fn)))
|
|
|
|
return F->getIntrinsicID();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-11-06 02:38:14 +01:00
|
|
|
static Intrinsic::ID llvm_map_to_intrinsic_id(unsigned ID) {
|
|
|
|
assert(ID < llvm::Intrinsic::num_intrinsics && "Intrinsic ID out of range");
|
|
|
|
return llvm::Intrinsic::ID(ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod,
|
|
|
|
unsigned ID,
|
|
|
|
LLVMTypeRef *ParamTypes,
|
|
|
|
size_t ParamCount) {
|
|
|
|
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
|
|
|
|
auto IID = llvm_map_to_intrinsic_id(ID);
|
|
|
|
return wrap(llvm::Intrinsic::getDeclaration(unwrap(Mod), IID, Tys));
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMIntrinsicGetName(unsigned ID, size_t *NameLength) {
|
|
|
|
auto IID = llvm_map_to_intrinsic_id(ID);
|
|
|
|
auto Str = llvm::Intrinsic::getName(IID);
|
|
|
|
*NameLength = Str.size();
|
|
|
|
return Str.data();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID,
|
|
|
|
LLVMTypeRef *ParamTypes, size_t ParamCount) {
|
|
|
|
auto IID = llvm_map_to_intrinsic_id(ID);
|
|
|
|
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
|
|
|
|
return wrap(llvm::Intrinsic::getType(*unwrap(Ctx), IID, Tys));
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMIntrinsicCopyOverloadedName(unsigned ID,
|
|
|
|
LLVMTypeRef *ParamTypes,
|
|
|
|
size_t ParamCount,
|
|
|
|
size_t *NameLength) {
|
|
|
|
auto IID = llvm_map_to_intrinsic_id(ID);
|
|
|
|
ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount);
|
2021-06-14 14:52:29 +02:00
|
|
|
auto Str = llvm::Intrinsic::getNameNoUnnamedTypes(IID, Tys);
|
|
|
|
*NameLength = Str.length();
|
|
|
|
return strdup(Str.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod, unsigned ID,
|
|
|
|
LLVMTypeRef *ParamTypes,
|
|
|
|
size_t ParamCount,
|
|
|
|
size_t *NameLength) {
|
|
|
|
auto IID = llvm_map_to_intrinsic_id(ID);
|
|
|
|
ArrayRef<Type *> Tys(unwrap(ParamTypes), ParamCount);
|
|
|
|
auto Str = llvm::Intrinsic::getName(IID, Tys, unwrap(Mod));
|
2018-11-06 02:38:14 +01:00
|
|
|
*NameLength = Str.length();
|
2018-11-06 02:54:12 +01:00
|
|
|
return strdup(Str.c_str());
|
2018-11-06 02:38:14 +01:00
|
|
|
}
|
|
|
|
|
2019-03-25 21:58:58 +01:00
|
|
|
unsigned LLVMLookupIntrinsicID(const char *Name, size_t NameLen) {
|
|
|
|
return Function::lookupIntrinsicID({Name, NameLen});
|
|
|
|
}
|
|
|
|
|
2018-11-06 02:38:14 +01:00
|
|
|
LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID) {
|
|
|
|
auto IID = llvm_map_to_intrinsic_id(ID);
|
|
|
|
return llvm::Intrinsic::isOverloaded(IID);
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) {
|
|
|
|
return unwrap<Function>(Fn)->getCallingConv();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) {
|
2009-09-02 10:44:58 +02:00
|
|
|
return unwrap<Function>(Fn)->setCallingConv(
|
|
|
|
static_cast<CallingConv::ID>(CC));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2008-08-17 20:44:35 +02:00
|
|
|
const char *LLVMGetGC(LLVMValueRef Fn) {
|
2007-12-10 04:18:06 +01:00
|
|
|
Function *F = unwrap<Function>(Fn);
|
2016-01-08 03:28:20 +01:00
|
|
|
return F->hasGC()? F->getGC().c_str() : nullptr;
|
2007-12-10 04:18:06 +01:00
|
|
|
}
|
|
|
|
|
2008-08-17 20:44:35 +02:00
|
|
|
void LLVMSetGC(LLVMValueRef Fn, const char *GC) {
|
2007-12-10 04:18:06 +01:00
|
|
|
Function *F = unwrap<Function>(Fn);
|
2008-08-17 20:44:35 +02:00
|
|
|
if (GC)
|
|
|
|
F->setGC(GC);
|
2007-12-10 04:18:06 +01:00
|
|
|
else
|
2008-08-17 20:44:35 +02:00
|
|
|
F->clearGC();
|
2007-12-10 04:18:06 +01:00
|
|
|
}
|
|
|
|
|
2016-06-12 08:17:24 +02:00
|
|
|
void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
|
|
|
|
LLVMAttributeRef A) {
|
|
|
|
unwrap<Function>(F)->addAttribute(Idx, unwrap(A));
|
|
|
|
}
|
|
|
|
|
2016-07-21 06:25:06 +02:00
|
|
|
unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) {
|
2017-04-12 02:38:00 +02:00
|
|
|
auto AS = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
|
|
|
|
return AS.getNumAttributes();
|
2016-07-21 06:25:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
|
|
|
|
LLVMAttributeRef *Attrs) {
|
2017-04-12 02:38:00 +02:00
|
|
|
auto AS = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
|
|
|
|
for (auto A : AS)
|
2016-07-21 06:25:06 +02:00
|
|
|
*Attrs++ = wrap(A);
|
|
|
|
}
|
|
|
|
|
2016-06-12 08:17:24 +02:00
|
|
|
LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F,
|
|
|
|
LLVMAttributeIndex Idx,
|
|
|
|
unsigned KindID) {
|
|
|
|
return wrap(unwrap<Function>(F)->getAttribute(Idx,
|
|
|
|
(Attribute::AttrKind)KindID));
|
|
|
|
}
|
|
|
|
|
2016-06-15 19:50:39 +02:00
|
|
|
LLVMAttributeRef LLVMGetStringAttributeAtIndex(LLVMValueRef F,
|
|
|
|
LLVMAttributeIndex Idx,
|
|
|
|
const char *K, unsigned KLen) {
|
|
|
|
return wrap(unwrap<Function>(F)->getAttribute(Idx, StringRef(K, KLen)));
|
|
|
|
}
|
|
|
|
|
2016-06-12 08:17:24 +02:00
|
|
|
void LLVMRemoveEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
|
|
|
|
unsigned KindID) {
|
|
|
|
unwrap<Function>(F)->removeAttribute(Idx, (Attribute::AttrKind)KindID);
|
|
|
|
}
|
|
|
|
|
2016-06-15 19:50:39 +02:00
|
|
|
void LLVMRemoveStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
|
|
|
|
const char *K, unsigned KLen) {
|
|
|
|
unwrap<Function>(F)->removeAttribute(Idx, StringRef(K, KLen));
|
|
|
|
}
|
|
|
|
|
2013-04-17 01:12:43 +02:00
|
|
|
void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A,
|
|
|
|
const char *V) {
|
|
|
|
Function *Func = unwrap<Function>(Fn);
|
2017-04-19 19:28:52 +02:00
|
|
|
Attribute Attr = Attribute::get(Func->getContext(), A, V);
|
|
|
|
Func->addAttribute(AttributeList::FunctionIndex, Attr);
|
2013-04-17 01:12:43 +02:00
|
|
|
}
|
|
|
|
|
2008-03-19 02:11:35 +01:00
|
|
|
/*--.. Operations on parameters ............................................--*/
|
|
|
|
|
|
|
|
unsigned LLVMCountParams(LLVMValueRef FnRef) {
|
|
|
|
// This function is strictly redundant to
|
|
|
|
// LLVMCountParamTypes(LLVMGetElementType(LLVMTypeOf(FnRef)))
|
2008-06-22 00:06:54 +02:00
|
|
|
return unwrap<Function>(FnRef)->arg_size();
|
2008-03-19 02:11:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGetParams(LLVMValueRef FnRef, LLVMValueRef *ParamRefs) {
|
|
|
|
Function *Fn = unwrap<Function>(FnRef);
|
2021-02-27 19:09:25 +01:00
|
|
|
for (Argument &A : Fn->args())
|
|
|
|
*ParamRefs++ = wrap(&A);
|
2008-03-19 02:11:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetParam(LLVMValueRef FnRef, unsigned index) {
|
2017-03-17 18:16:39 +01:00
|
|
|
Function *Fn = unwrap<Function>(FnRef);
|
|
|
|
return wrap(&Fn->arg_begin()[index]);
|
2008-03-19 02:11:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetParamParent(LLVMValueRef V) {
|
|
|
|
return wrap(unwrap<Argument>(V)->getParent());
|
|
|
|
}
|
|
|
|
|
2008-03-23 23:21:29 +01:00
|
|
|
LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn) {
|
|
|
|
Function *Func = unwrap<Function>(Fn);
|
|
|
|
Function::arg_iterator I = Func->arg_begin();
|
|
|
|
if (I == Func->arg_end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-23 23:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn) {
|
|
|
|
Function *Func = unwrap<Function>(Fn);
|
|
|
|
Function::arg_iterator I = Func->arg_end();
|
|
|
|
if (I == Func->arg_begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-23 23:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg) {
|
|
|
|
Argument *A = unwrap<Argument>(Arg);
|
2017-03-17 18:16:39 +01:00
|
|
|
Function *Fn = A->getParent();
|
|
|
|
if (A->getArgNo() + 1 >= Fn->arg_size())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2017-03-17 18:16:39 +01:00
|
|
|
return wrap(&Fn->arg_begin()[A->getArgNo() + 1]);
|
2008-03-23 23:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg) {
|
|
|
|
Argument *A = unwrap<Argument>(Arg);
|
2017-03-17 18:16:39 +01:00
|
|
|
if (A->getArgNo() == 0)
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2017-03-17 18:16:39 +01:00
|
|
|
return wrap(&A->getParent()->arg_begin()[A->getArgNo() - 1]);
|
2008-03-23 23:21:29 +01:00
|
|
|
}
|
|
|
|
|
2008-04-28 19:37:06 +02:00
|
|
|
void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) {
|
2013-01-23 07:14:59 +01:00
|
|
|
Argument *A = unwrap<Argument>(Arg);
|
2019-10-15 14:56:24 +02:00
|
|
|
A->addAttr(Attribute::getWithAlignment(A->getContext(), Align(align)));
|
2008-04-28 19:37:06 +02:00
|
|
|
}
|
|
|
|
|
2019-02-05 19:05:44 +01:00
|
|
|
/*--.. Operations on ifuncs ................................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMAddGlobalIFunc(LLVMModuleRef M,
|
|
|
|
const char *Name, size_t NameLen,
|
|
|
|
LLVMTypeRef Ty, unsigned AddrSpace,
|
|
|
|
LLVMValueRef Resolver) {
|
|
|
|
return wrap(GlobalIFunc::create(unwrap(Ty), AddrSpace,
|
|
|
|
GlobalValue::ExternalLinkage,
|
|
|
|
StringRef(Name, NameLen),
|
|
|
|
unwrap<Constant>(Resolver), unwrap(M)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetNamedGlobalIFunc(LLVMModuleRef M,
|
|
|
|
const char *Name, size_t NameLen) {
|
|
|
|
return wrap(unwrap(M)->getNamedIFunc(StringRef(Name, NameLen)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetFirstGlobalIFunc(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::ifunc_iterator I = Mod->ifunc_begin();
|
|
|
|
if (I == Mod->ifunc_end())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetLastGlobalIFunc(LLVMModuleRef M) {
|
|
|
|
Module *Mod = unwrap(M);
|
|
|
|
Module::ifunc_iterator I = Mod->ifunc_end();
|
|
|
|
if (I == Mod->ifunc_begin())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*--I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetNextGlobalIFunc(LLVMValueRef IFunc) {
|
|
|
|
GlobalIFunc *GIF = unwrap<GlobalIFunc>(IFunc);
|
|
|
|
Module::ifunc_iterator I(GIF);
|
|
|
|
if (++I == GIF->getParent()->ifunc_end())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetPreviousGlobalIFunc(LLVMValueRef IFunc) {
|
|
|
|
GlobalIFunc *GIF = unwrap<GlobalIFunc>(IFunc);
|
|
|
|
Module::ifunc_iterator I(GIF);
|
|
|
|
if (I == GIF->getParent()->ifunc_begin())
|
|
|
|
return nullptr;
|
|
|
|
return wrap(&*--I);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetGlobalIFuncResolver(LLVMValueRef IFunc) {
|
|
|
|
return wrap(unwrap<GlobalIFunc>(IFunc)->getResolver());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetGlobalIFuncResolver(LLVMValueRef IFunc, LLVMValueRef Resolver) {
|
|
|
|
unwrap<GlobalIFunc>(IFunc)->setResolver(unwrap<Constant>(Resolver));
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMEraseGlobalIFunc(LLVMValueRef IFunc) {
|
|
|
|
unwrap<GlobalIFunc>(IFunc)->eraseFromParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMRemoveGlobalIFunc(LLVMValueRef IFunc) {
|
|
|
|
unwrap<GlobalIFunc>(IFunc)->removeFromParent();
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
/*--.. Operations on basic blocks ..........................................--*/
|
|
|
|
|
2008-03-19 02:11:35 +01:00
|
|
|
LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB) {
|
|
|
|
return wrap(static_cast<Value*>(unwrap(BB)));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val) {
|
2007-09-26 22:56:12 +02:00
|
|
|
return isa<BasicBlock>(unwrap(Val));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val) {
|
|
|
|
return wrap(unwrap<BasicBlock>(Val));
|
|
|
|
}
|
|
|
|
|
2016-02-09 23:36:41 +01:00
|
|
|
const char *LLVMGetBasicBlockName(LLVMBasicBlockRef BB) {
|
|
|
|
return unwrap(BB)->getName().data();
|
|
|
|
}
|
|
|
|
|
2008-03-23 23:21:29 +01:00
|
|
|
LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB) {
|
|
|
|
return wrap(unwrap(BB)->getParent());
|
2008-03-19 02:11:35 +01:00
|
|
|
}
|
|
|
|
|
2011-08-23 22:27:46 +02:00
|
|
|
LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB) {
|
|
|
|
return wrap(unwrap(BB)->getTerminator());
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
unsigned LLVMCountBasicBlocks(LLVMValueRef FnRef) {
|
2008-06-22 00:06:54 +02:00
|
|
|
return unwrap<Function>(FnRef)->size();
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGetBasicBlocks(LLVMValueRef FnRef, LLVMBasicBlockRef *BasicBlocksRefs){
|
|
|
|
Function *Fn = unwrap<Function>(FnRef);
|
2016-06-26 16:10:56 +02:00
|
|
|
for (BasicBlock &BB : *Fn)
|
|
|
|
*BasicBlocksRefs++ = wrap(&BB);
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn) {
|
|
|
|
return wrap(&unwrap<Function>(Fn)->getEntryBlock());
|
|
|
|
}
|
|
|
|
|
2008-03-19 04:47:18 +01:00
|
|
|
LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn) {
|
|
|
|
Function *Func = unwrap<Function>(Fn);
|
|
|
|
Function::iterator I = Func->begin();
|
|
|
|
if (I == Func->end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn) {
|
|
|
|
Function *Func = unwrap<Function>(Fn);
|
|
|
|
Function::iterator I = Func->end();
|
|
|
|
if (I == Func->begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB) {
|
|
|
|
BasicBlock *Block = unwrap(BB);
|
2015-10-09 01:49:46 +02:00
|
|
|
Function::iterator I(Block);
|
2008-03-19 04:47:18 +01:00
|
|
|
if (++I == Block->getParent()->end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB) {
|
|
|
|
BasicBlock *Block = unwrap(BB);
|
2015-10-09 01:49:46 +02:00
|
|
|
Function::iterator I(Block);
|
2008-03-19 04:47:18 +01:00
|
|
|
if (I == Block->getParent()->begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
2019-01-08 07:24:19 +01:00
|
|
|
LLVMBasicBlockRef LLVMCreateBasicBlockInContext(LLVMContextRef C,
|
2019-01-14 18:16:55 +01:00
|
|
|
const char *Name) {
|
|
|
|
return wrap(llvm::BasicBlock::Create(*unwrap(C), Name));
|
2019-01-08 07:24:19 +01:00
|
|
|
}
|
|
|
|
|
2019-04-05 22:32:43 +02:00
|
|
|
void LLVMInsertExistingBasicBlockAfterInsertBlock(LLVMBuilderRef Builder,
|
|
|
|
LLVMBasicBlockRef BB) {
|
|
|
|
BasicBlock *ToInsert = unwrap(BB);
|
|
|
|
BasicBlock *CurBB = unwrap(Builder)->GetInsertBlock();
|
|
|
|
assert(CurBB && "current insertion point is invalid!");
|
|
|
|
CurBB->getParent()->getBasicBlockList().insertAfter(CurBB->getIterator(),
|
|
|
|
ToInsert);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMAppendExistingBasicBlock(LLVMValueRef Fn,
|
|
|
|
LLVMBasicBlockRef BB) {
|
|
|
|
unwrap<Function>(Fn)->getBasicBlockList().push_back(unwrap(BB));
|
|
|
|
}
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C,
|
|
|
|
LLVMValueRef FnRef,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(BasicBlock::Create(*unwrap(C), Name, unwrap<Function>(FnRef)));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef FnRef, const char *Name) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMAppendBasicBlockInContext(LLVMGetGlobalContext(), FnRef, Name);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMInsertBasicBlockInContext(LLVMContextRef C,
|
|
|
|
LLVMBasicBlockRef BBRef,
|
|
|
|
const char *Name) {
|
|
|
|
BasicBlock *BB = unwrap(BBRef);
|
|
|
|
return wrap(BasicBlock::Create(*unwrap(C), Name, BB->getParent(), BB));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef BBRef,
|
2007-09-26 22:56:12 +02:00
|
|
|
const char *Name) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMInsertBasicBlockInContext(LLVMGetGlobalContext(), BBRef, Name);
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMDeleteBasicBlock(LLVMBasicBlockRef BBRef) {
|
|
|
|
unwrap(BBRef)->eraseFromParent();
|
|
|
|
}
|
|
|
|
|
2011-08-23 22:27:46 +02:00
|
|
|
void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BBRef) {
|
|
|
|
unwrap(BBRef)->removeFromParent();
|
|
|
|
}
|
|
|
|
|
2010-07-19 17:31:07 +02:00
|
|
|
void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos) {
|
|
|
|
unwrap(BB)->moveBefore(unwrap(MovePos));
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos) {
|
|
|
|
unwrap(BB)->moveAfter(unwrap(MovePos));
|
|
|
|
}
|
|
|
|
|
2008-03-19 02:11:35 +01:00
|
|
|
/*--.. Operations on instructions ..........................................--*/
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst) {
|
|
|
|
return wrap(unwrap<Instruction>(Inst)->getParent());
|
|
|
|
}
|
|
|
|
|
2008-03-19 04:47:18 +01:00
|
|
|
LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB) {
|
|
|
|
BasicBlock *Block = unwrap(BB);
|
|
|
|
BasicBlock::iterator I = Block->begin();
|
|
|
|
if (I == Block->end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB) {
|
|
|
|
BasicBlock *Block = unwrap(BB);
|
|
|
|
BasicBlock::iterator I = Block->end();
|
|
|
|
if (I == Block->begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst) {
|
|
|
|
Instruction *Instr = unwrap<Instruction>(Inst);
|
2015-10-09 01:49:46 +02:00
|
|
|
BasicBlock::iterator I(Instr);
|
2008-03-19 04:47:18 +01:00
|
|
|
if (++I == Instr->getParent()->end())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst) {
|
|
|
|
Instruction *Instr = unwrap<Instruction>(Inst);
|
2015-10-09 01:49:46 +02:00
|
|
|
BasicBlock::iterator I(Instr);
|
2008-03-19 04:47:18 +01:00
|
|
|
if (I == Instr->getParent()->begin())
|
2014-04-09 08:08:46 +02:00
|
|
|
return nullptr;
|
2015-10-09 01:49:46 +02:00
|
|
|
return wrap(&*--I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
2016-02-11 22:37:54 +01:00
|
|
|
void LLVMInstructionRemoveFromParent(LLVMValueRef Inst) {
|
|
|
|
unwrap<Instruction>(Inst)->removeFromParent();
|
|
|
|
}
|
|
|
|
|
2011-10-03 22:59:18 +02:00
|
|
|
void LLVMInstructionEraseFromParent(LLVMValueRef Inst) {
|
|
|
|
unwrap<Instruction>(Inst)->eraseFromParent();
|
|
|
|
}
|
|
|
|
|
2011-10-06 14:13:20 +02:00
|
|
|
LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst) {
|
2011-10-14 22:37:42 +02:00
|
|
|
if (ICmpInst *I = dyn_cast<ICmpInst>(unwrap(Inst)))
|
|
|
|
return (LLVMIntPredicate)I->getPredicate();
|
|
|
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(unwrap(Inst)))
|
|
|
|
if (CE->getOpcode() == Instruction::ICmp)
|
|
|
|
return (LLVMIntPredicate)CE->getPredicate();
|
|
|
|
return (LLVMIntPredicate)0;
|
2011-10-06 14:13:20 +02:00
|
|
|
}
|
|
|
|
|
2014-10-28 20:46:44 +01:00
|
|
|
LLVMRealPredicate LLVMGetFCmpPredicate(LLVMValueRef Inst) {
|
|
|
|
if (FCmpInst *I = dyn_cast<FCmpInst>(unwrap(Inst)))
|
|
|
|
return (LLVMRealPredicate)I->getPredicate();
|
|
|
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(unwrap(Inst)))
|
|
|
|
if (CE->getOpcode() == Instruction::FCmp)
|
|
|
|
return (LLVMRealPredicate)CE->getPredicate();
|
|
|
|
return (LLVMRealPredicate)0;
|
|
|
|
}
|
|
|
|
|
2011-10-14 22:37:49 +02:00
|
|
|
LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst) {
|
|
|
|
if (Instruction *C = dyn_cast<Instruction>(unwrap(Inst)))
|
|
|
|
return map_to_llvmopcode(C->getOpcode());
|
|
|
|
return (LLVMOpcode)0;
|
|
|
|
}
|
|
|
|
|
2014-10-17 03:02:34 +02:00
|
|
|
LLVMValueRef LLVMInstructionClone(LLVMValueRef Inst) {
|
|
|
|
if (Instruction *C = dyn_cast<Instruction>(unwrap(Inst)))
|
|
|
|
return wrap(C->clone());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-10-19 01:03:55 +02:00
|
|
|
LLVMValueRef LLVMIsATerminatorInst(LLVMValueRef Inst) {
|
|
|
|
Instruction *I = dyn_cast<Instruction>(unwrap(Inst));
|
|
|
|
return (I && I->isTerminator()) ? wrap(I) : nullptr;
|
|
|
|
}
|
|
|
|
|
2016-02-10 01:09:37 +01:00
|
|
|
unsigned LLVMGetNumArgOperands(LLVMValueRef Instr) {
|
2018-03-30 19:49:53 +02:00
|
|
|
if (FuncletPadInst *FPI = dyn_cast<FuncletPadInst>(unwrap(Instr))) {
|
|
|
|
return FPI->getNumArgOperands();
|
|
|
|
}
|
2019-01-07 08:31:49 +01:00
|
|
|
return unwrap<CallBase>(Instr)->getNumArgOperands();
|
2016-02-10 01:09:37 +01:00
|
|
|
}
|
|
|
|
|
2018-03-30 19:49:53 +02:00
|
|
|
/*--.. Call and invoke instructions ........................................--*/
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr) {
|
2019-01-07 08:31:49 +01:00
|
|
|
return unwrap<CallBase>(Instr)->getCallingConv();
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) {
|
2019-01-07 08:31:49 +01:00
|
|
|
return unwrap<CallBase>(Instr)->setCallingConv(
|
|
|
|
static_cast<CallingConv::ID>(CC));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2013-09-19 01:31:10 +02:00
|
|
|
void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
|
2008-04-28 19:37:06 +02:00
|
|
|
unsigned align) {
|
2019-01-07 08:31:49 +01:00
|
|
|
auto *Call = unwrap<CallBase>(Instr);
|
2019-10-15 14:56:24 +02:00
|
|
|
Attribute AlignAttr =
|
|
|
|
Attribute::getWithAlignment(Call->getContext(), Align(align));
|
2019-01-07 08:31:49 +01:00
|
|
|
Call->addAttribute(index, AlignAttr);
|
2008-04-28 19:37:06 +02:00
|
|
|
}
|
|
|
|
|
2016-06-15 07:14:29 +02:00
|
|
|
void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
|
|
|
|
LLVMAttributeRef A) {
|
2019-01-07 08:31:49 +01:00
|
|
|
unwrap<CallBase>(C)->addAttribute(Idx, unwrap(A));
|
2016-06-15 07:14:29 +02:00
|
|
|
}
|
|
|
|
|
2016-07-21 06:25:06 +02:00
|
|
|
unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C,
|
|
|
|
LLVMAttributeIndex Idx) {
|
2019-01-07 08:31:49 +01:00
|
|
|
auto *Call = unwrap<CallBase>(C);
|
|
|
|
auto AS = Call->getAttributes().getAttributes(Idx);
|
2017-04-12 02:38:00 +02:00
|
|
|
return AS.getNumAttributes();
|
2016-07-21 06:25:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx,
|
|
|
|
LLVMAttributeRef *Attrs) {
|
2019-01-07 08:31:49 +01:00
|
|
|
auto *Call = unwrap<CallBase>(C);
|
|
|
|
auto AS = Call->getAttributes().getAttributes(Idx);
|
2017-04-12 02:38:00 +02:00
|
|
|
for (auto A : AS)
|
2016-07-21 06:25:06 +02:00
|
|
|
*Attrs++ = wrap(A);
|
|
|
|
}
|
|
|
|
|
2016-06-15 07:14:29 +02:00
|
|
|
LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C,
|
|
|
|
LLVMAttributeIndex Idx,
|
|
|
|
unsigned KindID) {
|
2019-01-07 08:31:49 +01:00
|
|
|
return wrap(
|
|
|
|
unwrap<CallBase>(C)->getAttribute(Idx, (Attribute::AttrKind)KindID));
|
2016-06-15 07:14:29 +02:00
|
|
|
}
|
|
|
|
|
2016-06-15 19:50:39 +02:00
|
|
|
LLVMAttributeRef LLVMGetCallSiteStringAttribute(LLVMValueRef C,
|
|
|
|
LLVMAttributeIndex Idx,
|
|
|
|
const char *K, unsigned KLen) {
|
2019-01-07 08:31:49 +01:00
|
|
|
return wrap(unwrap<CallBase>(C)->getAttribute(Idx, StringRef(K, KLen)));
|
2016-06-15 19:50:39 +02:00
|
|
|
}
|
|
|
|
|
2016-06-15 07:14:29 +02:00
|
|
|
void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
|
|
|
|
unsigned KindID) {
|
2019-01-07 08:31:49 +01:00
|
|
|
unwrap<CallBase>(C)->removeAttribute(Idx, (Attribute::AttrKind)KindID);
|
2016-06-15 07:14:29 +02:00
|
|
|
}
|
|
|
|
|
2016-06-15 19:50:39 +02:00
|
|
|
void LLVMRemoveCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
|
|
|
|
const char *K, unsigned KLen) {
|
2019-01-07 08:31:49 +01:00
|
|
|
unwrap<CallBase>(C)->removeAttribute(Idx, StringRef(K, KLen));
|
2016-06-15 19:50:39 +02:00
|
|
|
}
|
|
|
|
|
2016-02-10 01:09:37 +01:00
|
|
|
LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr) {
|
2020-04-28 05:15:59 +02:00
|
|
|
return wrap(unwrap<CallBase>(Instr)->getCalledOperand());
|
2016-02-10 01:09:37 +01:00
|
|
|
}
|
|
|
|
|
2019-01-14 22:37:42 +01:00
|
|
|
LLVMTypeRef LLVMGetCalledFunctionType(LLVMValueRef Instr) {
|
|
|
|
return wrap(unwrap<CallBase>(Instr)->getFunctionType());
|
|
|
|
}
|
|
|
|
|
2008-08-30 18:34:54 +02:00
|
|
|
/*--.. Operations on call instructions (only) ..............................--*/
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMIsTailCall(LLVMValueRef Call) {
|
2008-08-30 18:34:54 +02:00
|
|
|
return unwrap<CallInst>(Call)->isTailCall();
|
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
void LLVMSetTailCall(LLVMValueRef Call, LLVMBool isTailCall) {
|
2008-08-30 18:34:54 +02:00
|
|
|
unwrap<CallInst>(Call)->setTailCall(isTailCall);
|
|
|
|
}
|
|
|
|
|
2016-02-18 21:38:32 +01:00
|
|
|
/*--.. Operations on invoke instructions (only) ............................--*/
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetNormalDest(LLVMValueRef Invoke) {
|
|
|
|
return wrap(unwrap<InvokeInst>(Invoke)->getNormalDest());
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetUnwindDest(LLVMValueRef Invoke) {
|
2018-03-30 19:49:53 +02:00
|
|
|
if (CleanupReturnInst *CRI = dyn_cast<CleanupReturnInst>(unwrap(Invoke))) {
|
|
|
|
return wrap(CRI->getUnwindDest());
|
|
|
|
} else if (CatchSwitchInst *CSI = dyn_cast<CatchSwitchInst>(unwrap(Invoke))) {
|
|
|
|
return wrap(CSI->getUnwindDest());
|
|
|
|
}
|
2016-02-18 21:38:32 +01:00
|
|
|
return wrap(unwrap<InvokeInst>(Invoke)->getUnwindDest());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetNormalDest(LLVMValueRef Invoke, LLVMBasicBlockRef B) {
|
|
|
|
unwrap<InvokeInst>(Invoke)->setNormalDest(unwrap(B));
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetUnwindDest(LLVMValueRef Invoke, LLVMBasicBlockRef B) {
|
2018-03-30 19:49:53 +02:00
|
|
|
if (CleanupReturnInst *CRI = dyn_cast<CleanupReturnInst>(unwrap(Invoke))) {
|
|
|
|
return CRI->setUnwindDest(unwrap(B));
|
|
|
|
} else if (CatchSwitchInst *CSI = dyn_cast<CatchSwitchInst>(unwrap(Invoke))) {
|
|
|
|
return CSI->setUnwindDest(unwrap(B));
|
|
|
|
}
|
2016-02-18 21:38:32 +01:00
|
|
|
unwrap<InvokeInst>(Invoke)->setUnwindDest(unwrap(B));
|
|
|
|
}
|
|
|
|
|
2014-10-28 20:46:56 +01:00
|
|
|
/*--.. Operations on terminators ...........................................--*/
|
|
|
|
|
|
|
|
unsigned LLVMGetNumSuccessors(LLVMValueRef Term) {
|
2018-10-19 01:03:55 +02:00
|
|
|
return unwrap<Instruction>(Term)->getNumSuccessors();
|
2014-10-28 20:46:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetSuccessor(LLVMValueRef Term, unsigned i) {
|
2018-10-19 01:03:55 +02:00
|
|
|
return wrap(unwrap<Instruction>(Term)->getSuccessor(i));
|
2014-10-28 20:46:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetSuccessor(LLVMValueRef Term, unsigned i, LLVMBasicBlockRef block) {
|
2018-10-19 01:03:55 +02:00
|
|
|
return unwrap<Instruction>(Term)->setSuccessor(i, unwrap(block));
|
2014-10-28 20:46:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Operations on branch instructions (only) ............................--*/
|
|
|
|
|
|
|
|
LLVMBool LLVMIsConditional(LLVMValueRef Branch) {
|
|
|
|
return unwrap<BranchInst>(Branch)->isConditional();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetCondition(LLVMValueRef Branch) {
|
|
|
|
return wrap(unwrap<BranchInst>(Branch)->getCondition());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetCondition(LLVMValueRef Branch, LLVMValueRef Cond) {
|
|
|
|
return unwrap<BranchInst>(Branch)->setCondition(unwrap(Cond));
|
|
|
|
}
|
|
|
|
|
2011-08-23 22:27:46 +02:00
|
|
|
/*--.. Operations on switch instructions (only) ............................--*/
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef Switch) {
|
|
|
|
return wrap(unwrap<SwitchInst>(Switch)->getDefaultDest());
|
|
|
|
}
|
|
|
|
|
2016-02-09 23:50:53 +01:00
|
|
|
/*--.. Operations on alloca instructions (only) ............................--*/
|
|
|
|
|
|
|
|
LLVMTypeRef LLVMGetAllocatedType(LLVMValueRef Alloca) {
|
|
|
|
return wrap(unwrap<AllocaInst>(Alloca)->getAllocatedType());
|
|
|
|
}
|
|
|
|
|
2016-02-17 23:51:03 +01:00
|
|
|
/*--.. Operations on gep instructions (only) ...............................--*/
|
|
|
|
|
|
|
|
LLVMBool LLVMIsInBounds(LLVMValueRef GEP) {
|
|
|
|
return unwrap<GetElementPtrInst>(GEP)->isInBounds();
|
|
|
|
}
|
|
|
|
|
2016-05-01 04:23:14 +02:00
|
|
|
void LLVMSetIsInBounds(LLVMValueRef GEP, LLVMBool InBounds) {
|
|
|
|
return unwrap<GetElementPtrInst>(GEP)->setIsInBounds(InBounds);
|
2016-02-17 23:51:03 +01:00
|
|
|
}
|
|
|
|
|
2007-10-08 20:14:39 +02:00
|
|
|
/*--.. Operations on phi nodes .............................................--*/
|
|
|
|
|
|
|
|
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
|
|
|
|
LLVMBasicBlockRef *IncomingBlocks, unsigned Count) {
|
|
|
|
PHINode *PhiVal = unwrap<PHINode>(PhiNode);
|
|
|
|
for (unsigned I = 0; I != Count; ++I)
|
|
|
|
PhiVal->addIncoming(unwrap(IncomingValues[I]), unwrap(IncomingBlocks[I]));
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned LLVMCountIncoming(LLVMValueRef PhiNode) {
|
|
|
|
return unwrap<PHINode>(PhiNode)->getNumIncomingValues();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index) {
|
|
|
|
return wrap(unwrap<PHINode>(PhiNode)->getIncomingValue(Index));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index) {
|
|
|
|
return wrap(unwrap<PHINode>(PhiNode)->getIncomingBlock(Index));
|
|
|
|
}
|
|
|
|
|
2016-02-10 01:38:50 +01:00
|
|
|
/*--.. Operations on extractvalue and insertvalue nodes ....................--*/
|
|
|
|
|
|
|
|
unsigned LLVMGetNumIndices(LLVMValueRef Inst) {
|
|
|
|
auto *I = unwrap(Inst);
|
2016-02-17 23:51:03 +01:00
|
|
|
if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
|
|
|
|
return GEP->getNumIndices();
|
2016-02-10 01:38:50 +01:00
|
|
|
if (auto *EV = dyn_cast<ExtractValueInst>(I))
|
|
|
|
return EV->getNumIndices();
|
|
|
|
if (auto *IV = dyn_cast<InsertValueInst>(I))
|
|
|
|
return IV->getNumIndices();
|
2018-09-18 03:47:25 +02:00
|
|
|
if (auto *CE = dyn_cast<ConstantExpr>(I))
|
|
|
|
return CE->getIndices().size();
|
2016-02-10 01:38:50 +01:00
|
|
|
llvm_unreachable(
|
|
|
|
"LLVMGetNumIndices applies only to extractvalue and insertvalue!");
|
|
|
|
}
|
|
|
|
|
|
|
|
const unsigned *LLVMGetIndices(LLVMValueRef Inst) {
|
|
|
|
auto *I = unwrap(Inst);
|
|
|
|
if (auto *EV = dyn_cast<ExtractValueInst>(I))
|
|
|
|
return EV->getIndices().data();
|
|
|
|
if (auto *IV = dyn_cast<InsertValueInst>(I))
|
|
|
|
return IV->getIndices().data();
|
2018-09-18 03:47:25 +02:00
|
|
|
if (auto *CE = dyn_cast<ConstantExpr>(I))
|
|
|
|
return CE->getIndices().data();
|
2016-02-10 01:38:50 +01:00
|
|
|
llvm_unreachable(
|
|
|
|
"LLVMGetIndices applies only to extractvalue and insertvalue!");
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
|
|
|
|
/*===-- Instruction builders ----------------------------------------------===*/
|
|
|
|
|
2009-08-14 02:01:31 +02:00
|
|
|
LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C) {
|
|
|
|
return wrap(new IRBuilder<>(*unwrap(C)));
|
|
|
|
}
|
|
|
|
|
2008-05-04 14:55:34 +02:00
|
|
|
LLVMBuilderRef LLVMCreateBuilder(void) {
|
2009-08-14 02:01:31 +02:00
|
|
|
return LLVMCreateBuilderInContext(LLVMGetGlobalContext());
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2008-03-19 04:47:18 +01:00
|
|
|
void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block,
|
|
|
|
LLVMValueRef Instr) {
|
|
|
|
BasicBlock *BB = unwrap(Block);
|
2016-08-11 17:45:04 +02:00
|
|
|
auto I = Instr ? unwrap<Instruction>(Instr)->getIterator() : BB->end();
|
|
|
|
unwrap(Builder)->SetInsertPoint(BB, I);
|
2008-03-19 04:47:18 +01:00
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) {
|
|
|
|
Instruction *I = unwrap<Instruction>(Instr);
|
2015-10-09 01:49:46 +02:00
|
|
|
unwrap(Builder)->SetInsertPoint(I->getParent(), I->getIterator());
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) {
|
|
|
|
BasicBlock *BB = unwrap(Block);
|
|
|
|
unwrap(Builder)->SetInsertPoint(BB);
|
|
|
|
}
|
|
|
|
|
2008-03-19 02:11:35 +01:00
|
|
|
LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder) {
|
|
|
|
return wrap(unwrap(Builder)->GetInsertBlock());
|
|
|
|
}
|
|
|
|
|
2008-12-17 22:39:50 +01:00
|
|
|
void LLVMClearInsertionPosition(LLVMBuilderRef Builder) {
|
2010-04-01 08:31:45 +02:00
|
|
|
unwrap(Builder)->ClearInsertionPoint();
|
2008-12-17 22:39:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr) {
|
|
|
|
unwrap(Builder)->Insert(unwrap<Instruction>(Instr));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:20:57 +02:00
|
|
|
void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr,
|
|
|
|
const char *Name) {
|
|
|
|
unwrap(Builder)->Insert(unwrap<Instruction>(Instr), Name);
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
void LLVMDisposeBuilder(LLVMBuilderRef Builder) {
|
|
|
|
delete unwrap(Builder);
|
|
|
|
}
|
|
|
|
|
2010-02-28 10:45:59 +01:00
|
|
|
/*--.. Metadata builders ...................................................--*/
|
|
|
|
|
2019-04-10 16:19:05 +02:00
|
|
|
LLVMMetadataRef LLVMGetCurrentDebugLocation2(LLVMBuilderRef Builder) {
|
|
|
|
return wrap(unwrap(Builder)->getCurrentDebugLocation().getAsMDNode());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Builder, LLVMMetadataRef Loc) {
|
|
|
|
if (Loc)
|
|
|
|
unwrap(Builder)->SetCurrentDebugLocation(DebugLoc(unwrap<MDNode>(Loc)));
|
|
|
|
else
|
|
|
|
unwrap(Builder)->SetCurrentDebugLocation(DebugLoc());
|
|
|
|
}
|
|
|
|
|
2010-02-28 10:45:59 +01:00
|
|
|
void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) {
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
MDNode *Loc =
|
|
|
|
L ? cast<MDNode>(unwrap<MetadataAsValue>(L)->getMetadata()) : nullptr;
|
2015-03-30 21:40:05 +02:00
|
|
|
unwrap(Builder)->SetCurrentDebugLocation(DebugLoc(Loc));
|
2010-02-28 10:45:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) {
|
IR: Split Metadata from Value
Split `Metadata` away from the `Value` class hierarchy, as part of
PR21532. Assembly and bitcode changes are in the wings, but this is the
bulk of the change for the IR C++ API.
I have a follow-up patch prepared for `clang`. If this breaks other
sub-projects, I apologize in advance :(. Help me compile it on Darwin
I'll try to fix it. FWIW, the errors should be easy to fix, so it may
be simpler to just fix it yourself.
This breaks the build for all metadata-related code that's out-of-tree.
Rest assured the transition is mechanical and the compiler should catch
almost all of the problems.
Here's a quick guide for updating your code:
- `Metadata` is the root of a class hierarchy with three main classes:
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from
the `Value` class hierarchy. It is typeless -- i.e., instances do
*not* have a `Type`.
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.
If you're referring solely to resolved `MDNode`s -- post graph
construction -- just use `MDNode*`.
- `MDNode` (and the rest of `Metadata`) have only limited support for
`replaceAllUsesWith()`.
As long as an `MDNode` is pointing at a forward declaration -- the
result of `MDNode::getTemporary()` -- it maintains a side map of its
uses and can RAUW itself. Once the forward declarations are fully
resolved RAUW support is dropped on the ground. This means that
uniquing collisions on changing operands cause nodes to become
"distinct". (This already happened fairly commonly, whenever an
operand went to null.)
If you're constructing complex (non self-reference) `MDNode` cycles,
you need to call `MDNode::resolveCycles()` on each node (or on a
top-level node that somehow references all of the nodes). Also,
don't do that. Metadata cycles (and the RAUW machinery needed to
construct them) are expensive.
- An `MDNode` can only refer to a `Constant` through a bridge called
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).
As a side effect, accessing an operand of an `MDNode` that is known
to be, e.g., `ConstantInt`, takes three steps: first, cast from
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;
third, cast down to `ConstantInt`.
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have
metadata schema owners transition away from using `Constant`s when
the type isn't important (and they don't care about referring to
`GlobalValue`s).
In the meantime, I've added transitional API to the `mdconst`
namespace that matches semantics with the old code, in order to
avoid adding the error-prone three-step equivalent to every call
site. If your old code was:
MDNode *N = foo();
bar(isa <ConstantInt>(N->getOperand(0)));
baz(cast <ConstantInt>(N->getOperand(1)));
bak(cast_or_null <ConstantInt>(N->getOperand(2)));
bat(dyn_cast <ConstantInt>(N->getOperand(3)));
bay(dyn_cast_or_null<ConstantInt>(N->getOperand(4)));
you can trivially match its semantics with:
MDNode *N = foo();
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)));
baz(mdconst::extract <ConstantInt>(N->getOperand(1)));
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)));
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)));
bay(mdconst::dyn_extract_or_null<ConstantInt>(N->getOperand(4)));
and when you transition your metadata schema to `MDInt`:
MDNode *N = foo();
bar(isa <MDInt>(N->getOperand(0)));
baz(cast <MDInt>(N->getOperand(1)));
bak(cast_or_null <MDInt>(N->getOperand(2)));
bat(dyn_cast <MDInt>(N->getOperand(3)));
bay(dyn_cast_or_null<MDInt>(N->getOperand(4)));
- A `CallInst` -- specifically, intrinsic instructions -- can refer to
metadata through a bridge called `MetadataAsValue`. This is a
subclass of `Value` where `getType()->isMetadataTy()`.
`MetadataAsValue` is the *only* class that can legally refer to a
`LocalAsMetadata`, which is a bridged form of non-`Constant` values
like `Argument` and `Instruction`. It can also refer to any other
`Metadata` subclass.
(I'll break all your testcases in a follow-up commit, when I propagate
this change to assembly.)
llvm-svn: 223802
2014-12-09 19:38:53 +01:00
|
|
|
LLVMContext &Context = unwrap(Builder)->getContext();
|
|
|
|
return wrap(MetadataAsValue::get(
|
2015-03-30 21:40:05 +02:00
|
|
|
Context, unwrap(Builder)->getCurrentDebugLocation().getAsMDNode()));
|
2010-02-28 10:45:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) {
|
|
|
|
unwrap(Builder)->SetInstDebugLocation(unwrap<Instruction>(Inst));
|
|
|
|
}
|
|
|
|
|
2019-04-22 15:13:22 +02:00
|
|
|
void LLVMBuilderSetDefaultFPMathTag(LLVMBuilderRef Builder,
|
|
|
|
LLVMMetadataRef FPMathTag) {
|
|
|
|
|
|
|
|
unwrap(Builder)->setDefaultFPMathTag(FPMathTag
|
|
|
|
? unwrap<MDNode>(FPMathTag)
|
|
|
|
: nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMMetadataRef LLVMBuilderGetDefaultFPMathTag(LLVMBuilderRef Builder) {
|
|
|
|
return wrap(unwrap(Builder)->getDefaultFPMathTag());
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
/*--.. Instruction builders ................................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef B) {
|
|
|
|
return wrap(unwrap(B)->CreateRetVoid());
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildRet(LLVMBuilderRef B, LLVMValueRef V) {
|
|
|
|
return wrap(unwrap(B)->CreateRet(unwrap(V)));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildAggregateRet(LLVMBuilderRef B, LLVMValueRef *RetVals,
|
|
|
|
unsigned N) {
|
|
|
|
return wrap(unwrap(B)->CreateAggregateRet(unwrap(RetVals), N));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildBr(LLVMBuilderRef B, LLVMBasicBlockRef Dest) {
|
|
|
|
return wrap(unwrap(B)->CreateBr(unwrap(Dest)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef B, LLVMValueRef If,
|
|
|
|
LLVMBasicBlockRef Then, LLVMBasicBlockRef Else) {
|
|
|
|
return wrap(unwrap(B)->CreateCondBr(unwrap(If), unwrap(Then), unwrap(Else)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef B, LLVMValueRef V,
|
|
|
|
LLVMBasicBlockRef Else, unsigned NumCases) {
|
|
|
|
return wrap(unwrap(B)->CreateSwitch(unwrap(V), unwrap(Else), NumCases));
|
|
|
|
}
|
|
|
|
|
2010-02-28 10:46:06 +01:00
|
|
|
LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr,
|
|
|
|
unsigned NumDests) {
|
|
|
|
return wrap(unwrap(B)->CreateIndirectBr(unwrap(Addr), NumDests));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn,
|
|
|
|
LLVMValueRef *Args, unsigned NumArgs,
|
|
|
|
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
|
|
|
|
const char *Name) {
|
2019-01-14 22:37:48 +01:00
|
|
|
Value *V = unwrap(Fn);
|
|
|
|
FunctionType *FnT =
|
|
|
|
cast<FunctionType>(cast<PointerType>(V->getType())->getElementType());
|
|
|
|
|
|
|
|
return wrap(
|
|
|
|
unwrap(B)->CreateInvoke(FnT, unwrap(Fn), unwrap(Then), unwrap(Catch),
|
|
|
|
makeArrayRef(unwrap(Args), NumArgs), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildInvoke2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
|
|
|
|
LLVMValueRef *Args, unsigned NumArgs,
|
|
|
|
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateInvoke(
|
|
|
|
unwrap<FunctionType>(Ty), unwrap(Fn), unwrap(Then), unwrap(Catch),
|
|
|
|
makeArrayRef(unwrap(Args), NumArgs), Name));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2011-08-12 22:24:12 +02:00
|
|
|
LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
|
2015-07-16 03:16:39 +02:00
|
|
|
LLVMValueRef PersFn, unsigned NumClauses,
|
|
|
|
const char *Name) {
|
|
|
|
// The personality used to live on the landingpad instruction, but now it
|
|
|
|
// lives on the parent function. For compatibility, take the provided
|
|
|
|
// personality and put it on the parent function.
|
|
|
|
if (PersFn)
|
|
|
|
unwrap(B)->GetInsertBlock()->getParent()->setPersonalityFn(
|
|
|
|
cast<Function>(unwrap(PersFn)));
|
2015-06-17 22:52:32 +02:00
|
|
|
return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty), NumClauses, Name));
|
2011-08-12 22:24:12 +02:00
|
|
|
}
|
|
|
|
|
2018-03-30 19:49:53 +02:00
|
|
|
LLVMValueRef LLVMBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
|
|
|
|
LLVMValueRef *Args, unsigned NumArgs,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateCatchPad(unwrap(ParentPad),
|
|
|
|
makeArrayRef(unwrap(Args), NumArgs),
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildCleanupPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
|
|
|
|
LLVMValueRef *Args, unsigned NumArgs,
|
|
|
|
const char *Name) {
|
|
|
|
if (ParentPad == nullptr) {
|
|
|
|
Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
|
|
|
|
ParentPad = wrap(Constant::getNullValue(Ty));
|
|
|
|
}
|
|
|
|
return wrap(unwrap(B)->CreateCleanupPad(unwrap(ParentPad),
|
|
|
|
makeArrayRef(unwrap(Args), NumArgs),
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
2011-07-31 08:30:59 +02:00
|
|
|
LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) {
|
|
|
|
return wrap(unwrap(B)->CreateResume(unwrap(Exn)));
|
|
|
|
}
|
|
|
|
|
2018-03-30 19:49:53 +02:00
|
|
|
LLVMValueRef LLVMBuildCatchSwitch(LLVMBuilderRef B, LLVMValueRef ParentPad,
|
|
|
|
LLVMBasicBlockRef UnwindBB,
|
|
|
|
unsigned NumHandlers, const char *Name) {
|
|
|
|
if (ParentPad == nullptr) {
|
|
|
|
Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
|
|
|
|
ParentPad = wrap(Constant::getNullValue(Ty));
|
|
|
|
}
|
|
|
|
return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(UnwindBB),
|
|
|
|
NumHandlers, Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildCatchRet(LLVMBuilderRef B, LLVMValueRef CatchPad,
|
|
|
|
LLVMBasicBlockRef BB) {
|
|
|
|
return wrap(unwrap(B)->CreateCatchRet(unwrap<CatchPadInst>(CatchPad),
|
|
|
|
unwrap(BB)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildCleanupRet(LLVMBuilderRef B, LLVMValueRef CatchPad,
|
|
|
|
LLVMBasicBlockRef BB) {
|
|
|
|
return wrap(unwrap(B)->CreateCleanupRet(unwrap<CleanupPadInst>(CatchPad),
|
|
|
|
unwrap(BB)));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) {
|
|
|
|
return wrap(unwrap(B)->CreateUnreachable());
|
|
|
|
}
|
|
|
|
|
2008-01-01 06:50:53 +01:00
|
|
|
void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
|
|
|
|
LLVMBasicBlockRef Dest) {
|
|
|
|
unwrap<SwitchInst>(Switch)->addCase(unwrap<ConstantInt>(OnVal), unwrap(Dest));
|
|
|
|
}
|
|
|
|
|
2010-02-28 10:46:06 +01:00
|
|
|
void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest) {
|
|
|
|
unwrap<IndirectBrInst>(IndirectBr)->addDestination(unwrap(Dest));
|
|
|
|
}
|
|
|
|
|
2016-02-18 21:38:32 +01:00
|
|
|
unsigned LLVMGetNumClauses(LLVMValueRef LandingPad) {
|
|
|
|
return unwrap<LandingPadInst>(LandingPad)->getNumClauses();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetClause(LLVMValueRef LandingPad, unsigned Idx) {
|
|
|
|
return wrap(unwrap<LandingPadInst>(LandingPad)->getClause(Idx));
|
|
|
|
}
|
|
|
|
|
2011-08-12 22:24:12 +02:00
|
|
|
void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal) {
|
|
|
|
unwrap<LandingPadInst>(LandingPad)->
|
|
|
|
addClause(cast<Constant>(unwrap(ClauseVal)));
|
|
|
|
}
|
|
|
|
|
2016-02-18 21:38:32 +01:00
|
|
|
LLVMBool LLVMIsCleanup(LLVMValueRef LandingPad) {
|
|
|
|
return unwrap<LandingPadInst>(LandingPad)->isCleanup();
|
|
|
|
}
|
|
|
|
|
2011-08-12 22:24:12 +02:00
|
|
|
void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) {
|
|
|
|
unwrap<LandingPadInst>(LandingPad)->setCleanup(Val);
|
|
|
|
}
|
|
|
|
|
2018-03-30 19:49:53 +02:00
|
|
|
void LLVMAddHandler(LLVMValueRef CatchSwitch, LLVMBasicBlockRef Dest) {
|
|
|
|
unwrap<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Dest));
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned LLVMGetNumHandlers(LLVMValueRef CatchSwitch) {
|
|
|
|
return unwrap<CatchSwitchInst>(CatchSwitch)->getNumHandlers();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMGetHandlers(LLVMValueRef CatchSwitch, LLVMBasicBlockRef *Handlers) {
|
|
|
|
CatchSwitchInst *CSI = unwrap<CatchSwitchInst>(CatchSwitch);
|
2021-03-02 08:40:32 +01:00
|
|
|
for (const BasicBlock *H : CSI->handlers())
|
|
|
|
*Handlers++ = wrap(H);
|
2018-03-30 19:49:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetParentCatchSwitch(LLVMValueRef CatchPad) {
|
|
|
|
return wrap(unwrap<CatchPadInst>(CatchPad)->getCatchSwitch());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetParentCatchSwitch(LLVMValueRef CatchPad, LLVMValueRef CatchSwitch) {
|
|
|
|
unwrap<CatchPadInst>(CatchPad)
|
|
|
|
->setCatchSwitch(unwrap<CatchSwitchInst>(CatchSwitch));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Funclets ...........................................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMGetArgOperand(LLVMValueRef Funclet, unsigned i) {
|
|
|
|
return wrap(unwrap<FuncletPadInst>(Funclet)->getArgOperand(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetArgOperand(LLVMValueRef Funclet, unsigned i, LLVMValueRef value) {
|
|
|
|
unwrap<FuncletPadInst>(Funclet)->setArgOperand(i, unwrap(value));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
/*--.. Arithmetic ..........................................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateAdd(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNSWAdd(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:43 +01:00
|
|
|
LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNUWAdd(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFAdd(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateSub(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:43 +01:00
|
|
|
LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNSWSub(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNUWSub(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildFSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFSub(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateMul(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:43 +01:00
|
|
|
LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNSWMul(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNUWMul(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildFMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFMul(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateUDiv(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2016-10-05 01:32:42 +02:00
|
|
|
LLVMValueRef LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS,
|
|
|
|
LLVMValueRef RHS, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateSDiv(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildExactSDiv(LLVMBuilderRef B, LLVMValueRef LHS,
|
|
|
|
LLVMValueRef RHS, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateExactSDiv(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFDiv(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildURem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateURem(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildSRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateSRem(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildFRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFRem(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildShl(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateShl(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildLShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateLShr(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildAShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateAShr(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildAnd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateAnd(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildOr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateOr(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildXor(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateXor(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:27 +01:00
|
|
|
LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op,
|
|
|
|
LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
2011-10-06 14:39:34 +02:00
|
|
|
return wrap(unwrap(B)->CreateBinOp(Instruction::BinaryOps(map_from_llvmopcode(Op)), unwrap(LHS),
|
2010-02-28 06:51:27 +01:00
|
|
|
unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNeg(unwrap(V), Name));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:43 +01:00
|
|
|
LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNSWNeg(unwrap(V), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNUWNeg(unwrap(V), Name));
|
|
|
|
}
|
|
|
|
|
2009-09-28 23:51:41 +02:00
|
|
|
LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFNeg(unwrap(V), Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateNot(unwrap(V), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Memory ..............................................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
|
|
|
|
const char *Name) {
|
2011-07-18 06:54:35 +02:00
|
|
|
Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
|
2009-11-07 01:16:28 +01:00
|
|
|
Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty));
|
|
|
|
AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy);
|
2013-09-19 01:31:10 +02:00
|
|
|
Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(),
|
|
|
|
ITy, unwrap(Ty), AllocSize,
|
2014-04-09 08:08:46 +02:00
|
|
|
nullptr, nullptr, "");
|
2009-11-07 01:16:28 +01:00
|
|
|
return wrap(unwrap(B)->Insert(Malloc, Twine(Name)));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
|
|
|
|
LLVMValueRef Val, const char *Name) {
|
2011-07-18 06:54:35 +02:00
|
|
|
Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
|
2009-11-07 01:16:28 +01:00
|
|
|
Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty));
|
|
|
|
AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy);
|
2013-09-19 01:31:10 +02:00
|
|
|
Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(),
|
|
|
|
ITy, unwrap(Ty), AllocSize,
|
2014-04-09 08:08:46 +02:00
|
|
|
unwrap(Val), nullptr, "");
|
2009-11-07 01:16:28 +01:00
|
|
|
return wrap(unwrap(B)->Insert(Malloc, Twine(Name)));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2020-02-18 03:48:38 +01:00
|
|
|
LLVMValueRef LLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr,
|
2018-10-29 16:31:40 +01:00
|
|
|
LLVMValueRef Val, LLVMValueRef Len,
|
|
|
|
unsigned Align) {
|
2019-12-09 17:36:50 +01:00
|
|
|
return wrap(unwrap(B)->CreateMemSet(unwrap(Ptr), unwrap(Val), unwrap(Len),
|
|
|
|
MaybeAlign(Align)));
|
2018-10-29 16:31:40 +01:00
|
|
|
}
|
|
|
|
|
2020-02-18 03:48:38 +01:00
|
|
|
LLVMValueRef LLVMBuildMemCpy(LLVMBuilderRef B,
|
2018-10-29 16:31:40 +01:00
|
|
|
LLVMValueRef Dst, unsigned DstAlign,
|
|
|
|
LLVMValueRef Src, unsigned SrcAlign,
|
|
|
|
LLVMValueRef Size) {
|
2019-12-16 15:24:13 +01:00
|
|
|
return wrap(unwrap(B)->CreateMemCpy(unwrap(Dst), MaybeAlign(DstAlign),
|
|
|
|
unwrap(Src), MaybeAlign(SrcAlign),
|
2018-10-29 16:31:40 +01:00
|
|
|
unwrap(Size)));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildMemMove(LLVMBuilderRef B,
|
|
|
|
LLVMValueRef Dst, unsigned DstAlign,
|
|
|
|
LLVMValueRef Src, unsigned SrcAlign,
|
|
|
|
LLVMValueRef Size) {
|
2019-12-16 15:24:13 +01:00
|
|
|
return wrap(unwrap(B)->CreateMemMove(unwrap(Dst), MaybeAlign(DstAlign),
|
|
|
|
unwrap(Src), MaybeAlign(SrcAlign),
|
2018-10-29 16:31:40 +01:00
|
|
|
unwrap(Size)));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty,
|
|
|
|
const char *Name) {
|
2014-04-09 08:08:46 +02:00
|
|
|
return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), nullptr, Name));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty,
|
|
|
|
LLVMValueRef Val, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), unwrap(Val), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) {
|
2009-10-27 00:43:48 +01:00
|
|
|
return wrap(unwrap(B)->Insert(
|
|
|
|
CallInst::CreateFree(unwrap(PointerVal), unwrap(B)->GetInsertBlock())));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal,
|
|
|
|
const char *Name) {
|
2019-01-14 22:37:53 +01:00
|
|
|
Value *V = unwrap(PointerVal);
|
|
|
|
PointerType *Ty = cast<PointerType>(V->getType());
|
|
|
|
|
|
|
|
return wrap(unwrap(B)->CreateLoad(Ty->getElementType(), V, Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildLoad2(LLVMBuilderRef B, LLVMTypeRef Ty,
|
|
|
|
LLVMValueRef PointerVal, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateLoad(unwrap(Ty), unwrap(PointerVal), Name));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2013-09-19 01:31:10 +02:00
|
|
|
LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val,
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef PointerVal) {
|
|
|
|
return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal)));
|
|
|
|
}
|
|
|
|
|
2013-11-20 01:07:49 +01:00
|
|
|
static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) {
|
|
|
|
switch (Ordering) {
|
2016-04-06 23:19:33 +02:00
|
|
|
case LLVMAtomicOrderingNotAtomic: return AtomicOrdering::NotAtomic;
|
|
|
|
case LLVMAtomicOrderingUnordered: return AtomicOrdering::Unordered;
|
|
|
|
case LLVMAtomicOrderingMonotonic: return AtomicOrdering::Monotonic;
|
|
|
|
case LLVMAtomicOrderingAcquire: return AtomicOrdering::Acquire;
|
|
|
|
case LLVMAtomicOrderingRelease: return AtomicOrdering::Release;
|
|
|
|
case LLVMAtomicOrderingAcquireRelease:
|
|
|
|
return AtomicOrdering::AcquireRelease;
|
2013-11-20 01:07:49 +01:00
|
|
|
case LLVMAtomicOrderingSequentiallyConsistent:
|
2016-04-06 23:19:33 +02:00
|
|
|
return AtomicOrdering::SequentiallyConsistent;
|
2013-11-20 01:07:49 +01:00
|
|
|
}
|
2014-10-28 20:46:44 +01:00
|
|
|
|
2013-11-20 01:07:49 +01:00
|
|
|
llvm_unreachable("Invalid LLVMAtomicOrdering value!");
|
|
|
|
}
|
|
|
|
|
2015-08-02 14:16:57 +02:00
|
|
|
static LLVMAtomicOrdering mapToLLVMOrdering(AtomicOrdering Ordering) {
|
|
|
|
switch (Ordering) {
|
2016-04-06 23:19:33 +02:00
|
|
|
case AtomicOrdering::NotAtomic: return LLVMAtomicOrderingNotAtomic;
|
|
|
|
case AtomicOrdering::Unordered: return LLVMAtomicOrderingUnordered;
|
|
|
|
case AtomicOrdering::Monotonic: return LLVMAtomicOrderingMonotonic;
|
|
|
|
case AtomicOrdering::Acquire: return LLVMAtomicOrderingAcquire;
|
|
|
|
case AtomicOrdering::Release: return LLVMAtomicOrderingRelease;
|
|
|
|
case AtomicOrdering::AcquireRelease:
|
|
|
|
return LLVMAtomicOrderingAcquireRelease;
|
|
|
|
case AtomicOrdering::SequentiallyConsistent:
|
2015-08-02 14:16:57 +02:00
|
|
|
return LLVMAtomicOrderingSequentiallyConsistent;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Invalid AtomicOrdering value!");
|
|
|
|
}
|
|
|
|
|
Improve C API support for atomicrmw and cmpxchg.
atomicrmw and cmpxchg have a volatile flag, so allow them to be get and set with LLVM{Get,Set}Volatile. atomicrmw and fence have orderings, so allow them to be get and set with LLVM{Get,Set}Ordering. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
atomicrmw and cmpxchg have a volatile flag, so allow it to be set/get with LLVMGetVolatile and LLVMSetVolatile. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
Add LLVMIsA## for CatchSwitchInst, CallBrInst and FenceInst, as well as AtomicCmpXchgInst and AtomicRMWInst.
Update llvm-c-test to include atomicrmw and fence, and to copy volatile for the four applicable instructions.
Differential Revision: https://reviews.llvm.org/D67132
llvm-svn: 372938
2019-09-26 02:58:55 +02:00
|
|
|
static AtomicRMWInst::BinOp mapFromLLVMRMWBinOp(LLVMAtomicRMWBinOp BinOp) {
|
|
|
|
switch (BinOp) {
|
|
|
|
case LLVMAtomicRMWBinOpXchg: return AtomicRMWInst::Xchg;
|
|
|
|
case LLVMAtomicRMWBinOpAdd: return AtomicRMWInst::Add;
|
|
|
|
case LLVMAtomicRMWBinOpSub: return AtomicRMWInst::Sub;
|
|
|
|
case LLVMAtomicRMWBinOpAnd: return AtomicRMWInst::And;
|
|
|
|
case LLVMAtomicRMWBinOpNand: return AtomicRMWInst::Nand;
|
|
|
|
case LLVMAtomicRMWBinOpOr: return AtomicRMWInst::Or;
|
|
|
|
case LLVMAtomicRMWBinOpXor: return AtomicRMWInst::Xor;
|
|
|
|
case LLVMAtomicRMWBinOpMax: return AtomicRMWInst::Max;
|
|
|
|
case LLVMAtomicRMWBinOpMin: return AtomicRMWInst::Min;
|
|
|
|
case LLVMAtomicRMWBinOpUMax: return AtomicRMWInst::UMax;
|
|
|
|
case LLVMAtomicRMWBinOpUMin: return AtomicRMWInst::UMin;
|
|
|
|
case LLVMAtomicRMWBinOpFAdd: return AtomicRMWInst::FAdd;
|
|
|
|
case LLVMAtomicRMWBinOpFSub: return AtomicRMWInst::FSub;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Invalid LLVMAtomicRMWBinOp value!");
|
|
|
|
}
|
|
|
|
|
|
|
|
static LLVMAtomicRMWBinOp mapToLLVMRMWBinOp(AtomicRMWInst::BinOp BinOp) {
|
|
|
|
switch (BinOp) {
|
|
|
|
case AtomicRMWInst::Xchg: return LLVMAtomicRMWBinOpXchg;
|
|
|
|
case AtomicRMWInst::Add: return LLVMAtomicRMWBinOpAdd;
|
|
|
|
case AtomicRMWInst::Sub: return LLVMAtomicRMWBinOpSub;
|
|
|
|
case AtomicRMWInst::And: return LLVMAtomicRMWBinOpAnd;
|
|
|
|
case AtomicRMWInst::Nand: return LLVMAtomicRMWBinOpNand;
|
|
|
|
case AtomicRMWInst::Or: return LLVMAtomicRMWBinOpOr;
|
|
|
|
case AtomicRMWInst::Xor: return LLVMAtomicRMWBinOpXor;
|
|
|
|
case AtomicRMWInst::Max: return LLVMAtomicRMWBinOpMax;
|
|
|
|
case AtomicRMWInst::Min: return LLVMAtomicRMWBinOpMin;
|
|
|
|
case AtomicRMWInst::UMax: return LLVMAtomicRMWBinOpUMax;
|
|
|
|
case AtomicRMWInst::UMin: return LLVMAtomicRMWBinOpUMin;
|
|
|
|
case AtomicRMWInst::FAdd: return LLVMAtomicRMWBinOpFAdd;
|
|
|
|
case AtomicRMWInst::FSub: return LLVMAtomicRMWBinOpFSub;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Invalid AtomicRMWBinOp value!");
|
|
|
|
}
|
|
|
|
|
2017-07-12 00:23:00 +02:00
|
|
|
// TODO: Should this and other atomic instructions support building with
|
|
|
|
// "syncscope"?
|
2013-11-20 01:07:49 +01:00
|
|
|
LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering Ordering,
|
|
|
|
LLVMBool isSingleThread, const char *Name) {
|
|
|
|
return wrap(
|
|
|
|
unwrap(B)->CreateFence(mapFromLLVMOrdering(Ordering),
|
2017-07-12 00:23:00 +02:00
|
|
|
isSingleThread ? SyncScope::SingleThread
|
|
|
|
: SyncScope::System,
|
2013-11-20 01:07:49 +01:00
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
|
|
|
|
LLVMValueRef *Indices, unsigned NumIndices,
|
|
|
|
const char *Name) {
|
2011-07-22 10:16:57 +02:00
|
|
|
ArrayRef<Value *> IdxList(unwrap(Indices), NumIndices);
|
2019-01-14 22:39:35 +01:00
|
|
|
Value *Val = unwrap(Pointer);
|
|
|
|
Type *Ty =
|
|
|
|
cast<PointerType>(Val->getType()->getScalarType())->getElementType();
|
|
|
|
return wrap(unwrap(B)->CreateGEP(Ty, Val, IdxList, Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
|
|
|
|
LLVMValueRef Pointer, LLVMValueRef *Indices,
|
|
|
|
unsigned NumIndices, const char *Name) {
|
|
|
|
ArrayRef<Value *> IdxList(unwrap(Indices), NumIndices);
|
|
|
|
return wrap(unwrap(B)->CreateGEP(unwrap(Ty), unwrap(Pointer), IdxList, Name));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
|
|
|
|
LLVMValueRef *Indices, unsigned NumIndices,
|
|
|
|
const char *Name) {
|
2011-07-22 10:16:57 +02:00
|
|
|
ArrayRef<Value *> IdxList(unwrap(Indices), NumIndices);
|
2019-01-14 22:39:35 +01:00
|
|
|
Value *Val = unwrap(Pointer);
|
|
|
|
Type *Ty =
|
|
|
|
cast<PointerType>(Val->getType()->getScalarType())->getElementType();
|
|
|
|
return wrap(unwrap(B)->CreateInBoundsGEP(Ty, Val, IdxList, Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildInBoundsGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
|
|
|
|
LLVMValueRef Pointer, LLVMValueRef *Indices,
|
|
|
|
unsigned NumIndices, const char *Name) {
|
|
|
|
ArrayRef<Value *> IdxList(unwrap(Indices), NumIndices);
|
2015-04-03 23:33:42 +02:00
|
|
|
return wrap(
|
2019-01-14 22:39:35 +01:00
|
|
|
unwrap(B)->CreateInBoundsGEP(unwrap(Ty), unwrap(Pointer), IdxList, Name));
|
2009-08-16 04:19:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
|
|
|
|
unsigned Idx, const char *Name) {
|
2019-01-14 22:39:35 +01:00
|
|
|
Value *Val = unwrap(Pointer);
|
|
|
|
Type *Ty =
|
|
|
|
cast<PointerType>(Val->getType()->getScalarType())->getElementType();
|
|
|
|
return wrap(unwrap(B)->CreateStructGEP(Ty, Val, Idx, Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildStructGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
|
|
|
|
LLVMValueRef Pointer, unsigned Idx,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(
|
|
|
|
unwrap(B)->CreateStructGEP(unwrap(Ty), unwrap(Pointer), Idx, Name));
|
2009-08-16 04:19:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateGlobalString(Str, Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateGlobalStringPtr(Str, Name));
|
|
|
|
}
|
|
|
|
|
2012-03-22 04:54:15 +01:00
|
|
|
LLVMBool LLVMGetVolatile(LLVMValueRef MemAccessInst) {
|
|
|
|
Value *P = unwrap<Value>(MemAccessInst);
|
|
|
|
if (LoadInst *LI = dyn_cast<LoadInst>(P))
|
|
|
|
return LI->isVolatile();
|
Improve C API support for atomicrmw and cmpxchg.
atomicrmw and cmpxchg have a volatile flag, so allow them to be get and set with LLVM{Get,Set}Volatile. atomicrmw and fence have orderings, so allow them to be get and set with LLVM{Get,Set}Ordering. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
atomicrmw and cmpxchg have a volatile flag, so allow it to be set/get with LLVMGetVolatile and LLVMSetVolatile. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
Add LLVMIsA## for CatchSwitchInst, CallBrInst and FenceInst, as well as AtomicCmpXchgInst and AtomicRMWInst.
Update llvm-c-test to include atomicrmw and fence, and to copy volatile for the four applicable instructions.
Differential Revision: https://reviews.llvm.org/D67132
llvm-svn: 372938
2019-09-26 02:58:55 +02:00
|
|
|
if (StoreInst *SI = dyn_cast<StoreInst>(P))
|
|
|
|
return SI->isVolatile();
|
|
|
|
if (AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(P))
|
|
|
|
return AI->isVolatile();
|
|
|
|
return cast<AtomicCmpXchgInst>(P)->isVolatile();
|
2012-03-22 04:54:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetVolatile(LLVMValueRef MemAccessInst, LLVMBool isVolatile) {
|
|
|
|
Value *P = unwrap<Value>(MemAccessInst);
|
|
|
|
if (LoadInst *LI = dyn_cast<LoadInst>(P))
|
|
|
|
return LI->setVolatile(isVolatile);
|
Improve C API support for atomicrmw and cmpxchg.
atomicrmw and cmpxchg have a volatile flag, so allow them to be get and set with LLVM{Get,Set}Volatile. atomicrmw and fence have orderings, so allow them to be get and set with LLVM{Get,Set}Ordering. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
atomicrmw and cmpxchg have a volatile flag, so allow it to be set/get with LLVMGetVolatile and LLVMSetVolatile. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
Add LLVMIsA## for CatchSwitchInst, CallBrInst and FenceInst, as well as AtomicCmpXchgInst and AtomicRMWInst.
Update llvm-c-test to include atomicrmw and fence, and to copy volatile for the four applicable instructions.
Differential Revision: https://reviews.llvm.org/D67132
llvm-svn: 372938
2019-09-26 02:58:55 +02:00
|
|
|
if (StoreInst *SI = dyn_cast<StoreInst>(P))
|
|
|
|
return SI->setVolatile(isVolatile);
|
|
|
|
if (AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(P))
|
|
|
|
return AI->setVolatile(isVolatile);
|
|
|
|
return cast<AtomicCmpXchgInst>(P)->setVolatile(isVolatile);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMGetWeak(LLVMValueRef CmpXchgInst) {
|
|
|
|
return unwrap<AtomicCmpXchgInst>(CmpXchgInst)->isWeak();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetWeak(LLVMValueRef CmpXchgInst, LLVMBool isWeak) {
|
|
|
|
return unwrap<AtomicCmpXchgInst>(CmpXchgInst)->setWeak(isWeak);
|
2012-03-22 04:54:15 +01:00
|
|
|
}
|
|
|
|
|
2015-08-02 14:16:57 +02:00
|
|
|
LLVMAtomicOrdering LLVMGetOrdering(LLVMValueRef MemAccessInst) {
|
|
|
|
Value *P = unwrap<Value>(MemAccessInst);
|
|
|
|
AtomicOrdering O;
|
|
|
|
if (LoadInst *LI = dyn_cast<LoadInst>(P))
|
|
|
|
O = LI->getOrdering();
|
Improve C API support for atomicrmw and cmpxchg.
atomicrmw and cmpxchg have a volatile flag, so allow them to be get and set with LLVM{Get,Set}Volatile. atomicrmw and fence have orderings, so allow them to be get and set with LLVM{Get,Set}Ordering. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
atomicrmw and cmpxchg have a volatile flag, so allow it to be set/get with LLVMGetVolatile and LLVMSetVolatile. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
Add LLVMIsA## for CatchSwitchInst, CallBrInst and FenceInst, as well as AtomicCmpXchgInst and AtomicRMWInst.
Update llvm-c-test to include atomicrmw and fence, and to copy volatile for the four applicable instructions.
Differential Revision: https://reviews.llvm.org/D67132
llvm-svn: 372938
2019-09-26 02:58:55 +02:00
|
|
|
else if (StoreInst *SI = dyn_cast<StoreInst>(P))
|
|
|
|
O = SI->getOrdering();
|
2015-08-02 14:16:57 +02:00
|
|
|
else
|
Improve C API support for atomicrmw and cmpxchg.
atomicrmw and cmpxchg have a volatile flag, so allow them to be get and set with LLVM{Get,Set}Volatile. atomicrmw and fence have orderings, so allow them to be get and set with LLVM{Get,Set}Ordering. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
atomicrmw and cmpxchg have a volatile flag, so allow it to be set/get with LLVMGetVolatile and LLVMSetVolatile. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
Add LLVMIsA## for CatchSwitchInst, CallBrInst and FenceInst, as well as AtomicCmpXchgInst and AtomicRMWInst.
Update llvm-c-test to include atomicrmw and fence, and to copy volatile for the four applicable instructions.
Differential Revision: https://reviews.llvm.org/D67132
llvm-svn: 372938
2019-09-26 02:58:55 +02:00
|
|
|
O = cast<AtomicRMWInst>(P)->getOrdering();
|
2015-08-02 14:16:57 +02:00
|
|
|
return mapToLLVMOrdering(O);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetOrdering(LLVMValueRef MemAccessInst, LLVMAtomicOrdering Ordering) {
|
|
|
|
Value *P = unwrap<Value>(MemAccessInst);
|
|
|
|
AtomicOrdering O = mapFromLLVMOrdering(Ordering);
|
|
|
|
|
|
|
|
if (LoadInst *LI = dyn_cast<LoadInst>(P))
|
|
|
|
return LI->setOrdering(O);
|
|
|
|
return cast<StoreInst>(P)->setOrdering(O);
|
|
|
|
}
|
|
|
|
|
Improve C API support for atomicrmw and cmpxchg.
atomicrmw and cmpxchg have a volatile flag, so allow them to be get and set with LLVM{Get,Set}Volatile. atomicrmw and fence have orderings, so allow them to be get and set with LLVM{Get,Set}Ordering. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
atomicrmw and cmpxchg have a volatile flag, so allow it to be set/get with LLVMGetVolatile and LLVMSetVolatile. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
Add LLVMIsA## for CatchSwitchInst, CallBrInst and FenceInst, as well as AtomicCmpXchgInst and AtomicRMWInst.
Update llvm-c-test to include atomicrmw and fence, and to copy volatile for the four applicable instructions.
Differential Revision: https://reviews.llvm.org/D67132
llvm-svn: 372938
2019-09-26 02:58:55 +02:00
|
|
|
LLVMAtomicRMWBinOp LLVMGetAtomicRMWBinOp(LLVMValueRef Inst) {
|
|
|
|
return mapToLLVMRMWBinOp(unwrap<AtomicRMWInst>(Inst)->getOperation());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetAtomicRMWBinOp(LLVMValueRef Inst, LLVMAtomicRMWBinOp BinOp) {
|
|
|
|
unwrap<AtomicRMWInst>(Inst)->setOperation(mapFromLLVMRMWBinOp(BinOp));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
/*--.. Casts ...............................................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateTrunc(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildZExt(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateZExt(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildSExt(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateSExt(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFPToUI(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFPToSI(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateUIToFP(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateSIToFP(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFPTrunc(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFPExt(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreatePtrToInt(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateIntToPtr(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
2013-11-15 02:34:59 +01:00
|
|
|
LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateAddrSpaceCast(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateZExtOrBitCast(unwrap(Val), unwrap(DestTy),
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateSExtOrBitCast(unwrap(Val), unwrap(DestTy),
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateTruncOrBitCast(unwrap(Val), unwrap(DestTy),
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
2010-02-28 06:51:27 +01:00
|
|
|
LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
2011-10-06 14:39:34 +02:00
|
|
|
return wrap(unwrap(B)->CreateCast(Instruction::CastOps(map_from_llvmopcode(Op)), unwrap(Val),
|
2010-02-28 06:51:27 +01:00
|
|
|
unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreatePointerCast(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
2019-01-08 07:23:22 +01:00
|
|
|
LLVMValueRef LLVMBuildIntCast2(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, LLVMBool IsSigned,
|
2019-01-14 18:16:55 +01:00
|
|
|
const char *Name) {
|
|
|
|
return wrap(
|
|
|
|
unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), IsSigned, Name));
|
2019-01-08 07:23:22 +01:00
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val,
|
2009-11-23 11:49:03 +01:00
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy),
|
|
|
|
/*isSigned*/true, Name));
|
2009-08-16 04:19:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
LLVMTypeRef DestTy, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFPCast(unwrap(Val), unwrap(DestTy), Name));
|
|
|
|
}
|
|
|
|
|
2007-09-26 22:56:12 +02:00
|
|
|
/*--.. Comparisons .........................................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildICmp(LLVMBuilderRef B, LLVMIntPredicate Op,
|
|
|
|
LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateICmp(static_cast<ICmpInst::Predicate>(Op),
|
|
|
|
unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef B, LLVMRealPredicate Op,
|
|
|
|
LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFCmp(static_cast<FCmpInst::Predicate>(Op),
|
|
|
|
unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--.. Miscellaneous instructions ..........................................--*/
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) {
|
2011-03-30 13:28:46 +02:00
|
|
|
return wrap(unwrap(B)->CreatePHI(unwrap(Ty), 0, Name));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
|
|
|
|
LLVMValueRef *Args, unsigned NumArgs,
|
|
|
|
const char *Name) {
|
2019-01-14 22:37:42 +01:00
|
|
|
Value *V = unwrap(Fn);
|
|
|
|
FunctionType *FnT =
|
|
|
|
cast<FunctionType>(cast<PointerType>(V->getType())->getElementType());
|
|
|
|
|
|
|
|
return wrap(unwrap(B)->CreateCall(FnT, unwrap(Fn),
|
|
|
|
makeArrayRef(unwrap(Args), NumArgs), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildCall2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
|
|
|
|
LLVMValueRef *Args, unsigned NumArgs,
|
|
|
|
const char *Name) {
|
|
|
|
FunctionType *FTy = unwrap<FunctionType>(Ty);
|
|
|
|
return wrap(unwrap(B)->CreateCall(FTy, unwrap(Fn),
|
|
|
|
makeArrayRef(unwrap(Args), NumArgs), Name));
|
2007-09-26 22:56:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If,
|
|
|
|
LLVMValueRef Then, LLVMValueRef Else,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateSelect(unwrap(If), unwrap(Then), unwrap(Else),
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef B, LLVMValueRef List,
|
|
|
|
LLVMTypeRef Ty, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateVAArg(unwrap(List), unwrap(Ty), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef B, LLVMValueRef VecVal,
|
|
|
|
LLVMValueRef Index, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateExtractElement(unwrap(VecVal), unwrap(Index),
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef B, LLVMValueRef VecVal,
|
|
|
|
LLVMValueRef EltVal, LLVMValueRef Index,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateInsertElement(unwrap(VecVal), unwrap(EltVal),
|
|
|
|
unwrap(Index), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef B, LLVMValueRef V1,
|
|
|
|
LLVMValueRef V2, LLVMValueRef Mask,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateShuffleVector(unwrap(V1), unwrap(V2),
|
|
|
|
unwrap(Mask), Name));
|
|
|
|
}
|
2007-12-12 02:04:30 +01:00
|
|
|
|
2008-11-03 23:55:43 +01:00
|
|
|
LLVMValueRef LLVMBuildExtractValue(LLVMBuilderRef B, LLVMValueRef AggVal,
|
|
|
|
unsigned Index, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateExtractValue(unwrap(AggVal), Index, Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef B, LLVMValueRef AggVal,
|
|
|
|
LLVMValueRef EltVal, unsigned Index,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateInsertValue(unwrap(AggVal), unwrap(EltVal),
|
|
|
|
Index, Name));
|
|
|
|
}
|
|
|
|
|
[IR] Redefine Freeze instruction
Summary:
This patch redefines freeze instruction from being UnaryOperator to a subclass of UnaryInstruction.
ConstantExpr freeze is removed, as discussed in the previous review.
FreezeOperator is not added because there's no ConstantExpr freeze.
`freeze i8* null` test is added to `test/Bindings/llvm-c/freeze.ll` as well, because the null pointer-related bug in `tools/llvm-c/echo.cpp` is now fixed.
InstVisitor has visitFreeze now because freeze is not unaryop anymore.
Reviewers: whitequark, deadalnix, craig.topper, jdoerfert, lebedev.ri
Reviewed By: craig.topper, lebedev.ri
Subscribers: regehr, nlopes, mehdi_amini, hiraditya, steven_wu, dexonsmith, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69932
2019-11-06 17:17:49 +01:00
|
|
|
LLVMValueRef LLVMBuildFreeze(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateFreeze(unwrap(Val), Name));
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:19:59 +02:00
|
|
|
LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateIsNull(unwrap(Val), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef B, LLVMValueRef Val,
|
|
|
|
const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreateIsNotNull(unwrap(Val), Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef B, LLVMValueRef LHS,
|
|
|
|
LLVMValueRef RHS, const char *Name) {
|
|
|
|
return wrap(unwrap(B)->CreatePtrDiff(unwrap(LHS), unwrap(RHS), Name));
|
|
|
|
}
|
|
|
|
|
2013-09-19 01:31:10 +02:00
|
|
|
LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op,
|
|
|
|
LLVMValueRef PTR, LLVMValueRef Val,
|
|
|
|
LLVMAtomicOrdering ordering,
|
2013-04-23 15:21:19 +02:00
|
|
|
LLVMBool singleThread) {
|
Improve C API support for atomicrmw and cmpxchg.
atomicrmw and cmpxchg have a volatile flag, so allow them to be get and set with LLVM{Get,Set}Volatile. atomicrmw and fence have orderings, so allow them to be get and set with LLVM{Get,Set}Ordering. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
atomicrmw and cmpxchg have a volatile flag, so allow it to be set/get with LLVMGetVolatile and LLVMSetVolatile. Add missing LLVMAtomicRMWBinOpFAdd and LLVMAtomicRMWBinOpFSub enum constants. AtomicCmpXchg also has a weak flag, add a getter/setter for that too. Add a getter/setter for the binary-op of an atomicrmw.
Add LLVMIsA## for CatchSwitchInst, CallBrInst and FenceInst, as well as AtomicCmpXchgInst and AtomicRMWInst.
Update llvm-c-test to include atomicrmw and fence, and to copy volatile for the four applicable instructions.
Differential Revision: https://reviews.llvm.org/D67132
llvm-svn: 372938
2019-09-26 02:58:55 +02:00
|
|
|
AtomicRMWInst::BinOp intop = mapFromLLVMRMWBinOp(op);
|
2021-02-09 05:07:12 +01:00
|
|
|
return wrap(unwrap(B)->CreateAtomicRMW(
|
|
|
|
intop, unwrap(PTR), unwrap(Val), MaybeAlign(),
|
|
|
|
mapFromLLVMOrdering(ordering),
|
|
|
|
singleThread ? SyncScope::SingleThread : SyncScope::System));
|
2013-04-23 15:21:19 +02:00
|
|
|
}
|
|
|
|
|
2016-03-19 22:28:28 +01:00
|
|
|
LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr,
|
|
|
|
LLVMValueRef Cmp, LLVMValueRef New,
|
|
|
|
LLVMAtomicOrdering SuccessOrdering,
|
|
|
|
LLVMAtomicOrdering FailureOrdering,
|
|
|
|
LLVMBool singleThread) {
|
|
|
|
|
2021-02-09 05:07:12 +01:00
|
|
|
return wrap(unwrap(B)->CreateAtomicCmpXchg(
|
|
|
|
unwrap(Ptr), unwrap(Cmp), unwrap(New), MaybeAlign(),
|
|
|
|
mapFromLLVMOrdering(SuccessOrdering),
|
|
|
|
mapFromLLVMOrdering(FailureOrdering),
|
|
|
|
singleThread ? SyncScope::SingleThread : SyncScope::System));
|
2016-03-19 22:28:28 +01:00
|
|
|
}
|
|
|
|
|
C API: functions to get mask of a ShuffleVector
This commit fixes a regression (from LLVM 10 to LLVM 11 RC3) in the LLVM
C API.
Previously, commit 1ee6ec2bf removed the mask operand from the
ShuffleVector instruction, storing the mask data separately in the
instruction instead; this reduced the number of operands of
ShuffleVector from 3 to 2. AFAICT, this change unintentionally caused
a regression in the LLVM C API. Specifically, it is no longer possible
to get the mask of a ShuffleVector instruction through the C API. This
patch introduces new functions which together allow a C API user to get
the mask of a ShuffleVector instruction, restoring the functionality
which was previously available through LLVMGetOperand().
This patch also adds tests for this change to the llvm-c-test
executable, which involved adding support for InsertElement,
ExtractElement, and ShuffleVector itself (as well as constant vectors)
to echo.cpp. Previously, vector operations weren't tested at all in
echo.ll.
I also fixed some typos in comments and help-text nearby these changes,
which I happened to spot while developing this patch. Since the typo
fixes are technically unrelated other than being in the same files, I'm
happy to take them out if you'd rather they not be included in the patch.
Differential Revision: https://reviews.llvm.org/D88190
2020-09-25 23:34:23 +02:00
|
|
|
unsigned LLVMGetNumMaskElements(LLVMValueRef SVInst) {
|
|
|
|
Value *P = unwrap<Value>(SVInst);
|
|
|
|
ShuffleVectorInst *I = cast<ShuffleVectorInst>(P);
|
|
|
|
return I->getShuffleMask().size();
|
|
|
|
}
|
|
|
|
|
|
|
|
int LLVMGetMaskValue(LLVMValueRef SVInst, unsigned Elt) {
|
|
|
|
Value *P = unwrap<Value>(SVInst);
|
|
|
|
ShuffleVectorInst *I = cast<ShuffleVectorInst>(P);
|
|
|
|
return I->getMaskValue(Elt);
|
|
|
|
}
|
2020-09-27 01:32:38 +02:00
|
|
|
|
|
|
|
int LLVMGetUndefMaskElem(void) { return UndefMaskElem; }
|
2016-03-19 22:28:28 +01:00
|
|
|
|
|
|
|
LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst) {
|
|
|
|
Value *P = unwrap<Value>(AtomicInst);
|
|
|
|
|
|
|
|
if (AtomicRMWInst *I = dyn_cast<AtomicRMWInst>(P))
|
2017-07-12 00:23:00 +02:00
|
|
|
return I->getSyncScopeID() == SyncScope::SingleThread;
|
|
|
|
return cast<AtomicCmpXchgInst>(P)->getSyncScopeID() ==
|
|
|
|
SyncScope::SingleThread;
|
2016-03-19 22:28:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool NewValue) {
|
|
|
|
Value *P = unwrap<Value>(AtomicInst);
|
2017-07-12 00:23:00 +02:00
|
|
|
SyncScope::ID SSID = NewValue ? SyncScope::SingleThread : SyncScope::System;
|
2016-03-19 22:28:28 +01:00
|
|
|
|
|
|
|
if (AtomicRMWInst *I = dyn_cast<AtomicRMWInst>(P))
|
2017-07-12 00:23:00 +02:00
|
|
|
return I->setSyncScopeID(SSID);
|
|
|
|
return cast<AtomicCmpXchgInst>(P)->setSyncScopeID(SSID);
|
2016-03-19 22:28:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMAtomicOrdering LLVMGetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst) {
|
|
|
|
Value *P = unwrap<Value>(CmpXchgInst);
|
|
|
|
return mapToLLVMOrdering(cast<AtomicCmpXchgInst>(P)->getSuccessOrdering());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetCmpXchgSuccessOrdering(LLVMValueRef CmpXchgInst,
|
|
|
|
LLVMAtomicOrdering Ordering) {
|
|
|
|
Value *P = unwrap<Value>(CmpXchgInst);
|
|
|
|
AtomicOrdering O = mapFromLLVMOrdering(Ordering);
|
|
|
|
|
|
|
|
return cast<AtomicCmpXchgInst>(P)->setSuccessOrdering(O);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMAtomicOrdering LLVMGetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst) {
|
|
|
|
Value *P = unwrap<Value>(CmpXchgInst);
|
|
|
|
return mapToLLVMOrdering(cast<AtomicCmpXchgInst>(P)->getFailureOrdering());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMSetCmpXchgFailureOrdering(LLVMValueRef CmpXchgInst,
|
|
|
|
LLVMAtomicOrdering Ordering) {
|
|
|
|
Value *P = unwrap<Value>(CmpXchgInst);
|
|
|
|
AtomicOrdering O = mapFromLLVMOrdering(Ordering);
|
|
|
|
|
|
|
|
return cast<AtomicCmpXchgInst>(P)->setFailureOrdering(O);
|
|
|
|
}
|
2007-12-12 02:04:30 +01:00
|
|
|
|
|
|
|
/*===-- Module providers --------------------------------------------------===*/
|
|
|
|
|
|
|
|
LLVMModuleProviderRef
|
|
|
|
LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M) {
|
2010-01-27 21:34:15 +01:00
|
|
|
return reinterpret_cast<LLVMModuleProviderRef>(M);
|
2007-12-12 02:04:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP) {
|
|
|
|
delete unwrap(MP);
|
|
|
|
}
|
|
|
|
|
2007-12-19 23:30:40 +01:00
|
|
|
|
|
|
|
/*===-- Memory buffers ----------------------------------------------------===*/
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(
|
|
|
|
const char *Path,
|
|
|
|
LLVMMemoryBufferRef *OutMemBuf,
|
|
|
|
char **OutMessage) {
|
|
|
|
|
2014-07-06 19:43:13 +02:00
|
|
|
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path);
|
|
|
|
if (std::error_code EC = MBOrErr.getError()) {
|
|
|
|
*OutMessage = strdup(EC.message().c_str());
|
|
|
|
return 1;
|
2007-12-19 23:30:40 +01:00
|
|
|
}
|
2014-07-06 19:43:13 +02:00
|
|
|
*OutMemBuf = wrap(MBOrErr.get().release());
|
|
|
|
return 0;
|
2007-12-19 23:30:40 +01:00
|
|
|
}
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
|
|
|
|
char **OutMessage) {
|
2014-07-06 19:43:13 +02:00
|
|
|
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getSTDIN();
|
|
|
|
if (std::error_code EC = MBOrErr.getError()) {
|
|
|
|
*OutMessage = strdup(EC.message().c_str());
|
|
|
|
return 1;
|
2007-12-19 23:30:40 +01:00
|
|
|
}
|
2014-07-06 19:43:13 +02:00
|
|
|
*OutMemBuf = wrap(MBOrErr.get().release());
|
|
|
|
return 0;
|
2007-12-19 23:30:40 +01:00
|
|
|
}
|
|
|
|
|
2013-02-14 20:11:28 +01:00
|
|
|
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange(
|
|
|
|
const char *InputData,
|
|
|
|
size_t InputDataLength,
|
|
|
|
const char *BufferName,
|
2013-02-14 20:40:27 +01:00
|
|
|
LLVMBool RequiresNullTerminator) {
|
2013-02-14 20:11:28 +01:00
|
|
|
|
2014-08-27 22:03:13 +02:00
|
|
|
return wrap(MemoryBuffer::getMemBuffer(StringRef(InputData, InputDataLength),
|
|
|
|
StringRef(BufferName),
|
|
|
|
RequiresNullTerminator).release());
|
2013-02-14 20:11:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy(
|
|
|
|
const char *InputData,
|
|
|
|
size_t InputDataLength,
|
|
|
|
const char *BufferName) {
|
|
|
|
|
2014-08-27 22:03:13 +02:00
|
|
|
return wrap(
|
|
|
|
MemoryBuffer::getMemBufferCopy(StringRef(InputData, InputDataLength),
|
|
|
|
StringRef(BufferName)).release());
|
2013-02-14 20:11:28 +01:00
|
|
|
}
|
|
|
|
|
2013-04-18 21:50:53 +02:00
|
|
|
const char *LLVMGetBufferStart(LLVMMemoryBufferRef MemBuf) {
|
2013-04-17 01:12:47 +02:00
|
|
|
return unwrap(MemBuf)->getBufferStart();
|
|
|
|
}
|
2013-02-14 20:11:28 +01:00
|
|
|
|
2013-04-17 01:12:51 +02:00
|
|
|
size_t LLVMGetBufferSize(LLVMMemoryBufferRef MemBuf) {
|
|
|
|
return unwrap(MemBuf)->getBufferSize();
|
|
|
|
}
|
|
|
|
|
2007-12-19 23:30:40 +01:00
|
|
|
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf) {
|
|
|
|
delete unwrap(MemBuf);
|
|
|
|
}
|
2010-08-07 02:43:20 +02:00
|
|
|
|
2010-10-07 19:55:47 +02:00
|
|
|
/*===-- Pass Registry -----------------------------------------------------===*/
|
|
|
|
|
|
|
|
LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void) {
|
|
|
|
return wrap(PassRegistry::getPassRegistry());
|
|
|
|
}
|
2010-08-07 02:43:20 +02:00
|
|
|
|
|
|
|
/*===-- Pass Manager ------------------------------------------------------===*/
|
|
|
|
|
|
|
|
LLVMPassManagerRef LLVMCreatePassManager() {
|
2015-02-13 11:01:29 +01:00
|
|
|
return wrap(new legacy::PassManager());
|
2010-08-07 02:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M) {
|
2015-02-13 11:01:29 +01:00
|
|
|
return wrap(new legacy::FunctionPassManager(unwrap(M)));
|
2010-08-07 02:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) {
|
|
|
|
return LLVMCreateFunctionPassManagerForModule(
|
|
|
|
reinterpret_cast<LLVMModuleRef>(P));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
|
2015-02-13 11:01:29 +01:00
|
|
|
return unwrap<legacy::PassManager>(PM)->run(*unwrap(M));
|
2010-08-07 02:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM) {
|
2015-02-13 11:01:29 +01:00
|
|
|
return unwrap<legacy::FunctionPassManager>(FPM)->doInitialization();
|
2010-08-07 02:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F) {
|
2015-02-13 11:01:29 +01:00
|
|
|
return unwrap<legacy::FunctionPassManager>(FPM)->run(*unwrap<Function>(F));
|
2010-08-07 02:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM) {
|
2015-02-13 11:01:29 +01:00
|
|
|
return unwrap<legacy::FunctionPassManager>(FPM)->doFinalization();
|
2010-08-07 02:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMDisposePassManager(LLVMPassManagerRef PM) {
|
|
|
|
delete unwrap(PM);
|
|
|
|
}
|
2013-02-17 17:35:51 +01:00
|
|
|
|
|
|
|
/*===-- Threading ------------------------------------------------------===*/
|
|
|
|
|
|
|
|
LLVMBool LLVMStartMultithreaded() {
|
2014-06-27 17:13:01 +02:00
|
|
|
return LLVMIsMultithreaded();
|
2013-02-17 17:35:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMStopMultithreaded() {
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMBool LLVMIsMultithreaded() {
|
|
|
|
return llvm_is_multithreaded();
|
|
|
|
}
|