Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace PartialExecuter getPointerElementType #214

Merged
merged 2 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CGCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
llvm::Function* GetLen = llvm::Intrinsic::getDeclaration(&CGF.CGM.getModule(),
llvm::Intrinsic::cheerp_get_array_len, {elemType});
numElements = CGF.Builder.CreateCall(GetLen, {allocPtr});
llvm::Attribute ETAttr =
llvm::Attribute::get(GetLen->getContext(), llvm::Attribute::ElementType,
ptr.getElementType());
llvm::cast<llvm::CallInst>(numElements)->addParamAttr(0, ETAttr);
} else {
// Derive a char* in the same address space as the pointer.
ptr = CGF.Builder.CreateElementBitCast(ptr, CGF.Int8Ty);
Expand Down
60 changes: 25 additions & 35 deletions llvm/lib/CheerpWriter/PreExecute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,6 @@ static void RetListener(const std::vector<std::unique_ptr<char[]>>& allocas)
}
}

static GenericValue pre_execute_element_distance(FunctionType *FT, ArrayRef<GenericValue> Args)
{
Type* type = FT->getParamType(0)->getPointerElementType();
llvm::Module *module = PreExecute::currentPreExecutePass->currentModule;
uint32_t elementSize = module->getDataLayout().getTypeAllocSize(type);
GenericValue GV;
GV.IntVal = APInt(32, elementSize);
return GV;
}

