... | ... |
@@ -75,6 +75,7 @@ int cli_bytecode_context_clear(struct cli_bc_ctx *ctx) |
75 | 75 |
|
76 | 76 |
static unsigned typesize(const struct cli_bc *bc, uint16_t type) |
77 | 77 |
{ |
78 |
+ type &= 0x7fff; |
|
78 | 79 |
if (!type) |
79 | 80 |
return 0; |
80 | 81 |
if (type <= 8) |
... | ... |
@@ -90,6 +91,7 @@ static unsigned typesize(const struct cli_bc *bc, uint16_t type) |
90 | 90 |
|
91 | 91 |
static unsigned typealign(const struct cli_bc *bc, uint16_t type) |
92 | 92 |
{ |
93 |
+ type &= 0x7fff; |
|
93 | 94 |
if (type <= 64) { |
94 | 95 |
unsigned size = typesize(bc, type); |
95 | 96 |
return size ? size : 1; |
... | ... |
@@ -434,13 +436,13 @@ static int parseLSig(struct cli_bc *bc, unsigned char *buffer) |
434 | 434 |
char *vnames, *vend = strchr(buffer, ';'); |
435 | 435 |
if (vend) { |
436 | 436 |
bc->lsig = cli_strdup(buffer); |
437 |
+ *vend++ = '\0'; |
|
438 |
+ prefix = buffer; |
|
439 |
+ vnames = strchr(vend, '{'); |
|
437 | 440 |
} else { |
438 | 441 |
/* Not a logical signature, but we still have a virusname */ |
439 | 442 |
bc->lsig = NULL; |
440 | 443 |
} |
441 |
- *vend++ = '\0'; |
|
442 |
- prefix = buffer; |
|
443 |
- vnames = strchr(vend, '{'); |
|
444 | 444 |
|
445 | 445 |
return CL_SUCCESS; |
446 | 446 |
} |
... | ... |
@@ -823,6 +825,8 @@ static int parseFunctionHeader(struct cli_bc *bc, unsigned fn, unsigned char *bu |
823 | 823 |
} |
824 | 824 |
for (i=0;i<all_locals;i++) { |
825 | 825 |
func->types[i] = readNumber(buffer, &offset, len, &ok); |
826 |
+ if (readFixedNumber(buffer, &offset, len, &ok, 1)) |
|
827 |
+ func->types[i] |= 0x8000; |
|
826 | 828 |
} |
827 | 829 |
if (!ok) { |
828 | 830 |
cli_errmsg("Invalid local types\n"); |
... | ... |
@@ -582,7 +582,9 @@ libllvmscalar_la_SOURCES=\ |
582 | 582 |
llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp\ |
583 | 583 |
llvm/lib/Transforms/Scalar/CodeGenLICM.cpp\ |
584 | 584 |
llvm/lib/Transforms/Scalar/DCE.cpp\ |
585 |
- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp |
|
585 |
+ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp\ |
|
586 |
+ llvm/lib/Transforms/Scalar/ConstantProp.cpp\ |
|
587 |
+ llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp |
|
586 | 588 |
|
587 | 589 |
libllvmtransformutils_la_CPPFLAGS=$(LLVM_INCLUDES) $(LLVM_DEFS) |
588 | 590 |
libllvmtransformutils_la_CXXFLAGS=$(LLVM_CXXFLAGS) -fno-exceptions |
... | ... |
@@ -355,7 +355,9 @@ libllvmmc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ |
355 | 355 |
libllvmscalar_la_LIBADD = |
356 | 356 |
am_libllvmscalar_la_OBJECTS = libllvmscalar_la-CodeGenPrepare.lo \ |
357 | 357 |
libllvmscalar_la-CodeGenLICM.lo libllvmscalar_la-DCE.lo \ |
358 |
- libllvmscalar_la-LoopStrengthReduce.lo |
|
358 |
+ libllvmscalar_la-LoopStrengthReduce.lo \ |
|
359 |
+ libllvmscalar_la-ConstantProp.lo \ |
|
360 |
+ libllvmscalar_la-SimplifyCFGPass.lo |
|
359 | 361 |
libllvmscalar_la_OBJECTS = $(am_libllvmscalar_la_OBJECTS) |
360 | 362 |
libllvmscalar_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ |
361 | 363 |
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ |
... | ... |
@@ -1399,7 +1401,9 @@ libllvmscalar_la_SOURCES = \ |
1399 | 1399 |
llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp\ |
1400 | 1400 |
llvm/lib/Transforms/Scalar/CodeGenLICM.cpp\ |
1401 | 1401 |
llvm/lib/Transforms/Scalar/DCE.cpp\ |
1402 |
- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp |
|
1402 |
+ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp\ |
|
1403 |
+ llvm/lib/Transforms/Scalar/ConstantProp.cpp\ |
|
1404 |
+ llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp |
|
1403 | 1405 |
|
1404 | 1406 |
libllvmtransformutils_la_CPPFLAGS = $(LLVM_INCLUDES) $(LLVM_DEFS) |
1405 | 1407 |
libllvmtransformutils_la_CXXFLAGS = $(LLVM_CXXFLAGS) -fno-exceptions |
... | ... |
@@ -1937,8 +1941,10 @@ distclean-compile: |
1937 | 1937 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmmc_la-TargetAsmParser.Plo@am__quote@ |
1938 | 1938 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmscalar_la-CodeGenLICM.Plo@am__quote@ |
1939 | 1939 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmscalar_la-CodeGenPrepare.Plo@am__quote@ |
1940 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmscalar_la-ConstantProp.Plo@am__quote@ |
|
1940 | 1941 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmscalar_la-DCE.Plo@am__quote@ |
1941 | 1942 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmscalar_la-LoopStrengthReduce.Plo@am__quote@ |
1943 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmscalar_la-SimplifyCFGPass.Plo@am__quote@ |
|
1942 | 1944 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmsdag_la-AsmPrinter.Plo@am__quote@ |
1943 | 1945 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmsdag_la-CallingConvLower.Plo@am__quote@ |
1944 | 1946 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmsdag_la-DAGCombiner.Plo@am__quote@ |
... | ... |
@@ -3731,6 +3737,22 @@ libllvmscalar_la-LoopStrengthReduce.lo: llvm/lib/Transforms/Scalar/LoopStrengthR |
3731 | 3731 |
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
3732 | 3732 |
@am__fastdepCXX_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libllvmscalar_la_CPPFLAGS) $(CPPFLAGS) $(libllvmscalar_la_CXXFLAGS) $(CXXFLAGS) -c -o libllvmscalar_la-LoopStrengthReduce.lo `test -f 'llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp' || echo '$(srcdir)/'`llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp |
3733 | 3733 |
|
3734 |
+libllvmscalar_la-ConstantProp.lo: llvm/lib/Transforms/Scalar/ConstantProp.cpp |
|
3735 |
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libllvmscalar_la_CPPFLAGS) $(CPPFLAGS) $(libllvmscalar_la_CXXFLAGS) $(CXXFLAGS) -MT libllvmscalar_la-ConstantProp.lo -MD -MP -MF $(DEPDIR)/libllvmscalar_la-ConstantProp.Tpo -c -o libllvmscalar_la-ConstantProp.lo `test -f 'llvm/lib/Transforms/Scalar/ConstantProp.cpp' || echo '$(srcdir)/'`llvm/lib/Transforms/Scalar/ConstantProp.cpp |
|
3736 |
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libllvmscalar_la-ConstantProp.Tpo $(DEPDIR)/libllvmscalar_la-ConstantProp.Plo |
|
3737 |
+@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ |
|
3738 |
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='llvm/lib/Transforms/Scalar/ConstantProp.cpp' object='libllvmscalar_la-ConstantProp.lo' libtool=yes @AMDEPBACKSLASH@ |
|
3739 |
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
3740 |
+@am__fastdepCXX_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libllvmscalar_la_CPPFLAGS) $(CPPFLAGS) $(libllvmscalar_la_CXXFLAGS) $(CXXFLAGS) -c -o libllvmscalar_la-ConstantProp.lo `test -f 'llvm/lib/Transforms/Scalar/ConstantProp.cpp' || echo '$(srcdir)/'`llvm/lib/Transforms/Scalar/ConstantProp.cpp |
|
3741 |
+ |
|
3742 |
+libllvmscalar_la-SimplifyCFGPass.lo: llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp |
|
3743 |
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libllvmscalar_la_CPPFLAGS) $(CPPFLAGS) $(libllvmscalar_la_CXXFLAGS) $(CXXFLAGS) -MT libllvmscalar_la-SimplifyCFGPass.lo -MD -MP -MF $(DEPDIR)/libllvmscalar_la-SimplifyCFGPass.Tpo -c -o libllvmscalar_la-SimplifyCFGPass.lo `test -f 'llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp' || echo '$(srcdir)/'`llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp |
|
3744 |
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libllvmscalar_la-SimplifyCFGPass.Tpo $(DEPDIR)/libllvmscalar_la-SimplifyCFGPass.Plo |
|
3745 |
+@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ |
|
3746 |
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp' object='libllvmscalar_la-SimplifyCFGPass.lo' libtool=yes @AMDEPBACKSLASH@ |
|
3747 |
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
|
3748 |
+@am__fastdepCXX_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libllvmscalar_la_CPPFLAGS) $(CPPFLAGS) $(libllvmscalar_la_CXXFLAGS) $(CXXFLAGS) -c -o libllvmscalar_la-SimplifyCFGPass.lo `test -f 'llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp' || echo '$(srcdir)/'`llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp |
|
3749 |
+ |
|
3734 | 3750 |
libllvmsdag_la-CallingConvLower.lo: llvm/lib/CodeGen/SelectionDAG/CallingConvLower.cpp |
3735 | 3751 |
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libllvmsdag_la_CPPFLAGS) $(CPPFLAGS) $(libllvmsdag_la_CXXFLAGS) $(CXXFLAGS) -MT libllvmsdag_la-CallingConvLower.lo -MD -MP -MF $(DEPDIR)/libllvmsdag_la-CallingConvLower.Tpo -c -o libllvmsdag_la-CallingConvLower.lo `test -f 'llvm/lib/CodeGen/SelectionDAG/CallingConvLower.cpp' || echo '$(srcdir)/'`llvm/lib/CodeGen/SelectionDAG/CallingConvLower.cpp |
3736 | 3752 |
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libllvmsdag_la-CallingConvLower.Tpo $(DEPDIR)/libllvmsdag_la-CallingConvLower.Plo |
... | ... |
@@ -99,7 +99,7 @@ static void NORETURN jit_exception_handler(void) |
99 | 99 |
void llvm_error_handler(void *user_data, const std::string &reason) |
100 | 100 |
{ |
101 | 101 |
// Output it to stderr, it might exceed the 1k/4k limit of cli_errmsg |
102 |
- errs() << reason; |
|
102 |
+ errs() << MODULE << reason; |
|
103 | 103 |
jit_exception_handler(); |
104 | 104 |
} |
105 | 105 |
|
... | ... |
@@ -179,6 +179,7 @@ public: |
179 | 179 |
|
180 | 180 |
const Type *get(uint16_t ty) |
181 | 181 |
{ |
182 |
+ ty &= 0x7fff; |
|
182 | 183 |
if (ty < 69) |
183 | 184 |
return getStatic(ty); |
184 | 185 |
ty -= 69; |
... | ... |
@@ -225,9 +226,12 @@ private: |
225 | 225 |
return Values[operand]; |
226 | 226 |
if (operand < func->numValues) { |
227 | 227 |
Value *V = Values[operand]; |
228 |
- if (V->getType() == Ty) |
|
228 |
+ if (func->types[operand]&0x8000 && V->getType() == Ty) { |
|
229 | 229 |
return V; |
230 |
- return Builder.CreateLoad(V); |
|
230 |
+ } |
|
231 |
+ V = Builder.CreateLoad(V); |
|
232 |
+ assert(V->getType() == Ty); |
|
233 |
+ return V; |
|
231 | 234 |
} |
232 | 235 |
unsigned w = (Ty->getPrimitiveSizeInBits()+7)/8; |
233 | 236 |
return convertOperand(func, map[w], operand); |
... | ... |
@@ -243,8 +247,11 @@ private: |
243 | 243 |
unsigned w, operand_t operand) { |
244 | 244 |
if (operand < func->numArgs) |
245 | 245 |
return Values[operand]; |
246 |
- if (operand < func->numValues) |
|
246 |
+ if (operand < func->numValues) { |
|
247 |
+ if (func->types[operand]&0x8000) |
|
248 |
+ return Values[operand]; |
|
247 | 249 |
return Builder.CreateLoad(Values[operand]); |
250 |
+ } |
|
248 | 251 |
|
249 | 252 |
if (operand & 0x80000000) { |
250 | 253 |
operand &= 0x7fffffff; |
... | ... |
@@ -309,7 +316,7 @@ private: |
309 | 309 |
|
310 | 310 |
const Type* mapType(uint16_t typeID) |
311 | 311 |
{ |
312 |
- return TypeMap->get(typeID); |
|
312 |
+ return TypeMap->get(typeID&0x7fffffff); |
|
313 | 313 |
} |
314 | 314 |
|
315 | 315 |
Constant *buildConstant(const Type *Ty, uint64_t *components, unsigned &c) |
... | ... |
@@ -364,6 +371,31 @@ public: |
364 | 364 |
} |
365 | 365 |
} |
366 | 366 |
|
367 |
+ template <typename InputIterator> |
|
368 |
+ bool createGEP(unsigned dest, Value *Base, InputIterator Start, InputIterator End) { |
|
369 |
+ assert(dest >= numArgs && dest < numLocals+numArgs && "Instruction destination out of range"); |
|
370 |
+ const Type *Ty = GetElementPtrInst::getIndexedType(Base->getType(), Start, End); |
|
371 |
+ const Type *ETy = cast<PointerType>(cast<PointerType>(Values[dest]->getType())->getElementType())->getElementType(); |
|
372 |
+ if (!Ty || (Ty != ETy && (!isa<IntegerType>(Ty) || !isa<IntegerType>(ETy)))) { |
|
373 |
+ errs() << MODULE << "Wrong indices for GEP opcode: " |
|
374 |
+ << " expected type: " << *ETy; |
|
375 |
+ if (Ty) |
|
376 |
+ errs() << " actual type: " << *Ty; |
|
377 |
+ errs() << " base: " << *Base << " indices: "; |
|
378 |
+ for (InputIterator I=Start; I != End; I++) { |
|
379 |
+ errs() << **I << ", "; |
|
380 |
+ } |
|
381 |
+ errs() << "\n"; |
|
382 |
+ return false; |
|
383 |
+ } |
|
384 |
+ Value *V = Builder.CreateGEP(Base, Start, End); |
|
385 |
+ if (Ty != ETy) { |
|
386 |
+ V = Builder.CreateBitCast(V, PointerType::getUnqual(ETy)); |
|
387 |
+ } |
|
388 |
+ Store(dest, V); |
|
389 |
+ return true; |
|
390 |
+ } |
|
391 |
+ |
|
367 | 392 |
bool generate() { |
368 | 393 |
TypeMap = new LLVMTypeMapper(Context, bc->types + 4, bc->num_types - 5); |
369 | 394 |
|
... | ... |
@@ -383,6 +415,55 @@ public: |
383 | 383 |
FHandler->addFnAttr(Attribute::NoInline); |
384 | 384 |
EE->addGlobalMapping(FHandler, (void*)jit_exception_handler); |
385 | 385 |
|
386 |
+ std::vector<const Type*> args; |
|
387 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
388 |
+ args.push_back(Type::getInt8Ty(Context)); |
|
389 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
390 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
391 |
+ FunctionType* FuncTy_3 = FunctionType::get(Type::getVoidTy(Context), |
|
392 |
+ args, false); |
|
393 |
+ Function *FMemset = Function::Create(FuncTy_3, GlobalValue::ExternalLinkage, |
|
394 |
+ "llvm.memset.i32", M); |
|
395 |
+ FMemset->setDoesNotThrow(); |
|
396 |
+ FMemset->setDoesNotCapture(1, true); |
|
397 |
+ |
|
398 |
+ args.clear(); |
|
399 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
400 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
401 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
402 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
403 |
+ FunctionType* FuncTy_4 = FunctionType::get(Type::getVoidTy(Context), |
|
404 |
+ args, false); |
|
405 |
+ Function *FMemmove = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage, |
|
406 |
+ "llvm.memmove.i32", M); |
|
407 |
+ FMemmove->setDoesNotThrow(); |
|
408 |
+ FMemmove->setDoesNotCapture(1, true); |
|
409 |
+ |
|
410 |
+ Function *FMemcpy = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage, |
|
411 |
+ "llvm.memcpy.i32", M); |
|
412 |
+ FMemcpy->setDoesNotThrow(); |
|
413 |
+ FMemcpy->setDoesNotCapture(1, true); |
|
414 |
+ |
|
415 |
+ FunctionType* DummyTy = FunctionType::get(Type::getVoidTy(Context), false); |
|
416 |
+ Function *FRealMemset = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
417 |
+ "memset", M); |
|
418 |
+ EE->addGlobalMapping(FRealMemset, (void*)memset); |
|
419 |
+ Function *FRealMemmove = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
420 |
+ "memmove", M); |
|
421 |
+ EE->addGlobalMapping(FRealMemmove, (void*)memmove); |
|
422 |
+ Function *FRealMemcpy = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
423 |
+ "memcpy", M); |
|
424 |
+ EE->addGlobalMapping(FRealMemcpy, (void*)memcpy); |
|
425 |
+ |
|
426 |
+ args.clear(); |
|
427 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
428 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
429 |
+ args.push_back(EE->getTargetData()->getIntPtrType(Context)); |
|
430 |
+ FunctionType* FuncTy_5 = FunctionType::get(Type::getInt32Ty(Context), |
|
431 |
+ args, false); |
|
432 |
+ Function* FRealMemcmp = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, "memcmp", M); |
|
433 |
+ EE->addGlobalMapping(FRealMemcmp, (void*)memcmp); |
|
434 |
+ |
|
386 | 435 |
// The hidden ctx param to all functions |
387 | 436 |
const Type *HiddenCtx = PointerType::getUnqual(Type::getInt8Ty(Context)); |
388 | 437 |
|
... | ... |
@@ -399,8 +480,6 @@ public: |
399 | 399 |
if (isa<PointerType>(Ty)) { |
400 | 400 |
unsigned g = bc->globals[i][1]; |
401 | 401 |
if (GVoffsetMap.count(g)) { |
402 |
- const Type *MTy = GVtypeMap[g]; |
|
403 |
- assert(Ty == MTy); |
|
404 | 402 |
FakeGVs.set(i); |
405 | 403 |
globals.push_back(0); |
406 | 404 |
continue; |
... | ... |
@@ -477,16 +556,21 @@ public: |
477 | 477 |
offset); |
478 | 478 |
Value *GEP = Builder.CreateInBoundsGEP(Ctx, Idx); |
479 | 479 |
const Type *Ty = GVtypeMap[g]; |
480 |
- Value *Cast = Builder.CreateBitCast(GEP, |
|
481 |
- PointerType::getUnqual(Ty)); |
|
480 |
+ Ty = PointerType::getUnqual(PointerType::getUnqual(Ty)); |
|
481 |
+ Value *Cast = Builder.CreateBitCast(GEP, Ty); |
|
482 | 482 |
Value *SpecialGV = Builder.CreateLoad(Cast); |
483 |
- Constant *C = ConstantInt::get(Type::getInt32Ty(Context), bc->globals[i][0]); |
|
484 |
- globals[i] = Builder.CreateInBoundsGEP(SpecialGV, C); |
|
483 |
+ Value *C[] = { |
|
484 |
+ ConstantInt::get(Type::getInt32Ty(Context), 0), |
|
485 |
+ ConstantInt::get(Type::getInt32Ty(Context), bc->globals[i][0]) |
|
486 |
+ }; |
|
487 |
+ globals[i] = Builder.CreateInBoundsGEP(SpecialGV, C, |
|
488 |
+ C+2); |
|
485 | 489 |
} |
486 | 490 |
} |
487 | 491 |
|
488 | 492 |
// Generate LLVM IR for each BB |
489 | 493 |
for (unsigned i=0;i<func->numBB;i++) { |
494 |
+ bool unreachable = false; |
|
490 | 495 |
const struct cli_bc_bb *bb = &func->BB[i]; |
491 | 496 |
Builder.SetInsertPoint(BB[i]); |
492 | 497 |
for (unsigned j=0;j<bb->numInsts;j++) { |
... | ... |
@@ -507,6 +591,7 @@ public: |
507 | 507 |
case OP_BC_GEPN: |
508 | 508 |
case OP_BC_STORE: |
509 | 509 |
case OP_BC_COPY: |
510 |
+ case OP_BC_RET: |
|
510 | 511 |
// these instructions represents operands differently |
511 | 512 |
break; |
512 | 513 |
default: |
... | ... |
@@ -624,8 +709,11 @@ public: |
624 | 624 |
break; |
625 | 625 |
} |
626 | 626 |
case OP_BC_RET: |
627 |
+ { |
|
628 |
+ Op0 = convertOperand(func, F->getReturnType(), inst->u.unaryop); |
|
627 | 629 |
Builder.CreateRet(Op0); |
628 | 630 |
break; |
631 |
+ } |
|
629 | 632 |
case OP_BC_RET_VOID: |
630 | 633 |
Builder.CreateRetVoid(); |
631 | 634 |
break; |
... | ... |
@@ -698,44 +786,110 @@ public: |
698 | 698 |
} |
699 | 699 |
case OP_BC_GEP1: |
700 | 700 |
{ |
701 |
- Value *V = Values[inst->u.binop[0]]; |
|
701 |
+ Value *V = convertOperand(func, inst, inst->u.binop[0]); |
|
702 | 702 |
Value *Op = convertOperand(func, I32Ty, inst->u.binop[1]); |
703 |
- Store(inst->dest, Builder.CreateGEP(V, Op)); |
|
703 |
+ if (!createGEP(inst->dest, V, &Op, &Op+1)) |
|
704 |
+ return false; |
|
704 | 705 |
break; |
705 | 706 |
} |
706 | 707 |
case OP_BC_GEP2: |
707 | 708 |
{ |
708 | 709 |
std::vector<Value*> Idxs; |
709 |
- Value *V = Values[inst->u.three[0]]; |
|
710 |
+ Value *V = convertOperand(func, inst, inst->u.three[0]); |
|
710 | 711 |
Idxs.push_back(convertOperand(func, I32Ty, inst->u.three[1])); |
711 | 712 |
Idxs.push_back(convertOperand(func, I32Ty, inst->u.three[2])); |
712 |
- Store(inst->dest, Builder.CreateGEP(V, Idxs.begin(), Idxs.end())); |
|
713 |
+ if (!createGEP(inst->dest, V, Idxs.begin(), Idxs.end())) |
|
714 |
+ return false; |
|
713 | 715 |
break; |
714 | 716 |
} |
715 | 717 |
case OP_BC_GEPN: |
716 | 718 |
{ |
717 | 719 |
std::vector<Value*> Idxs; |
718 | 720 |
assert(inst->u.ops.numOps > 1); |
719 |
- Value *V = Values[inst->u.ops.ops[0]]; |
|
721 |
+ Value *V = convertOperand(func, inst, inst->u.binop[0]); |
|
720 | 722 |
for (unsigned a=1;a<inst->u.ops.numOps;a++) |
721 | 723 |
Idxs.push_back(convertOperand(func, I32Ty, inst->u.ops.ops[a])); |
722 |
- Store(inst->dest, Builder.CreateGEP(V, Idxs.begin(), Idxs.end())); |
|
724 |
+ if (!createGEP(inst->dest, V, Idxs.begin(), Idxs.end())) |
|
725 |
+ return false; |
|
723 | 726 |
break; |
724 | 727 |
} |
725 | 728 |
case OP_BC_STORE: |
726 | 729 |
{ |
727 | 730 |
Value *Dest = convertOperand(func, inst, inst->u.binop[1]); |
728 | 731 |
const Type *ETy = cast<PointerType>(Dest->getType())->getElementType(); |
729 |
- Builder.CreateStore(getOperand(func, ETy, inst->u.binop[0]), |
|
732 |
+ Builder.CreateStore(convertOperand(func, ETy, inst->u.binop[0]), |
|
730 | 733 |
Dest); |
731 | 734 |
break; |
732 | 735 |
} |
733 | 736 |
case OP_BC_LOAD: |
737 |
+ { |
|
738 |
+ Op0 = Builder.CreateBitCast(Op0, |
|
739 |
+ Values[inst->dest]->getType()); |
|
734 | 740 |
Op0 = Builder.CreateLoad(Op0); |
735 | 741 |
Store(inst->dest, Op0); |
736 | 742 |
break; |
743 |
+ } |
|
744 |
+ case OP_BC_MEMSET: |
|
745 |
+ { |
|
746 |
+ Value *Dst = convertOperand(func, inst, inst->u.three[0]); |
|
747 |
+ Value *Val = convertOperand(func, Type::getInt8Ty(Context), inst->u.three[1]); |
|
748 |
+ Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]); |
|
749 |
+ CallInst *c = Builder.CreateCall4(FMemset, Dst, Val, Len, |
|
750 |
+ ConstantInt::get(Type::getInt32Ty(Context), 1)); |
|
751 |
+ c->setTailCall(true); |
|
752 |
+ c->setDoesNotThrow(); |
|
753 |
+ break; |
|
754 |
+ } |
|
755 |
+ case OP_BC_MEMCPY: |
|
756 |
+ { |
|
757 |
+ Value *Dst = convertOperand(func, inst, inst->u.three[0]); |
|
758 |
+ Value *Src = convertOperand(func, inst, inst->u.three[1]); |
|
759 |
+ Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]); |
|
760 |
+ CallInst *c = Builder.CreateCall4(FMemcpy, Dst, Src, Len, |
|
761 |
+ ConstantInt::get(Type::getInt32Ty(Context), 1)); |
|
762 |
+ c->setTailCall(true); |
|
763 |
+ c->setDoesNotThrow(); |
|
764 |
+ break; |
|
765 |
+ } |
|
766 |
+ case OP_BC_MEMMOVE: |
|
767 |
+ { |
|
768 |
+ Value *Dst = convertOperand(func, inst, inst->u.three[0]); |
|
769 |
+ Value *Src = convertOperand(func, inst, inst->u.three[1]); |
|
770 |
+ Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]); |
|
771 |
+ CallInst *c = Builder.CreateCall4(FMemmove, Dst, Src, Len, |
|
772 |
+ ConstantInt::get(Type::getInt32Ty(Context), 1)); |
|
773 |
+ c->setTailCall(true); |
|
774 |
+ c->setDoesNotThrow(); |
|
775 |
+ break; |
|
776 |
+ } |
|
777 |
+ case OP_BC_MEMCMP: |
|
778 |
+ { |
|
779 |
+ Value *Dst = convertOperand(func, inst, inst->u.three[0]); |
|
780 |
+ Value *Src = convertOperand(func, inst, inst->u.three[1]); |
|
781 |
+ Value *Len = convertOperand(func, EE->getTargetData()->getIntPtrType(Context), inst->u.three[2]); |
|
782 |
+ CallInst *c = Builder.CreateCall4(FRealMemcmp, Dst, Src, Len, |
|
783 |
+ ConstantInt::get(Type::getInt32Ty(Context), 1)); |
|
784 |
+ c->setTailCall(true); |
|
785 |
+ c->setDoesNotThrow(); |
|
786 |
+ Store(inst->dest, c); |
|
787 |
+ break; |
|
788 |
+ } |
|
789 |
+ case OP_BC_ISBIGENDIAN: |
|
790 |
+ Store(inst->dest, WORDS_BIGENDIAN ? |
|
791 |
+ ConstantInt::getTrue(Context) : |
|
792 |
+ ConstantInt::getFalse(Context)); |
|
793 |
+ break; |
|
794 |
+ case OP_BC_ABORT: |
|
795 |
+ if (!unreachable) { |
|
796 |
+ CallInst *CI = Builder.CreateCall(FHandler); |
|
797 |
+ CI->setDoesNotReturn(); |
|
798 |
+ CI->setDoesNotThrow(); |
|
799 |
+ Builder.CreateUnreachable(); |
|
800 |
+ unreachable = true; |
|
801 |
+ } |
|
802 |
+ break; |
|
737 | 803 |
default: |
738 |
- errs() << "JIT doesn't implement opcode " << |
|
804 |
+ errs() << MODULE << "JIT doesn't implement opcode " << |
|
739 | 805 |
inst->opcode << " yet!\n"; |
740 | 806 |
return false; |
741 | 807 |
} |
... | ... |
@@ -744,6 +898,7 @@ public: |
744 | 744 |
|
745 | 745 |
if (verifyFunction(*F, PrintMessageAction)) { |
746 | 746 |
errs() << MODULE << "Verification failed\n"; |
747 |
+ F->dump(); |
|
747 | 748 |
// verification failed |
748 | 749 |
return false; |
749 | 750 |
} |
... | ... |
@@ -754,7 +909,7 @@ public: |
754 | 754 |
|
755 | 755 |
DEBUG(M->dump()); |
756 | 756 |
delete TypeMap; |
757 |
- std::vector<const Type*> args; |
|
757 |
+ args.clear(); |
|
758 | 758 |
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
759 | 759 |
FunctionType *Callable = FunctionType::get(Type::getInt32Ty(Context), |
760 | 760 |
args, false); |
... | ... |
@@ -866,6 +1021,10 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs) |
866 | 866 |
OurFPM.add(createPromoteMemoryToRegisterPass()); |
867 | 867 |
// Delete dead instructions |
868 | 868 |
OurFPM.add(createDeadCodeEliminationPass()); |
869 |
+ // Fold constants |
|
870 |
+ OurFPM.add(createConstantPropagationPass()); |
|
871 |
+ // SimplifyCFG |
|
872 |
+ OurFPM.add(createCFGSimplificationPass()); |
|
869 | 873 |
OurFPM.doInitialization(); |
870 | 874 |
|
871 | 875 |
//TODO: create a wrapper that calls pthread_getspecific |