P4 to Git Change 1142726 by emankov@em-hsa-amd on 2015/04/21 07:12:16
ECR #333753 - Compiler Lib/ORCA RT: JIT refactoring Purpose: Make JIT work with different LLVMs - LLVM 3.6 pre-merge task. Synopsis: After splitting of Compiler Lib, JIT appeared to be apart from Compiler Lib's infrastructure and without any wrapping, hence working only with statically linked LLVM from amdocl library (HSAIL), which is unacceptable in the light of 2 LLVMs after upcoming LLVM 3.6 merge. CPU should work on LLVM 3.2. Finally JIT folder is totally removed from the Compiler Lib sources and make system as unneeded laterally from the Compiler Libs infrastructure solution. Testing: pre check-in, smoke, ocl_conformance 1.2 CPU (selectively) Reviewers: Stanislav Mekhanoshin, Brian Sumner, Jan Sjodin, Artem Tamazov, Daniil Fukalov Affected files ... ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/build/Makefile.api#109 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/Makefile#33 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/api/v0_8/acl.cpp#29 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/api/v0_8/aclLoaders.cpp#12 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/Disassembler.cpp#1 move/add ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/Disassembler.h#1 move/add ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/build/Makefile.common#29 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/codegen.cpp#61 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/codegen.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/v0_8/if_acl.cpp#66 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/common/v0_8/if_acl.h#3 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/backends/cpu/x86_be.cpp#29 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/build/Makefile.complib#80 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/include/v0_8/acl.h#9 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/include/v0_8/aclFunctors.h#5 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/include/v0_8/aclStructs.h#16 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/include/v0_8/aclTypes.h#6 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/Makefile#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/include/jit.h#3 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/src/Disassembler.cpp#4 move/delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/src/Disassembler.h#2 move/delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/src/Makefile#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/src/build/Makefile#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/src/build/Makefile.src#5 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/src/jit.cpp#15 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/jit/src/jit.hpp#3 delete ... //depot/stg/opencl/drivers/opencl/compiler/llvm/linux/include/llvm/Config/config.h#27 edit ... //depot/stg/opencl/drivers/opencl/compiler/llvm32/linux/include/llvm/Config/config.h#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubinary.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuprogram.cpp#64 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuprogram.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/tests/ocltst/module/complib/CLAssumptionCheck.cpp#41 edit
Цей коміт міститься в:
@@ -0,0 +1,343 @@
|
||||
//===- Disassembler.cpp - Disassembler for hex strings --------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class implements the disassembler of strings of bytes written in
|
||||
// hexadecimal, from standard input or from a file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Disassembler.h"
|
||||
#include "lib/MC/MCDisassembler/EDDisassembler.h"
|
||||
#include "lib/MC/MCDisassembler/EDInst.h"
|
||||
#include "lib/MC/MCDisassembler/EDOperand.h"
|
||||
#include "lib/MC/MCDisassembler/EDToken.h"
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/MemoryObject.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy;
|
||||
|
||||
namespace {
|
||||
class VectorMemoryObject : public MemoryObject {
|
||||
private:
|
||||
const ByteArrayTy &Bytes;
|
||||
public:
|
||||
VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {}
|
||||
|
||||
uint64_t getBase() const { return 0; }
|
||||
uint64_t getExtent() const { return Bytes.size(); }
|
||||
|
||||
int readByte(uint64_t Addr, uint8_t *Byte) const {
|
||||
if (Addr >= getExtent())
|
||||
return -1;
|
||||
*Byte = Bytes[Addr].first;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static bool PrintInsts(const MCDisassembler &DisAsm,
|
||||
const ByteArrayTy &Bytes,
|
||||
SourceMgr &SM, raw_ostream &Out,
|
||||
MCStreamer &Streamer) {
|
||||
// Wrap the vector in a MemoryObject.
|
||||
VectorMemoryObject memoryObject(Bytes);
|
||||
|
||||
// Disassemble it to strings.
|
||||
uint64_t Size;
|
||||
uint64_t Index;
|
||||
|
||||
for (Index = 0; Index < Bytes.size(); Index += Size) {
|
||||
MCInst Inst;
|
||||
|
||||
MCDisassembler::DecodeStatus S;
|
||||
S = DisAsm.getInstruction(Inst, Size, memoryObject, Index,
|
||||
/*REMOVE*/ nulls(), nulls());
|
||||
switch (S) {
|
||||
case MCDisassembler::Fail:
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
|
||||
SourceMgr::DK_Warning,
|
||||
"invalid instruction encoding");
|
||||
if (Size == 0)
|
||||
Size = 1; // skip illegible bytes
|
||||
break;
|
||||
|
||||
case MCDisassembler::SoftFail:
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
|
||||
SourceMgr::DK_Warning,
|
||||
"potentially undefined instruction encoding");
|
||||
// Fall through
|
||||
|
||||
case MCDisassembler::Success:
|
||||
Streamer.EmitInstruction(Inst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ByteArrayFromString(ByteArrayTy &ByteArray,
|
||||
StringRef &Str,
|
||||
SourceMgr &SM) {
|
||||
while (!Str.empty()) {
|
||||
// Strip horizontal whitespace.
|
||||
if (size_t Pos = Str.find_first_not_of(" \t\r")) {
|
||||
Str = Str.substr(Pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is the end of a line or start of a comment, remove the rest of
|
||||
// the line.
|
||||
if (Str[0] == '\n' || Str[0] == '#') {
|
||||
// Strip to the end of line if we already processed any bytes on this
|
||||
// line. This strips the comment and/or the \n.
|
||||
if (Str[0] == '\n') {
|
||||
Str = Str.substr(1);
|
||||
} else {
|
||||
Str = Str.substr(Str.find_first_of('\n'));
|
||||
if (!Str.empty())
|
||||
Str = Str.substr(1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the current token.
|
||||
size_t Next = Str.find_first_of(" \t\n\r#");
|
||||
StringRef Value = Str.substr(0, Next);
|
||||
|
||||
// Convert to a byte and add to the byte vector.
|
||||
unsigned ByteVal = 0;
|
||||
if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) {
|
||||
// If we have an error, print it and skip to the end of line.
|
||||
SM.PrintMessage(SMLoc::getFromPointer(Value.data()), SourceMgr::DK_Error,
|
||||
"invalid input token");
|
||||
Str = Str.substr(Str.find('\n'));
|
||||
ByteArray.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data()));
|
||||
Str = Str.substr(Next);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Disassembler::disassemble(const Target &T,
|
||||
const std::string &Triple,
|
||||
MCSubtargetInfo &STI,
|
||||
MCStreamer &Streamer,
|
||||
MemoryBuffer &Buffer,
|
||||
SourceMgr &SM,
|
||||
raw_ostream &Out) {
|
||||
OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(STI));
|
||||
if (!DisAsm) {
|
||||
errs() << "error: no disassembler for target " << Triple << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set up initial section manually here
|
||||
Streamer.InitSections();
|
||||
|
||||
bool ErrorOccurred = false;
|
||||
|
||||
// Convert the input to a vector for disassembly.
|
||||
ByteArrayTy ByteArray;
|
||||
StringRef Str = Buffer.getBuffer();
|
||||
|
||||
ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM);
|
||||
|
||||
if (!ByteArray.empty())
|
||||
ErrorOccurred |= PrintInsts(*DisAsm, ByteArray, SM, Out, Streamer);
|
||||
|
||||
return ErrorOccurred;
|
||||
}
|
||||
|
||||
static int byteArrayReader(uint8_t *B, uint64_t A, void *Arg) {
|
||||
ByteArrayTy &ByteArray = *((ByteArrayTy*)Arg);
|
||||
|
||||
if (A >= ByteArray.size())
|
||||
return -1;
|
||||
|
||||
*B = ByteArray[A].first;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) {
|
||||
EDDisassembler &disassembler = *(EDDisassembler *)((void **)Arg)[0];
|
||||
raw_ostream &Out = *(raw_ostream *)((void **)Arg)[1];
|
||||
|
||||
if (const char *regName = disassembler.nameWithRegisterID(R))
|
||||
Out << "[" << regName << "/" << R << "]";
|
||||
|
||||
if (disassembler.registerIsStackPointer(R))
|
||||
Out << "(sp)";
|
||||
if (disassembler.registerIsProgramCounter(R))
|
||||
Out << "(pc)";
|
||||
|
||||
*V = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Disassembler::disassembleEnhanced(const std::string &TS,
|
||||
MemoryBuffer &Buffer,
|
||||
SourceMgr &SM,
|
||||
raw_ostream &Out) {
|
||||
ByteArrayTy ByteArray;
|
||||
StringRef Str = Buffer.getBuffer();
|
||||
|
||||
if (ByteArrayFromString(ByteArray, Str, SM)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Triple T(TS);
|
||||
EDDisassembler::AssemblySyntax AS;
|
||||
|
||||
switch (T.getArch()) {
|
||||
default:
|
||||
errs() << "error: no default assembly syntax for " << TS.c_str() << "\n";
|
||||
return -1;
|
||||
case Triple::arm:
|
||||
case Triple::thumb:
|
||||
AS = EDDisassembler::kEDAssemblySyntaxARMUAL;
|
||||
break;
|
||||
case Triple::x86:
|
||||
case Triple::x86_64:
|
||||
AS = EDDisassembler::kEDAssemblySyntaxX86ATT;
|
||||
break;
|
||||
}
|
||||
|
||||
OwningPtr<EDDisassembler>
|
||||
disassembler(EDDisassembler::getDisassembler(TS.c_str(), AS));
|
||||
|
||||
if (disassembler == 0) {
|
||||
errs() << "error: couldn't get disassembler for " << TS << '\n';
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (ByteArray.size()) {
|
||||
OwningPtr<EDInst>
|
||||
inst(disassembler->createInst(byteArrayReader, 0, &ByteArray));
|
||||
|
||||
if (inst == 0) {
|
||||
errs() << "error: Didn't get an instruction\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
ByteArray.erase (ByteArray.begin(), ByteArray.begin() + inst->byteSize());
|
||||
|
||||
unsigned numTokens = inst->numTokens();
|
||||
if ((int)numTokens < 0) {
|
||||
errs() << "error: couldn't count the instruction's tokens\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned tokenIndex = 0; tokenIndex != numTokens; ++tokenIndex) {
|
||||
EDToken *token;
|
||||
|
||||
if (inst->getToken(token, tokenIndex)) {
|
||||
errs() << "error: Couldn't get token\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *buf;
|
||||
if (token->getString(buf)) {
|
||||
errs() << "error: Couldn't get string for token\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
Out << '[';
|
||||
int operandIndex = token->operandID();
|
||||
|
||||
if (operandIndex >= 0)
|
||||
Out << operandIndex << "-";
|
||||
|
||||
switch (token->type()) {
|
||||
case EDToken::kTokenWhitespace: Out << "w"; break;
|
||||
case EDToken::kTokenPunctuation: Out << "p"; break;
|
||||
case EDToken::kTokenOpcode: Out << "o"; break;
|
||||
case EDToken::kTokenLiteral: Out << "l"; break;
|
||||
case EDToken::kTokenRegister: Out << "r"; break;
|
||||
}
|
||||
|
||||
Out << ":" << buf;
|
||||
|
||||
if (token->type() == EDToken::kTokenLiteral) {
|
||||
Out << "=";
|
||||
if (token->literalSign())
|
||||
Out << "-";
|
||||
uint64_t absoluteValue;
|
||||
if (token->literalAbsoluteValue(absoluteValue)) {
|
||||
errs() << "error: Couldn't get the value of a literal token\n";
|
||||
return -1;
|
||||
}
|
||||
Out << absoluteValue;
|
||||
} else if (token->type() == EDToken::kTokenRegister) {
|
||||
Out << "=";
|
||||
unsigned regID;
|
||||
if (token->registerID(regID)) {
|
||||
errs() << "error: Couldn't get the ID of a register token\n";
|
||||
return -1;
|
||||
}
|
||||
Out << "r" << regID;
|
||||
}
|
||||
|
||||
Out << "]";
|
||||
}
|
||||
|
||||
Out << " ";
|
||||
|
||||
if (inst->isBranch())
|
||||
Out << "<br> ";
|
||||
if (inst->isMove())
|
||||
Out << "<mov> ";
|
||||
|
||||
unsigned numOperands = inst->numOperands();
|
||||
|
||||
if ((int)numOperands < 0) {
|
||||
errs() << "error: Couldn't count operands\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned operandIndex = 0; operandIndex != numOperands;
|
||||
++operandIndex) {
|
||||
Out << operandIndex << ":";
|
||||
|
||||
EDOperand *operand;
|
||||
if (inst->getOperand(operand, operandIndex)) {
|
||||
errs() << "error: couldn't get operand\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t evaluatedResult;
|
||||
void *Arg[] = { disassembler.get(), &Out };
|
||||
if (operand->evaluate(evaluatedResult, verboseEvaluator, Arg)) {
|
||||
errs() << "error: Couldn't evaluate an operand\n";
|
||||
return -1;
|
||||
}
|
||||
Out << "=" << evaluatedResult << " ";
|
||||
}
|
||||
|
||||
Out << '\n';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//===- Disassembler.h - Text File Disassembler ----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class implements the disassembler of strings of bytes written in
|
||||
// hexadecimal, from standard input or from a file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef DISASSEMBLER_H
|
||||
#define DISASSEMBLER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MemoryBuffer;
|
||||
class Target;
|
||||
class raw_ostream;
|
||||
class SourceMgr;
|
||||
class MCSubtargetInfo;
|
||||
class MCStreamer;
|
||||
|
||||
class Disassembler {
|
||||
public:
|
||||
static int disassemble(const Target &T,
|
||||
const std::string &Triple,
|
||||
MCSubtargetInfo &STI,
|
||||
MCStreamer &Streamer,
|
||||
MemoryBuffer &Buffer,
|
||||
SourceMgr &SM,
|
||||
raw_ostream &Out);
|
||||
|
||||
static int disassembleEnhanced(const std::string &tripleString,
|
||||
MemoryBuffer &buffer,
|
||||
SourceMgr &SM,
|
||||
raw_ostream &Out);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "codegen.hpp"
|
||||
#include "utils/libUtils.h"
|
||||
#include "os/os.hpp"
|
||||
#include "jit/src/jit.hpp"
|
||||
#include "utils/target_mappings.h"
|
||||
#ifdef _MSC_VER
|
||||
/* for disabling warning in llvm/ADT/Statistic.h */
|
||||
@@ -15,15 +14,20 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default:4146)
|
||||
#endif
|
||||
#include "llvm/DataLayout.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/DataLayout.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/ExecutionEngine/JITEventListener.h"
|
||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||
#include "llvm/ExecutionEngine/ObjectImage.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
@@ -50,6 +54,301 @@ AdjustCGOptLevel(Module& M, CodeGenOpt::Level OrigOLvl)
|
||||
return OrigOLvl;
|
||||
}
|
||||
|
||||
//!--------------------------------------------------------------------------!//
|
||||
// JIT Memory manager
|
||||
//!--------------------------------------------------------------------------!//
|
||||
OCLMCJITMemoryManager::~OCLMCJITMemoryManager() {
|
||||
for (llvm::SmallVectorImpl<Allocation>::iterator
|
||||
I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end();
|
||||
I != E; ++I)
|
||||
llvm::sys::Memory::releaseMappedMemory(I->first);
|
||||
for (llvm::SmallVectorImpl<Allocation>::iterator
|
||||
I = AllocatedDataMem.begin(), E = AllocatedDataMem.end();
|
||||
I != E; ++I)
|
||||
llvm::sys::Memory::releaseMappedMemory(I->first);
|
||||
}
|
||||
|
||||
void
|
||||
OCLMCJITMemoryManager::deallocateSection(uint8_t* BasePtr) {
|
||||
for (llvm::SmallVectorImpl<Allocation>::iterator
|
||||
I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end();
|
||||
I != E; ++I)
|
||||
if (I->first.base() == BasePtr) {
|
||||
llvm::sys::Memory::releaseMappedMemory(I->first);
|
||||
AllocatedCodeMem.erase(I);
|
||||
return;
|
||||
}
|
||||
for (llvm::SmallVectorImpl<Allocation>::iterator
|
||||
I = AllocatedDataMem.begin(), E = AllocatedDataMem.end();
|
||||
I != E; ++I)
|
||||
if (I->first.base() == BasePtr) {
|
||||
llvm::sys::Memory::releaseMappedMemory(I->first);
|
||||
AllocatedDataMem.erase(I);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void OCLMCJITMemoryManager::reserveMemory(uint64_t Size) {
|
||||
llvm::sys::MemoryBlock Block = allocateSection(Size);
|
||||
AllocatedCodeMem.push_back(Allocation(Block, 64));
|
||||
allocPtr = (uint8_t*)Block.base();
|
||||
allocMaxPtr = allocPtr + Block.size();
|
||||
}
|
||||
|
||||
uint8_t *OCLMCJITMemoryManager::
|
||||
allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) {
|
||||
// The recording memory manager is just a local copy of the remote target.
|
||||
// The alignment requirement is just stored here for later use. Regular
|
||||
// heap storage is sufficient here, but we're using mapped memory to work
|
||||
// around a bug in MCJIT.
|
||||
uint8_t* address = reservedAlloc(Size, Alignment);
|
||||
if(address != NULL) {
|
||||
return address;
|
||||
} else {
|
||||
llvm::sys::MemoryBlock Block = allocateSection(Size);
|
||||
AllocatedCodeMem.push_back(Allocation(Block, Alignment));
|
||||
return (uint8_t*)Block.base();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *OCLMCJITMemoryManager::
|
||||
allocateDataSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID, bool isReasOnly) {
|
||||
bool IsReadOnly = false;
|
||||
// The recording memory manager is just a local copy of the remote target.
|
||||
// The alignment requirement is just stored here for later use. Regular
|
||||
// heap storage is sufficient here, but we're using mapped memory to work
|
||||
// around a bug in MCJIT.
|
||||
uint8_t* address = reservedAlloc(Size, Alignment);
|
||||
if(address != NULL) {
|
||||
return address;
|
||||
} else {
|
||||
llvm::sys::MemoryBlock Block = allocateSection(Size);
|
||||
AllocatedDataMem.push_back(Allocation(Block, Alignment));
|
||||
return (uint8_t*)Block.base();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t * OCLMCJITMemoryManager::reservedAlloc(uintptr_t Size, unsigned Alignment) {
|
||||
if(allocPtr != NULL) {
|
||||
uint8_t *allocPtrAligned =
|
||||
(uint8_t*)(((uintptr_t)allocPtr +
|
||||
((uintptr_t)Alignment-1)) & ~((uintptr_t)Alignment-1));
|
||||
uint8_t *allocPtrNext = allocPtrAligned + Size;
|
||||
if(allocPtrNext < allocMaxPtr) {
|
||||
allocPtr = allocPtrNext;
|
||||
return allocPtrAligned;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
llvm::sys::MemoryBlock OCLMCJITMemoryManager::allocateSection(uintptr_t Size) {
|
||||
llvm::error_code ec;
|
||||
llvm::sys::MemoryBlock MB =
|
||||
llvm::sys::Memory::allocateMappedMemory(Size,
|
||||
&Near,
|
||||
llvm::sys::Memory::MF_READ |
|
||||
llvm::sys::Memory::MF_WRITE |
|
||||
llvm::sys::Memory::MF_EXEC,
|
||||
ec);
|
||||
assert(!ec && MB.base());
|
||||
|
||||
// FIXME: This is part of a work around to keep sections near one another
|
||||
// when MCJIT performs relocations after code emission but before
|
||||
// the generated code is moved to the remote target.
|
||||
// Save this address as the basis for our next request
|
||||
Near = MB;
|
||||
return MB;
|
||||
}
|
||||
|
||||
void OCLMCJITMemoryManager::setMemoryWritable() {
|
||||
assert(!"Unexpected");
|
||||
}
|
||||
|
||||
void OCLMCJITMemoryManager::setMemoryExecutable() {
|
||||
assert(!"Unexpected");
|
||||
}
|
||||
|
||||
void OCLMCJITMemoryManager::setPoisonMemory(bool poison) {
|
||||
assert(!"Unexpected");
|
||||
}
|
||||
|
||||
void OCLMCJITMemoryManager::AllocateGOT() {
|
||||
assert(!"Unexpected");
|
||||
}
|
||||
|
||||
uint8_t *OCLMCJITMemoryManager::getGOTBase() const {
|
||||
assert(!"Unexpected");
|
||||
return 0;
|
||||
}
|
||||
uint8_t *OCLMCJITMemoryManager::startFunctionBody(const llvm::Function *F,
|
||||
uintptr_t &ActualSize) {
|
||||
assert(!"Unexpected");
|
||||
return 0;
|
||||
}
|
||||
uint8_t *OCLMCJITMemoryManager::allocateStub(const llvm::GlobalValue* F,
|
||||
unsigned StubSize,
|
||||
unsigned Alignment) {
|
||||
assert(!"Unexpected");
|
||||
return 0;
|
||||
}
|
||||
void OCLMCJITMemoryManager::endFunctionBody(const llvm::Function *F,
|
||||
uint8_t *FunctionStart,
|
||||
uint8_t *FunctionEnd) {
|
||||
assert(!"Unexpected");
|
||||
}
|
||||
uint8_t *OCLMCJITMemoryManager::allocateSpace(intptr_t Size,
|
||||
unsigned Alignment) {
|
||||
assert(!"Unexpected");
|
||||
return 0;
|
||||
}
|
||||
uint8_t *OCLMCJITMemoryManager::allocateGlobal(uintptr_t Size,
|
||||
unsigned Alignment) {
|
||||
assert(!"Unexpected");
|
||||
return 0;
|
||||
}
|
||||
void OCLMCJITMemoryManager::deallocateFunctionBody(void *Body) {
|
||||
assert(!"Unexpected");
|
||||
}
|
||||
uint8_t* OCLMCJITMemoryManager::startExceptionTable(const llvm::Function* F,
|
||||
uintptr_t &ActualSize) {
|
||||
assert(!"Unexpected");
|
||||
return 0;
|
||||
}
|
||||
void OCLMCJITMemoryManager::endExceptionTable(const llvm::Function *F,
|
||||
uint8_t *TableStart,
|
||||
uint8_t *TableEnd,
|
||||
uint8_t* FrameRegister) {
|
||||
assert(!"Unexpected");
|
||||
}
|
||||
void OCLMCJITMemoryManager::deallocateExceptionTable(void *ET) {
|
||||
assert(!"Unexpected");
|
||||
}
|
||||
|
||||
static int jit_noop() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *OCLMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
|
||||
bool AbortOnFailure) {
|
||||
// We should not invoke parent's ctors/dtors from generated main()!
|
||||
// On Mingw and Cygwin, the symbol __main is resolved to
|
||||
// callee's(eg. tools/lli) one, to invoke wrong duplicated ctors
|
||||
// (and register wrong callee's dtors with atexit(3)).
|
||||
// We expect ExecutionEngine::runStaticConstructorsDestructors()
|
||||
// is called before ExecutionEngine::runFunctionAsMain() is called.
|
||||
if (Name == "__main") return (void*)(intptr_t)&jit_noop;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//!--------------------------------------------------------------------------!//
|
||||
// JIT Event Listener
|
||||
//!--------------------------------------------------------------------------!//
|
||||
class OclJITEventListener : public llvm::JITEventListener
|
||||
{
|
||||
private:
|
||||
std::string* output_;
|
||||
|
||||
public:
|
||||
OclJITEventListener(std::string &output) {
|
||||
output_ = &output;
|
||||
}
|
||||
|
||||
virtual void NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
|
||||
encodeObjectImage(Obj.getData(), *output_);
|
||||
}
|
||||
|
||||
// Encoding and decoding are used to eliminate 0x00 ('\0') from the
|
||||
// string so it is safe to use it as a null terminated c string.
|
||||
// Translate:
|
||||
// 0x00 -> 0xaa 0x55
|
||||
// 0xaa -> 0xaa 0xaa
|
||||
static void encodeObjectImage(std::string objectImage, std::string &encodedObjectImage) {
|
||||
size_t length = objectImage.length();
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
unsigned char c = objectImage[i];
|
||||
switch (c) {
|
||||
case 0x00U:
|
||||
encodedObjectImage.push_back(0xaaU);
|
||||
encodedObjectImage.push_back(0x55U);
|
||||
break;
|
||||
case 0xaaU:
|
||||
encodedObjectImage.push_back(0xaaU);
|
||||
encodedObjectImage.push_back(0xaaU);
|
||||
break;
|
||||
default:
|
||||
encodedObjectImage.push_back(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Translate:
|
||||
// 0xaa 0x55 -> 0x00
|
||||
// 0xaa 0xaa -> 0xaa
|
||||
static void decodeObjectImage(std::string encodedObjectImage, std::string &decodedObjectImage) {
|
||||
size_t length = encodedObjectImage.length();
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
unsigned char c = encodedObjectImage[i];
|
||||
switch (c) {
|
||||
case 0xaaU:
|
||||
{
|
||||
i = i + 1; // Increment to advance two characters
|
||||
unsigned char cnext = encodedObjectImage[i];
|
||||
if (cnext == 0xaaU) {
|
||||
decodedObjectImage.push_back(0xaaU);
|
||||
} else if (cnext == 0x55U) {
|
||||
decodedObjectImage.push_back(0x00U);
|
||||
} else {
|
||||
assert(!"Bad encoding encountered");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
decodedObjectImage.push_back(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void decodeObjectImage(std::string encodedObjectImage, std::string &decodedObjectImage) {
|
||||
OclJITEventListener::decodeObjectImage(encodedObjectImage, decodedObjectImage);
|
||||
}
|
||||
|
||||
// Returns empty string if code generation was successful,
|
||||
// otherwise the return string contains the error the MCJIT encountered.
|
||||
std::string
|
||||
jitCodeGen(llvm::Module* Composite,
|
||||
llvm::TargetMachine* TargetMachine,
|
||||
llvm::CodeGenOpt::Level OLvl,
|
||||
std::string& output) {
|
||||
std::string ErrStr;
|
||||
OclJITEventListener Listener(output);
|
||||
llvm::InitializeNativeTargetAsmParser();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
llvm::JITMemoryManager* MemMgr = new OCLMCJITMemoryManager();
|
||||
llvm::EngineBuilder builder(Composite);
|
||||
builder.setOptLevel(OLvl);
|
||||
builder.setErrorStr(&ErrStr);
|
||||
builder.setJITMemoryManager(MemMgr);
|
||||
builder.setUseMCJIT(true);
|
||||
// builder.setRelocationModel(llvm::Reloc::PIC_)
|
||||
// builder.setCodeModel(llvm::CodeModel::Large)
|
||||
#ifndef ANDROID
|
||||
std::unique_ptr<llvm::ExecutionEngine>
|
||||
TheExecutionEngine(builder.create(TargetMachine));
|
||||
|
||||
TheExecutionEngine->RegisterJITEventListener(&Listener);
|
||||
TheExecutionEngine->finalizeObject();
|
||||
TheExecutionEngine->removeModule(Composite);
|
||||
#endif
|
||||
return ErrStr;
|
||||
}
|
||||
|
||||
int
|
||||
llvmCodeGen(
|
||||
Module* Composite,
|
||||
@@ -231,7 +530,7 @@ llvmCodeGen(
|
||||
// MCJIT(Jan)
|
||||
if(!isGPU && OptionsObj->oVariables->UseJIT) {
|
||||
TargetMachine* jittarget(TheTarget->createTargetMachine(TheTriple.getTriple(),
|
||||
aclutGetCodegenName(binary->target), FeatureStr, targetOptions,
|
||||
aclutGetCodegenName(binary->target), FeatureStr, targetOptions,
|
||||
WINDOWS_SWITCH(Reloc::DynamicNoPIC, Reloc::PIC_),
|
||||
CodeModel::Default, OLvl));
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#ifndef _BE_CODEGEN_HPP_
|
||||
#define _BE_CODEGEN_HPP_
|
||||
#include "compiler_stage.hpp"
|
||||
#include "llvm/ExecutionEngine/JITMemoryManager.h"
|
||||
|
||||
namespace amdcl
|
||||
{
|
||||
@@ -84,4 +85,77 @@ namespace amdcl
|
||||
/*@}*/
|
||||
#endif
|
||||
} // amdcl namespace
|
||||
|
||||
//!--------------------------------------------------------------------------!//
|
||||
// JIT Memory manager
|
||||
//!--------------------------------------------------------------------------!//
|
||||
class OCLMCJITMemoryManager : public llvm::JITMemoryManager {
|
||||
public:
|
||||
typedef std::pair<llvm::sys::MemoryBlock, unsigned> Allocation;
|
||||
|
||||
private:
|
||||
llvm::SmallVector<Allocation, 16> AllocatedDataMem;
|
||||
llvm::SmallVector<Allocation, 16> AllocatedCodeMem;
|
||||
|
||||
// FIXME: This is part of a work around to keep sections near one another
|
||||
// when MCJIT performs relocations after code emission but before
|
||||
// the generated code is moved to the remote target.
|
||||
llvm::sys::MemoryBlock Near;
|
||||
uint8_t * reservedAlloc(uintptr_t Size, unsigned Alignment);
|
||||
llvm::sys::MemoryBlock allocateSection(uintptr_t Size);
|
||||
|
||||
uint8_t *allocPtr;
|
||||
uint8_t *allocMaxPtr;
|
||||
|
||||
public:
|
||||
OCLMCJITMemoryManager() : allocPtr(NULL), allocMaxPtr(NULL) {}
|
||||
virtual ~OCLMCJITMemoryManager();
|
||||
|
||||
typedef llvm::SmallVectorImpl<Allocation>::const_iterator const_data_iterator;
|
||||
typedef llvm::SmallVectorImpl<Allocation>::const_iterator const_code_iterator;
|
||||
|
||||
const_data_iterator data_begin() const { return AllocatedDataMem.begin(); }
|
||||
const_data_iterator data_end() const { return AllocatedDataMem.end(); }
|
||||
const_code_iterator code_begin() const { return AllocatedCodeMem.begin(); }
|
||||
const_code_iterator code_end() const { return AllocatedCodeMem.end(); }
|
||||
|
||||
virtual void reserveMemory(uint64_t size);
|
||||
|
||||
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID);
|
||||
|
||||
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID, bool isReadOnly);
|
||||
|
||||
void *getPointerToNamedFunction(const std::string &Name,
|
||||
bool AbortOnFailure = true);
|
||||
|
||||
bool applyPermissions(std::string *ErrMsg) { return false; }
|
||||
|
||||
// The following obsolete JITMemoryManager calls are stubbed out for
|
||||
// this model.
|
||||
void setMemoryWritable();
|
||||
void setMemoryExecutable();
|
||||
void setPoisonMemory(bool poison);
|
||||
void AllocateGOT();
|
||||
uint8_t *getGOTBase() const;
|
||||
uint8_t *startFunctionBody(const llvm::Function *F, uintptr_t &ActualSize);
|
||||
uint8_t *allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
|
||||
unsigned Alignment);
|
||||
void endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
|
||||
uint8_t *FunctionEnd);
|
||||
uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
|
||||
uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
|
||||
void deallocateFunctionBody(void *Body);
|
||||
uint8_t* startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize);
|
||||
void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
|
||||
uint8_t *TableEnd, uint8_t* FrameRegister);
|
||||
void deallocateExceptionTable(void *ET);
|
||||
void deallocateSection(uint8_t* BasePtr);
|
||||
};
|
||||
|
||||
// The jitCodeGen function creates a string where the '\0' characters
|
||||
// have been encoded. decodeObjectImage puts the '\0' characters back.
|
||||
void decodeObjectImage(std::string encodedObjectImage, std::string &decodedObjectImage);
|
||||
|
||||
#endif // _BE_CODEGEN_HPP_
|
||||
|
||||
@@ -35,22 +35,42 @@
|
||||
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Analysis/Passes.h"
|
||||
#if defined(LEGACY_COMPLIB)
|
||||
#include "Disassembler.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#endif
|
||||
#include "llvm/MC/MCObjectFileInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/Threading.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Bitcode/BitstreamWriter.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Support/IRReader.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/ObjectImage.h"
|
||||
#include "llvm/ExecutionEngine/ObjectBuffer.h"
|
||||
#include "llvm/ExecutionEngine/JITEventListener.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
|
||||
aclLoaderData * ACL_API_ENTRY
|
||||
if_aclCompilerInit(aclCompiler *cl, aclBinary *bin,
|
||||
@@ -58,7 +78,7 @@ if_aclCompilerInit(aclCompiler *cl, aclBinary *bin,
|
||||
{
|
||||
amdcl::acquire_global_lock();
|
||||
char* timing = ::getenv("AMD_DEBUG_HLC_ENABLE_TIMING");
|
||||
if (timing && (timing[0] == '1'))
|
||||
if (timing && (timing[0] == '1'))
|
||||
llvm::TimePassesIsEnabled = true;
|
||||
else
|
||||
llvm::TimePassesIsEnabled = false;
|
||||
@@ -2208,7 +2228,7 @@ void deserializeCLMetadata(const char* ptr, aclMetadata * const md, const size_t
|
||||
tmp_ptr += fmtPtr->fmtStrSize + 1;
|
||||
}
|
||||
assert(md->data_size == size && "The size and data size calculations are off!");
|
||||
assert((size_t)(tmp_ptr - reinterpret_cast<char*>(md))
|
||||
assert((size_t)(tmp_ptr - reinterpret_cast<char*>(md))
|
||||
== size && "Size of data and calculated sizes differ!");
|
||||
}
|
||||
|
||||
@@ -2903,6 +2923,258 @@ if_aclDbgRemoveArgument(aclCompiler *cl,
|
||||
return error_code;
|
||||
}
|
||||
|
||||
static OCLMCJITMemoryManager* memMgr = NULL;
|
||||
|
||||
OCLMCJITMemoryManager* createJITMemoryManager() {
|
||||
if (!memMgr) {
|
||||
memMgr = new OCLMCJITMemoryManager();
|
||||
}
|
||||
return memMgr;
|
||||
}
|
||||
|
||||
aclJITObjectImage ACL_API_ENTRY
|
||||
if_aclJITObjectImageCreate(const void* buffer, size_t length,
|
||||
aclBinary* bin, acl_error* error_code) {
|
||||
llvm::StringRef dataString((const char*)buffer, length);
|
||||
llvm::MemoryBuffer* memBuf = llvm::MemoryBuffer::getMemBufferCopy(dataString);
|
||||
llvm::ObjectBuffer* objBuf = new llvm::ObjectBuffer(memBuf);
|
||||
llvm::RuntimeDyld rtdyld(createJITMemoryManager());
|
||||
llvm::ObjectImage* objectImage = rtdyld.loadObject(objBuf);
|
||||
rtdyld.resolveRelocations();
|
||||
amd::option::Options* options = reinterpret_cast<amd::option::Options*>(bin->options);
|
||||
if (options && options->isDumpFlagSet(amd::option::DUMP_O)) {
|
||||
llvm::StringRef finalData = objectImage->getData();
|
||||
std::string finalDataString = finalData.str();
|
||||
std::string objname = options->getDumpFileName(".elf");
|
||||
std::ofstream out(objname.c_str(), std::fstream::binary | std::fstream::trunc);
|
||||
out << finalDataString;
|
||||
out.close();
|
||||
}
|
||||
return objectImage;
|
||||
}
|
||||
|
||||
aclJITObjectImage ACL_API_ENTRY
|
||||
if_aclJITObjectImageCopy(const void* buffer, size_t length, acl_error* error_code) {
|
||||
llvm::StringRef dataString((const char*)buffer, length);
|
||||
llvm::MemoryBuffer* memBuf = llvm::MemoryBuffer::getMemBufferCopy(dataString);
|
||||
llvm::ObjectBuffer* objBuf = new llvm::ObjectBuffer(memBuf);
|
||||
llvm::RuntimeDyld rtdyld(createJITMemoryManager());
|
||||
llvm::ObjectImage* objectImage = rtdyld.loadObject(objBuf);
|
||||
rtdyld.resolveRelocations();
|
||||
return objectImage;
|
||||
}
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
if_aclJITObjectImageDestroy(aclJITObjectImage image) {
|
||||
llvm::ObjectImage* objectImage(reinterpret_cast<llvm::ObjectImage*>(image));
|
||||
llvm::object::section_iterator end = objectImage->end_sections();
|
||||
llvm::error_code err;
|
||||
for (llvm::object::section_iterator iter = objectImage->begin_sections();
|
||||
iter != end; iter.increment(err)) {
|
||||
llvm::object::SectionRef sectionRef = *iter;
|
||||
uint64_t address;
|
||||
sectionRef.getAddress(address);
|
||||
memMgr->deallocateSection((uint8_t*)address);
|
||||
}
|
||||
delete objectImage;
|
||||
return ACL_SUCCESS;
|
||||
}
|
||||
|
||||
size_t ACL_API_ENTRY
|
||||
if_aclJITObjectImageSize(aclJITObjectImage image, acl_error* error_code) {
|
||||
return (reinterpret_cast<llvm::ObjectImage*>(image))->getData().size();
|
||||
}
|
||||
|
||||
const char* ACL_API_ENTRY
|
||||
if_aclJITObjectImageData(aclJITObjectImage image, acl_error* error_code) {
|
||||
return (reinterpret_cast<llvm::ObjectImage*>(image))->getData().data();
|
||||
}
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
if_aclJITObjectImageFinalize(aclJITObjectImage image) {
|
||||
// TODO: Implement
|
||||
return ACL_SUCCESS;
|
||||
}
|
||||
|
||||
size_t ACL_API_ENTRY
|
||||
if_aclJITObjectImageGetGlobalsSize(aclJITObjectImage image, acl_error* error_code) {
|
||||
size_t totalSize = 0;
|
||||
llvm::ObjectImage* objectImage(reinterpret_cast<llvm::ObjectImage*>(image));
|
||||
llvm::object::section_iterator end = objectImage->end_sections();
|
||||
llvm::error_code err;
|
||||
for (llvm::object::section_iterator iter = objectImage->begin_sections();
|
||||
iter != end; iter.increment(err)) {
|
||||
llvm::object::SectionRef sectionRef = *iter;
|
||||
llvm::StringRef name;
|
||||
uint64_t size;
|
||||
bool isBSS, isData, isText;
|
||||
sectionRef.getName(name);
|
||||
sectionRef.getSize(size);
|
||||
sectionRef.isBSS(isBSS);
|
||||
sectionRef.isData(isData);
|
||||
sectionRef.isText(isText);
|
||||
if ((isBSS || isData) && !isText) {
|
||||
totalSize += (size_t)size;
|
||||
}
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
if_aclJITObjectImageIterateSymbols(aclJITObjectImage image,
|
||||
JITSymbolCallback jit_callback, void* data) {
|
||||
llvm::ObjectImage* objectImage(reinterpret_cast<llvm::ObjectImage*>(image));
|
||||
llvm::object::symbol_iterator end = objectImage->end_symbols();
|
||||
llvm::StringRef name;
|
||||
uint64_t address;
|
||||
llvm::error_code err;
|
||||
for (llvm::object::symbol_iterator iter = objectImage->begin_symbols();
|
||||
iter != end; iter.increment(err)) {
|
||||
llvm::object::SymbolRef symRef = *iter;
|
||||
symRef.getName(name);
|
||||
symRef.getAddress(address);
|
||||
jit_callback(name.str().c_str(), (const void*)address, data);
|
||||
}
|
||||
return ACL_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(LEGACY_COMPLIB)
|
||||
#if 0
|
||||
static std::string getFeaturesString(llvm::StringMap<bool>& Features)
|
||||
{
|
||||
std::string FeatureString;
|
||||
llvm::raw_string_ostream FeatureStream(FeatureString);
|
||||
llvm::SubtargetFeatures TargetFeatures("");
|
||||
llvm::StringMapConstIterator<bool> iterEnd = Features.end();
|
||||
for(llvm::StringMapConstIterator<bool> I = Features.begin();
|
||||
I != iterEnd; ++I) {
|
||||
const llvm::StringMapEntry<bool> entry = *I;
|
||||
TargetFeatures.AddFeature(entry.getKey(), entry.getValue());
|
||||
}
|
||||
TargetFeatures.print(FeatureStream);
|
||||
return FeatureString;
|
||||
}
|
||||
#endif
|
||||
|
||||
static std::string getTripleName()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return LP64_SWITCH("i686-pc-mingw32-amdopencl",
|
||||
"x86_64-pc-mingw32-amdopencl");
|
||||
#else
|
||||
return LP64_SWITCH("i686-pc-linux-amdopencl",
|
||||
"x86_64-pc-linux-amdopencl");
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::string bytesToHexString(const char* data, size_t size) {
|
||||
std::stringstream hexstring;
|
||||
hexstring << std::hex << std::setfill('0');
|
||||
for(size_t i = 0; i < size; ++i) {
|
||||
hexstring << "0x" << std::setw(2) << unsigned((unsigned char)data[i])
|
||||
<< std::endl;
|
||||
}
|
||||
hexstring << std::endl;
|
||||
return hexstring.str();
|
||||
}
|
||||
|
||||
char* ACL_API_ENTRY
|
||||
if_aclJITObjectImageDisassembleKernel(constAclJITObjectImage image,
|
||||
const char* kernel, acl_error* error_code) {
|
||||
const llvm::ObjectImage* objectImage(reinterpret_cast<const llvm::ObjectImage*>(image));
|
||||
llvm::object::symbol_iterator end = objectImage->end_symbols();
|
||||
llvm::error_code err;
|
||||
llvm::StringRef name;
|
||||
std::stringstream disas;
|
||||
for (llvm::object::symbol_iterator iter = objectImage->begin_symbols();
|
||||
iter != end; iter.increment(err)) {
|
||||
llvm::object::SymbolRef symRef = *iter;
|
||||
symRef.getName(name);
|
||||
std::string kernelStr(kernel);
|
||||
if(name == kernelStr) {
|
||||
uint64_t start;
|
||||
uint64_t size;
|
||||
symRef.getSize(size);
|
||||
symRef.getAddress(start);
|
||||
const char *bytes = (const char *)start;
|
||||
const uint64_t extent = 0x10000;
|
||||
uint64_t max_pc = 0;
|
||||
|
||||
llvm::InitializeAllTargetInfos();
|
||||
llvm::InitializeAllTargetMCs();
|
||||
llvm::InitializeAllAsmParsers();
|
||||
llvm::InitializeAllDisassemblers();
|
||||
|
||||
std::string TripleName = getTripleName();
|
||||
std::string Error;
|
||||
const llvm::Target *TheTarget =
|
||||
llvm::TargetRegistry::lookupTarget(TripleName, Error);
|
||||
|
||||
std::string hexstring = bytesToHexString(bytes, size);
|
||||
llvm::StringRef kernelMem(hexstring);
|
||||
llvm::MemoryBuffer *Buffer =
|
||||
llvm::MemoryBuffer::getMemBuffer(kernelMem, "", false);
|
||||
llvm::SourceMgr SrcMgr;
|
||||
|
||||
SrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());
|
||||
|
||||
llvm::OwningPtr<llvm::MCAsmInfo>
|
||||
MAI(TheTarget->createMCAsmInfo(TripleName));
|
||||
assert(MAI && "Unable to create target asm info!");
|
||||
|
||||
llvm::OwningPtr<llvm::MCRegisterInfo>
|
||||
MRI(TheTarget->createMCRegInfo(TripleName));
|
||||
assert(MRI && "Unable to create target register info!");
|
||||
|
||||
llvm::OwningPtr<llvm::MCObjectFileInfo>
|
||||
MOFI(new llvm::MCObjectFileInfo());
|
||||
llvm::MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
|
||||
MOFI->InitMCObjectFileInfo(TripleName, llvm::Reloc::Default,
|
||||
llvm::CodeModel::Default, Ctx);
|
||||
|
||||
Ctx.setAllowTemporaryLabels(true);
|
||||
Ctx.setGenDwarfForAssembly(true);
|
||||
|
||||
std::string MCPU = "corei7-avx";
|
||||
std::string FeaturesStr;
|
||||
|
||||
std::string DisasResultString;
|
||||
llvm::raw_string_ostream OutputStream(DisasResultString);
|
||||
OutputStream.SetUnbuffered();
|
||||
llvm::formatted_raw_ostream FOS(OutputStream);
|
||||
llvm::OwningPtr<llvm::MCStreamer> Str;
|
||||
llvm::OwningPtr<llvm::MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
|
||||
llvm::OwningPtr<llvm::MCSubtargetInfo>
|
||||
STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
|
||||
llvm::MCInstPrinter *IP =
|
||||
TheTarget->createMCInstPrinter(0 /* OutputAsmVariant */, *MAI, *MCII, *MRI,
|
||||
*STI);
|
||||
llvm::MCCodeEmitter *CE = 0;
|
||||
llvm::MCAsmBackend *MAB = 0;
|
||||
if (false) {
|
||||
CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
|
||||
MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
|
||||
}
|
||||
Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
|
||||
/*useLoc*/ true,
|
||||
/*useCFI*/ true,
|
||||
/*useDwarfDirectory*/ true,
|
||||
IP, CE, MAB, false));
|
||||
// int Res = llvm::Disassembler::disassemble(*TheTarget,
|
||||
// TripleName, *STI, *Str,
|
||||
// *Buffer, SrcMgr, OutputStream);
|
||||
|
||||
int Res =
|
||||
llvm::Disassembler::disassembleEnhanced(TripleName, *Buffer, SrcMgr,
|
||||
OutputStream);
|
||||
const char* result = DisasResultString.c_str();
|
||||
return strdup(result);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void myLogFunc(const char * msg, size_t size)
|
||||
{
|
||||
printf("%s\n", msg);
|
||||
@@ -2979,15 +3251,15 @@ bool aclRenderscriptCompile(
|
||||
return false;
|
||||
|
||||
aclTargetInfo target = aclGetTargetInfo("hsail", "Bonaire", &error_code);
|
||||
if (error_code != ACL_SUCCESS)
|
||||
if (error_code != ACL_SUCCESS)
|
||||
return false;
|
||||
|
||||
|
||||
aclBinary *aoe = aclBinaryInit(sizeof(aclBinary), &target, NULL, &error_code);
|
||||
if (error_code != ACL_SUCCESS)
|
||||
if (error_code != ACL_SUCCESS)
|
||||
return false;
|
||||
|
||||
|
||||
error_code = aclInsertSection(aoc, aoe, source, size, aclLLVMIR);
|
||||
if (error_code != ACL_SUCCESS)
|
||||
if (error_code != ACL_SUCCESS)
|
||||
return false;
|
||||
|
||||
#if 1
|
||||
@@ -2996,7 +3268,7 @@ bool aclRenderscriptCompile(
|
||||
#else
|
||||
error_code = aclCompile(aoc, aoe, NULL, ACL_TYPE_RSLLVMIR_BINARY, ACL_TYPE_ISA, myLogFunc);
|
||||
#endif
|
||||
|
||||
|
||||
if (error_code == ACL_FRONTEND_FAILURE) {
|
||||
printf("ACL_FRONTEND_FAILURE.\n");
|
||||
return true;
|
||||
@@ -3007,11 +3279,11 @@ bool aclRenderscriptCompile(
|
||||
|
||||
if ((aoe == NULL) || (aoe->bin == NULL))
|
||||
return false;
|
||||
|
||||
|
||||
char *buffer = NULL;
|
||||
size_t len;
|
||||
acl_error errCode = aclWriteToMem(aoe, reinterpret_cast<void**>(&buffer), &len);
|
||||
if (errCode != ACL_SUCCESS)
|
||||
if (errCode != ACL_SUCCESS)
|
||||
return false;
|
||||
|
||||
*outLen = len;
|
||||
|
||||
@@ -129,4 +129,44 @@ if_aclDbgRemoveArgument(aclCompiler *cl,
|
||||
acl_error ACL_API_ENTRY
|
||||
if_aclSetupLoaderObject(aclCompiler *cl) ACL_API_0_8;
|
||||
|
||||
void* ACL_API_ENTRY
|
||||
if_aclJITObjectImageCreate(const void* buffer,
|
||||
size_t length,
|
||||
aclBinary* bin,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
void* ACL_API_ENTRY
|
||||
if_aclJITObjectImageCopy(const void* buffer,
|
||||
size_t length,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
if_aclJITObjectImageDestroy(aclJITObjectImage buffer) ACL_API_0_8;
|
||||
|
||||
size_t ACL_API_ENTRY
|
||||
if_aclJITObjectImageSize(aclJITObjectImage image,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
const char* ACL_API_ENTRY
|
||||
if_aclJITObjectImageData(aclJITObjectImage image,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
if_aclJITObjectImageFinalize(aclJITObjectImage image) ACL_API_0_8;
|
||||
|
||||
size_t ACL_API_ENTRY
|
||||
if_aclJITObjectImageGetGlobalsSize(aclJITObjectImage image,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
if_aclJITObjectImageIterateSymbols(aclJITObjectImage image,
|
||||
JITSymbolCallback jit_callback, void* data) ACL_API_0_8;
|
||||
|
||||
#if defined(LEGACY_COMPLIB)
|
||||
char* ACL_API_ENTRY
|
||||
if_aclJITObjectImageDisassembleKernel(constAclJITObjectImage image,
|
||||
const char* kernel,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
#endif
|
||||
|
||||
#endif // _IF_ACL_0_8_H_
|
||||
|
||||
@@ -230,11 +230,53 @@ const void* ACL_API_ENTRY
|
||||
size_t *size,
|
||||
acl_error *error_code) ACL_API_0_8;
|
||||
|
||||
//!--------------------------------------------------------------------------!//
|
||||
// Functions that deal with aclJITObjectImage objects.
|
||||
//!--------------------------------------------------------------------------!//
|
||||
aclJITObjectImage ACL_API_ENTRY
|
||||
aclJITObjectImageCreate(aclCompiler *cl, const void* buffer,
|
||||
size_t length, aclBinary* bin, acl_error* error_code);
|
||||
|
||||
aclJITObjectImage ACL_API_ENTRY
|
||||
aclJITObjectImageCopy(aclCompiler *cl, const void* buffer,
|
||||
size_t length, acl_error* error_code);
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
aclJITObjectImageDestroy(aclCompiler *cl, aclJITObjectImage buffer);
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
aclJITObjectImageFinalize(aclCompiler *cl, aclJITObjectImage image);
|
||||
|
||||
size_t ACL_API_ENTRY
|
||||
aclJITObjectImageSize(aclCompiler *cl, aclJITObjectImage image,
|
||||
acl_error* error_code);
|
||||
|
||||
const char* ACL_API_ENTRY
|
||||
aclJITObjectImageData(aclCompiler *cl, aclJITObjectImage image,
|
||||
acl_error* error_code);
|
||||
|
||||
size_t ACL_API_ENTRY
|
||||
aclJITObjectImageGetGlobalsSize(aclCompiler *cl, aclJITObjectImage image,
|
||||
acl_error* error_code);
|
||||
|
||||
acl_error ACL_API_ENTRY
|
||||
aclJITObjectImageIterateSymbols(aclCompiler *cl, aclJITObjectImage image,
|
||||
aclJITSymbolCallback callback, void* data);
|
||||
|
||||
#if defined(LEGACY_COMPLIB)
|
||||
char* ACL_API_ENTRY
|
||||
aclJITObjectImageDisassembleKernel(aclCompiler *cl, constAclJITObjectImage image,
|
||||
const char* kernel, acl_error* error_code);
|
||||
#endif
|
||||
|
||||
//!--------------------------------------------------------------------------!//
|
||||
// Debug functionality
|
||||
//!--------------------------------------------------------------------------!//
|
||||
void aclDumpBinary(const aclBinary *bin);
|
||||
// Functions to retrieve kernel information
|
||||
|
||||
//!--------------------------------------------------------------------------!//
|
||||
// Functions that deal with kenel statistics.
|
||||
//!--------------------------------------------------------------------------!//
|
||||
void aclGetKstatsR800(const void* shader,
|
||||
aclKernelStats &kstats, const char* chip_id);
|
||||
void aclGetKstatsSI(const void* shader,
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
// information on what errors occur.
|
||||
typedef void (*aclLogFunction_0_8)(const char *msg, size_t size);
|
||||
|
||||
typedef bool (*aclJITSymbolCallback)(const char*, const void*, void*);
|
||||
typedef void* aclJITObjectImage;
|
||||
typedef const void* constAclJITObjectImage;
|
||||
|
||||
typedef acl_error
|
||||
(ACL_API_ENTRY *InsertSec_0_8)(aclCompiler *cl,
|
||||
aclBinary *binary,
|
||||
@@ -176,6 +180,47 @@ typedef acl_error
|
||||
typedef acl_error
|
||||
(ACL_API_ENTRY *SetupLoaderObject_0_8)(aclCompiler *cl) ACL_API_0_8;
|
||||
|
||||
typedef aclJITObjectImage
|
||||
(ACL_API_ENTRY *JITObjectImageCreate_0_8)(const void* buffer,
|
||||
size_t length,
|
||||
aclBinary* bin,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
typedef aclJITObjectImage
|
||||
(ACL_API_ENTRY *JITObjectImageCopy_0_8)(const void* buffer,
|
||||
size_t length,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
typedef acl_error
|
||||
(ACL_API_ENTRY *JITObjectImageDestroy_0_8)(aclJITObjectImage image) ACL_API_0_8;
|
||||
|
||||
typedef size_t
|
||||
(ACL_API_ENTRY *JITObjectImageSize_0_8)(aclJITObjectImage image,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
typedef const char *
|
||||
(ACL_API_ENTRY *JITObjectImageData_0_8)(aclJITObjectImage image,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
typedef acl_error
|
||||
(ACL_API_ENTRY *JITObjectImageFinalize_0_8)(aclJITObjectImage image) ACL_API_0_8;
|
||||
|
||||
typedef size_t
|
||||
(ACL_API_ENTRY *JITObjectImageGetGlobalsSize_0_8)(aclJITObjectImage image,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
typedef bool (*JITSymbolCallback_0_8)(const char*, const void*, void*);
|
||||
|
||||
typedef acl_error
|
||||
(ACL_API_ENTRY *JITObjectImageIterateSymbols_0_8)(aclJITObjectImage image,
|
||||
JITSymbolCallback_0_8 jit_callback,
|
||||
void* data) ACL_API_0_8;
|
||||
|
||||
typedef char*
|
||||
(ACL_API_ENTRY *JITObjectImageDisassembleKernel_0_8)(constAclJITObjectImage image,
|
||||
const char* kernel,
|
||||
acl_error* error_code) ACL_API_0_8;
|
||||
|
||||
typedef void*
|
||||
(*AllocFunc_0_8)(size_t size) ACL_API_0_8;
|
||||
|
||||
|
||||
@@ -210,6 +210,15 @@ typedef struct _acl_cl_loader_rec_0_8 {
|
||||
AddDbgArg addDbg;
|
||||
RemoveDbgArg removeDbg;
|
||||
SetupLoaderObject setupLoaderObject;
|
||||
JITObjectImageCreate jitOICreate;
|
||||
JITObjectImageCopy jitOICopy;
|
||||
JITObjectImageDestroy jitOIDestroy;
|
||||
JITObjectImageSize jitOISize;
|
||||
JITObjectImageData jitOIData;
|
||||
JITObjectImageFinalize jitOIFinalize;
|
||||
JITObjectImageGetGlobalsSize jitOIGlobalSize;
|
||||
JITObjectImageIterateSymbols jitOIIterateSymbols;
|
||||
JITObjectImageDisassembleKernel jitOIDisassembleKernel;
|
||||
} aclCLLoader_0_8;
|
||||
|
||||
//! Structure that holds the required functions
|
||||
|
||||
@@ -83,6 +83,16 @@ typedef CGPhase_0_8 CGPhase;
|
||||
typedef DisasmISA_0_8 DisasmISA;
|
||||
typedef AllocFunc_0_8 AllocFunc;
|
||||
typedef FreeFunc_0_8 FreeFunc;
|
||||
typedef JITObjectImageCreate_0_8 JITObjectImageCreate;
|
||||
typedef JITObjectImageCopy_0_8 JITObjectImageCopy;
|
||||
typedef JITObjectImageDestroy_0_8 JITObjectImageDestroy;
|
||||
typedef JITObjectImageSize_0_8 JITObjectImageSize;
|
||||
typedef JITObjectImageData_0_8 JITObjectImageData;
|
||||
typedef JITObjectImageFinalize_0_8 JITObjectImageFinalize;
|
||||
typedef JITObjectImageGetGlobalsSize_0_8 JITObjectImageGetGlobalsSize;
|
||||
typedef JITSymbolCallback_0_8 JITSymbolCallback;
|
||||
typedef JITObjectImageIterateSymbols_0_8 JITObjectImageIterateSymbols;
|
||||
typedef JITObjectImageDisassembleKernel_0_8 JITObjectImageDisassembleKernel;
|
||||
|
||||
#include "aclStructs.h"
|
||||
|
||||
|
||||
@@ -173,9 +173,12 @@ ClBinary::loadX86JIT(Program& program, bool& hasJITBinary)
|
||||
// force recompiling
|
||||
return true;
|
||||
}
|
||||
|
||||
program.setJITBinary(aclJITObjectImageCopy(section, sz));
|
||||
|
||||
acl_error err = ACL_SUCCESS;
|
||||
program.setJITBinary(aclJITObjectImageCopy(program.compiler(), section, sz, &err));
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageCopy failed");
|
||||
return false;
|
||||
}
|
||||
hasJITBinary = true;
|
||||
return true;
|
||||
}
|
||||
@@ -192,10 +195,18 @@ bool
|
||||
ClBinary::storeX86JIT(Program& program)
|
||||
{
|
||||
if (saveISA()) {
|
||||
acl_error err = ACL_SUCCESS;
|
||||
aclJITObjectImage objectImage = program.getJITBinary();
|
||||
const char* x86CodePtr = aclJITObjectImageData(objectImage);
|
||||
size_t x86CodeSize = aclJITObjectImageSize(objectImage);
|
||||
|
||||
size_t x86CodeSize = aclJITObjectImageSize(program.compiler(), objectImage, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageSize failed");
|
||||
return false;
|
||||
}
|
||||
const char* x86CodePtr = aclJITObjectImageData(program.compiler(), objectImage, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageData failed");
|
||||
return false;
|
||||
}
|
||||
elfOut_->addSection(amd::OclElf::JITBINARY, x86CodePtr, x86CodeSize);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
#include "amdrt.inc"
|
||||
#endif
|
||||
|
||||
#include "acl.h"
|
||||
#include "jit.h"
|
||||
|
||||
//CLC_IN_PROCESS_CHANGE
|
||||
extern int openclFrontEnd(const char* cmdline, std::string*, std::string* typInfo = NULL);
|
||||
|
||||
@@ -416,9 +413,11 @@ setSymbolsCallbackCStr(const char* symbol, const void* value, void* data) {
|
||||
struct DisasData {
|
||||
public:
|
||||
DisasData(std::stringstream *stream,
|
||||
aclJITObjectImage im) : asmstream(stream), image(im) {};
|
||||
aclJITObjectImage im, aclCompiler* cmpl)
|
||||
: asmstream(stream), image(im), compiler(cmpl) {};
|
||||
std::stringstream *asmstream;
|
||||
aclJITObjectImage image;
|
||||
aclCompiler* compiler;
|
||||
};
|
||||
|
||||
#if defined(LEGACY_COMPLIB)
|
||||
@@ -428,6 +427,7 @@ disasSymbolsCallback(std::string symbol, const void* value, void* data)
|
||||
DisasData* disasData = (DisasData*) data;
|
||||
std::stringstream &asmstream = *(disasData->asmstream);
|
||||
aclJITObjectImage image = disasData->image;
|
||||
aclCompiler* compiler = disasData->compiler;
|
||||
const char __OpenCL_[] = "__OpenCL_";
|
||||
const char _stub[] = "_stub";
|
||||
const char _kernel[] = "_kernel";
|
||||
@@ -445,8 +445,13 @@ disasSymbolsCallback(std::string symbol, const void* value, void* data)
|
||||
|
||||
if ((symbol.compare(suffixPos, sizeof(_stub) - 1, _stub) == 0) ||
|
||||
(symbol.compare(suffixPos, sizeof(_kernel) - 1, _kernel) == 0)) {
|
||||
acl_error err = ACL_SUCCESS;
|
||||
char* kernelDisas =
|
||||
aclJITObjectImageDisassembleKernel(image, symbol.c_str());
|
||||
aclJITObjectImageDisassembleKernel(compiler, image, symbol.c_str(), &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageDisassembleKernel failed");
|
||||
return false;
|
||||
}
|
||||
asmstream << kernelDisas;
|
||||
free(kernelDisas);
|
||||
}
|
||||
@@ -471,9 +476,9 @@ Program::compileBinaryToISA(amd::option::Options* options)
|
||||
std::string tempName = amd::Os::getTempFileName();
|
||||
dllFileName_ = tempName + "." IF(IS_WINDOWS, "dll", "so");
|
||||
|
||||
acl_error err;
|
||||
acl_error err = ACL_SUCCESS;
|
||||
aclTargetInfo aclinfo = info(has_avx ?
|
||||
/*has_fma4 ? "Bulldozer" :*/
|
||||
/*has_fma4 ? "Bulldozer" :*/
|
||||
"Corei7_AVX" :
|
||||
"Athlon64");
|
||||
|
||||
@@ -554,8 +559,18 @@ Program::compileBinaryToISA(amd::option::Options* options)
|
||||
|
||||
if (options->oVariables->UseJIT) {
|
||||
// printf("Using the jit!\n");
|
||||
aclJITObjectImage objectImage = aclJITObjectImageCreate(isa, len, bin);
|
||||
aclJITObjectImageFinalize(objectImage);
|
||||
aclJITObjectImage objectImage = aclJITObjectImageCreate(compiler(), isa, len, bin, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageCreate failed");
|
||||
aclBinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
err = aclJITObjectImageFinalize(compiler(), objectImage);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageFinalize failed");
|
||||
aclBinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
setJITBinary(objectImage);
|
||||
aclBinaryFini(bin);
|
||||
|
||||
@@ -568,10 +583,14 @@ Program::compileBinaryToISA(amd::option::Options* options)
|
||||
#if 0
|
||||
// Debug stuff. Try and disassemble all kernels and stubs
|
||||
std::stringstream asmtext;
|
||||
DisasData disasData(&asmtext, objectImage);
|
||||
aclJITObjectImageIterateSymbols(objectImage,
|
||||
DisasData disasData(&asmtext, objectImage, compiler());
|
||||
err = aclJITObjectImageIterateSymbols(compiler(), objectImage,
|
||||
disasSymbolsCallbackCStr,
|
||||
&disasData);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageIterateSymbols failed");
|
||||
return false;
|
||||
}
|
||||
printf("DisasSize: %d\nDisas: %s\n", (int)asmtext.str().size(),
|
||||
asmtext.str().c_str());
|
||||
|
||||
@@ -696,7 +715,7 @@ Program::compileImpl(
|
||||
f.close();
|
||||
}
|
||||
|
||||
acl_error err;
|
||||
acl_error err = ACL_SUCCESS;
|
||||
aclTargetInfo aclinfo = info();
|
||||
|
||||
aclBinaryOptions binOpts = {0};
|
||||
@@ -830,12 +849,26 @@ bool
|
||||
Program::loadDllCode(amd::option::Options* options, bool addElfSymbols)
|
||||
{
|
||||
if(options->oVariables->UseJIT) {
|
||||
acl_error err = ACL_SUCCESS;
|
||||
aclJITObjectImage objectImage = getJITBinary();
|
||||
aclJITObjectImageIterateSymbols(objectImage, setKernelInfoCallbackCStr,
|
||||
this);
|
||||
aclJITObjectImageIterateSymbols(objectImage, setSymbolsCallbackCStr,
|
||||
clBinary());
|
||||
setGlobalVariableTotalSize(aclJITObjectImageGetGlobalsSize(objectImage));
|
||||
err = aclJITObjectImageIterateSymbols(compiler(), objectImage,
|
||||
setKernelInfoCallbackCStr, this);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageIterateSymbols failed");
|
||||
return false;
|
||||
}
|
||||
err = aclJITObjectImageIterateSymbols(compiler(), objectImage,
|
||||
setSymbolsCallbackCStr, clBinary());
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageIterateSymbols failed");
|
||||
return false;
|
||||
}
|
||||
size_t size = aclJITObjectImageGetGlobalsSize(compiler(), objectImage, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageGetGlobalsSize failed");
|
||||
return false;
|
||||
}
|
||||
setGlobalVariableTotalSize(size);
|
||||
return true;
|
||||
}
|
||||
// Check if we have a URI
|
||||
@@ -888,10 +921,24 @@ Program::linkImpl(amd::option::Options* options)
|
||||
return false;
|
||||
} else if (hasJITBinary) {
|
||||
aclJITObjectImage objectImage = getJITBinary();
|
||||
aclJITObjectImageIterateSymbols(objectImage, setKernelInfoCallbackCStr, this);
|
||||
aclJITObjectImageIterateSymbols(objectImage, setSymbolsCallbackCStr, clBinary());
|
||||
setGlobalVariableTotalSize(aclJITObjectImageGetGlobalsSize(objectImage));
|
||||
|
||||
acl_error err = aclJITObjectImageIterateSymbols(compiler(), objectImage,
|
||||
setKernelInfoCallbackCStr, this);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageIterateSymbols failed");
|
||||
return false;
|
||||
}
|
||||
err = aclJITObjectImageIterateSymbols(compiler(), objectImage,
|
||||
setSymbolsCallbackCStr, clBinary());
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageIterateSymbols failed");
|
||||
return false;
|
||||
}
|
||||
size_t size = aclJITObjectImageGetGlobalsSize(compiler(), objectImage, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclJITObjectImageGetGlobalsSize failed");
|
||||
return false;
|
||||
}
|
||||
setGlobalVariableTotalSize(size);
|
||||
return true;
|
||||
}
|
||||
// Fall-through to recompile
|
||||
@@ -1184,7 +1231,7 @@ Program::createBinary(amd::option::Options* options)
|
||||
|
||||
const aclTargetInfo &
|
||||
Program::info(const char * str) {
|
||||
acl_error err;
|
||||
acl_error err = ACL_SUCCESS;
|
||||
info_ = aclGetTargetInfo(LP64_SWITCH("x86", "x86-64"), ( str && str[0] == '\0' ? "Generic" : str ), &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclGetTargetInfo failed");
|
||||
@@ -1195,7 +1242,7 @@ Program::info(const char * str) {
|
||||
Program::~Program()
|
||||
{
|
||||
if(getJITBinary() != NULL) {
|
||||
aclJITObjectImageDestroy(getJITBinary());
|
||||
aclJITObjectImageDestroy(compiler(), getJITBinary());
|
||||
}
|
||||
|
||||
if (!sourceFileName_.empty()) {
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "device/cpu/cpubinary.hpp"
|
||||
#include <string>
|
||||
|
||||
#include "jit.h"
|
||||
|
||||
// forward declaration
|
||||
namespace amd {
|
||||
namespace option {
|
||||
@@ -95,9 +93,12 @@ public:
|
||||
aclJITObjectImage getJITBinary() { return this->JITBinary; }
|
||||
void setJITBinary(aclJITObjectImage JITBinary) { this->JITBinary = JITBinary; }
|
||||
|
||||
private:
|
||||
//! Returns the pointer to the Compiler struct
|
||||
//! Became public (prev. private) due to use in cpubinary for aclJIT functionality
|
||||
aclCompiler* compiler() { return static_cast<const Device&>(device()).compiler(); }
|
||||
|
||||
private:
|
||||
|
||||
//! Disable default copy constructor
|
||||
Program(const Program&);
|
||||
|
||||
|
||||
Посилання в новій задачі
Заблокувати користувача