static char* most_derived_pointer(char* Addr) {
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
const GlobalValue* GV = currentEE->getGlobalValueAtAddress(Addr);
Expand All @@ -82,14 +72,14 @@ static char* most_derived_pointer(char* Addr) {
}

static GenericValue pre_execute_pointer_base(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
char *p = (char *)(currentEE->GVTORP(Args[0]));
return currentEE->RPTOGV(most_derived_pointer(p));
}

static GenericValue pre_execute_pointer_offset(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
GenericValue G;
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
char *p = (char *)(currentEE->GVTORP(Args[0]));
Expand All @@ -99,7 +89,7 @@ static GenericValue pre_execute_pointer_offset(FunctionType *FT,
}

static GenericValue pre_execute_allocate_array(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
size_t size=(size_t)(Args[1].IntVal.getLimitedValue());

Expand Down Expand Up @@ -133,7 +123,7 @@ static GenericValue pre_execute_allocate_array(FunctionType *FT,
}

static GenericValue pre_execute_allocate(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
size_t size=(size_t)(Args[1].IntVal.getLimitedValue());
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
void* ret = PreExecute::currentPreExecutePass->allocator->allocate(size);
Expand All @@ -153,7 +143,7 @@ static GenericValue pre_execute_allocate(FunctionType *FT,
}

static GenericValue pre_execute_reallocate(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
void *p = (void *)(currentEE->GVTORP(Args[0]));
size_t size=(size_t)(Args[1].IntVal.getLimitedValue());
Expand Down Expand Up @@ -190,7 +180,7 @@ static GenericValue pre_execute_reallocate(FunctionType *FT,
}

static GenericValue pre_execute_deallocate(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
#ifdef DEBUG_PRE_EXECUTE
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
void *p = (void *)(currentEE->GVTORP(Args[0]));
Expand All @@ -206,10 +196,12 @@ static GenericValue pre_execute_deallocate(FunctionType *FT,
}

static GenericValue pre_execute_get_array_len(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
const DataLayout& DL = currentEE->getDataLayout();
Type* type = FT->getParamType(0)->getPointerElementType();
assert(Attrs.hasParamAttr(0, Attribute::ElementType) && "ElementType attribute not present on call");
Type* type = Attrs.getParamAttr(0, Attribute::ElementType).getValueAsType();

size_t cookieWords = cheerp::TypeSupport::getArrayCookieSizeAsmJS(DL, type) / sizeof(uint32_t);
uint32_t *cookie = static_cast<uint32_t*>(currentEE->GVTORP(Args[0])) - cookieWords;

Expand All @@ -219,12 +211,12 @@ static GenericValue pre_execute_get_array_len(FunctionType *FT,
}

static GenericValue pre_execute_cast(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
return Args[0];
}

static GenericValue pre_execute_memcpy(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
// Support fully typed memcpy
memcpy(currentEE->GVTORP(Args[0]), currentEE->GVTORP(Args[1]),
Expand All @@ -236,7 +228,7 @@ static GenericValue pre_execute_memcpy(FunctionType *FT,
}

static GenericValue pre_execute_memmove(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
// Support fully typed memmove
memmove(currentEE->GVTORP(Args[0]), currentEE->GVTORP(Args[1]),
Expand All @@ -248,7 +240,7 @@ static GenericValue pre_execute_memmove(FunctionType *FT,
}

static GenericValue pre_execute_memset(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
// Support fully typed memset
memset(currentEE->GVTORP(Args[0]),
Expand All @@ -261,7 +253,7 @@ static GenericValue pre_execute_memset(FunctionType *FT,
}

static GenericValue pre_execute_umax(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
GenericValue GV;
if(Args[0].IntVal.ugt(Args[1].IntVal))
GV.IntVal = Args[0].IntVal;
Expand All @@ -271,7 +263,7 @@ static GenericValue pre_execute_umax(FunctionType *FT,
}

static GenericValue pre_execute_smax(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
GenericValue GV;
if(Args[0].IntVal.sgt(Args[1].IntVal))
GV.IntVal = Args[0].IntVal;
Expand All @@ -281,7 +273,7 @@ static GenericValue pre_execute_smax(FunctionType *FT,
}

static GenericValue pre_execute_abs(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
GenericValue GV;
if(Args[0].IntVal.sgt(APInt(FT->getReturnType()->isIntegerTy(32) ? 32 : 64, 0)))
GV.IntVal = Args[0].IntVal;
Expand All @@ -291,7 +283,7 @@ static GenericValue pre_execute_abs(FunctionType *FT,
}

static GenericValue pre_execute_umin(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
GenericValue GV;
if(Args[0].IntVal.ult(Args[1].IntVal))
GV.IntVal = Args[0].IntVal;
Expand All @@ -301,7 +293,7 @@ static GenericValue pre_execute_umin(FunctionType *FT,
}

static GenericValue pre_execute_smin(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
GenericValue GV;
if(Args[0].IntVal.slt(Args[1].IntVal))
GV.IntVal = Args[0].IntVal;
Expand Down Expand Up @@ -406,7 +398,7 @@ static bool get_subobject_byte_offset(StructType* derivedType, uint32_t baseInde
}

static GenericValue pre_execute_downcast_current(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {

ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
assert(currentEE->getCurrentCaller());
Expand Down Expand Up @@ -435,7 +427,7 @@ static GenericValue pre_execute_downcast_current(FunctionType *FT,
}

static GenericValue pre_execute_downcast(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
// We need to apply the offset in bytes using the bases metadata
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
char* Addr = (char*)currentEE->GVTORP(Args[0]);
Expand Down Expand Up @@ -469,7 +461,7 @@ static GenericValue pre_execute_downcast(FunctionType *FT,
}

static GenericValue pre_execute_virtualcast(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
// We need to apply the offset in bytes using the bases metadata
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
char* Addr = (char*)currentEE->GVTORP(Args[0]);
Expand All @@ -494,12 +486,12 @@ static GenericValue pre_execute_virtualcast(FunctionType *FT,
}

static GenericValue pre_execute_upcast(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
return Args[0];
}

static GenericValue assertEqualImpl(FunctionType *FT,
ArrayRef<GenericValue> Args)
ArrayRef<GenericValue> Args, AttributeList Attrs)
{
ExecutionEngine *currentEE = PreExecute::currentPreExecutePass->currentEE;
bool success = Args[0].IntVal.getZExtValue();
Expand All @@ -515,7 +507,7 @@ static GenericValue assertEqualImpl(FunctionType *FT,
}

static GenericValue emptyFunction(FunctionType *FT,
ArrayRef<GenericValue> Args)
ArrayRef<GenericValue> Args, AttributeList Attrs)
{
return GenericValue(0);
}
Expand Down Expand Up @@ -543,8 +535,6 @@ static void* LazyFunctionCreator(const std::string& funcName)
return (void*)(void(*)())pre_execute_deallocate;
if (strncmp(funcName.c_str(), "llvm.cheerp.get.array.len.", strlen("llvm.cheerp.get.array.len."))==0)
return (void*)(void(*)())pre_execute_get_array_len;
if (strncmp(funcName.c_str(), "llvm.cheerp.element.distance.", strlen("llvm.cheerp.element.distance."))==0)
return (void*)(void(*)())pre_execute_element_distance;
if (strncmp(funcName.c_str(), "llvm.cheerp.pointer.base.", strlen("llvm.cheerp.pointer.base."))==0)
return (void*)(void(*)())pre_execute_pointer_base;
if (strncmp(funcName.c_str(), "llvm.cheerp.pointer.offset.", strlen("llvm.cheerp.pointer.offset."))==0)
Expand Down
30 changes: 16 additions & 14 deletions llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ using namespace llvm;

namespace {

typedef GenericValue (*ExFunc)(FunctionType *, ArrayRef<GenericValue>);
typedef GenericValue (*ExFunc)(FunctionType *, ArrayRef<GenericValue>, AttributeList);
typedef void (*RawFunc)();

struct Functions {
Expand Down Expand Up @@ -274,6 +274,8 @@ GenericValue Interpreter::callExternalFunction(Function *F,
TheInterpreter = this;

auto &Fns = getFunctions();
assert(ECStack.size() > 1);
ExecutionContext &CallerFrame = *(ECStack.end() - 2);
std::unique_lock<sys::Mutex> Guard(Fns.Lock);

// Do a lookup to see if the function is in our cache... this should just be a
Expand All @@ -283,7 +285,7 @@ GenericValue Interpreter::callExternalFunction(Function *F,
if (ExFunc Fn = (FI == Fns.ExportedFunctions.end()) ? lookupFunction(F, LazyFunctionCreator)
: FI->second) {
Guard.unlock();
return Fn(F->getFunctionType(), ArgVals);
return Fn(F->getFunctionType(), ArgVals, CallerFrame.Caller->getAttributes());
}

#ifdef USE_LIBFFI
Expand Down Expand Up @@ -331,7 +333,7 @@ GenericValue Interpreter::callExternalFunction(Function *F,

// void atexit(Function*)
static GenericValue lle_X_atexit(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList /*unused*/) {
assert(Args.size() == 1);
TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0]));
GenericValue GV;
Expand All @@ -340,13 +342,13 @@ static GenericValue lle_X_atexit(FunctionType *FT,
}

// void exit(int)
static GenericValue lle_X_exit(FunctionType *FT, ArrayRef<GenericValue> Args) {
static GenericValue lle_X_exit(FunctionType *FT, ArrayRef<GenericValue> Args, AttributeList /*unused*/) {
TheInterpreter->exitCalled(Args[0]);
return GenericValue();
}

// void abort(void)
static GenericValue lle_X_abort(FunctionType *FT, ArrayRef<GenericValue> Args) {
static GenericValue lle_X_abort(FunctionType *FT, ArrayRef<GenericValue> Args, AttributeList /*unused*/) {
//FIXME: should we report or raise here?
//report_fatal_error("Interpreted program raised SIGABRT");
raise (SIGABRT);
Expand All @@ -356,7 +358,7 @@ static GenericValue lle_X_abort(FunctionType *FT, ArrayRef<GenericValue> Args) {
// int sprintf(char *, const char *, ...) - a very rough implementation to make
// output useful.
static GenericValue lle_X_sprintf(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList /*unused*/) {
char *OutputBuffer = (char *)GVTOP(Args[0]);
const char *FmtStr = (const char *)GVTOP(Args[1]);
unsigned ArgNo = 2;
Expand Down Expand Up @@ -438,19 +440,19 @@ static GenericValue lle_X_sprintf(FunctionType *FT,
// int printf(const char *, ...) - a very rough implementation to make output
// useful.
static GenericValue lle_X_printf(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
char Buffer[10000];
std::vector<GenericValue> NewArgs;
NewArgs.push_back(PTOGV((void*)&Buffer[0]));
llvm::append_range(NewArgs, Args);
GenericValue GV = lle_X_sprintf(FT, NewArgs);
GenericValue GV = lle_X_sprintf(FT, NewArgs, Attrs);
outs() << Buffer;
return GV;
}

// int sscanf(const char *format, ...);
static GenericValue lle_X_sscanf(FunctionType *FT,
ArrayRef<GenericValue> args) {
ArrayRef<GenericValue> args, AttributeList /*unused*/) {
assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!");

char *Args[10];
Expand All @@ -464,7 +466,7 @@ static GenericValue lle_X_sscanf(FunctionType *FT,
}

// int scanf(const char *format, ...);
static GenericValue lle_X_scanf(FunctionType *FT, ArrayRef<GenericValue> args) {
static GenericValue lle_X_scanf(FunctionType *FT, ArrayRef<GenericValue> args, AttributeList /*unused*/) {
assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!");

char *Args[10];
Expand All @@ -480,20 +482,20 @@ static GenericValue lle_X_scanf(FunctionType *FT, ArrayRef<GenericValue> args) {
// int fprintf(FILE *, const char *, ...) - a very rough implementation to make
// output useful.
static GenericValue lle_X_fprintf(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList Attrs) {
assert(Args.size() >= 2);
char Buffer[10000];
std::vector<GenericValue> NewArgs;
NewArgs.push_back(PTOGV(Buffer));
NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end());
GenericValue GV = lle_X_sprintf(FT, NewArgs);
GenericValue GV = lle_X_sprintf(FT, NewArgs, Attrs);

fputs(Buffer, (FILE *) GVTOP(Args[0]));
return GV;
}

static GenericValue lle_X_memset(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList /*unused*/) {
int val = (int)Args[1].IntVal.getSExtValue();
size_t len = (size_t)Args[2].IntVal.getZExtValue();
memset((void *)GVTOP(Args[0]), val, len);
Expand All @@ -505,7 +507,7 @@ static GenericValue lle_X_memset(FunctionType *FT,
}

static GenericValue lle_X_memcpy(FunctionType *FT,
ArrayRef<GenericValue> Args) {
ArrayRef<GenericValue> Args, AttributeList /*unused*/) {
memcpy(GVTOP(Args[0]), GVTOP(Args[1]),
(size_t)(Args[2].IntVal.getLimitedValue()));

Expand Down
Loading