LLVM: lib/ExecutionEngine/ExecutionEngine.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

39#include

40#include

41#include

42using namespace llvm;

43

44#define DEBUG_TYPE "jit"

45

46STATISTIC(NumInitBytes, "Number of bytes of global vars initialized");

47STATISTIC(NumGlobals , "Number of global vars initialized");

48

50 std::unique_ptr M, std::string *ErrorStr,

51 std::shared_ptr MemMgr,

52 std::shared_ptr Resolver,

53 std::unique_ptr TM) = nullptr;

54

55ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr M,

56 std::string *ErrorStr) =nullptr;

57

58void JITEventListener::anchor() {}

59

60void ObjectCache::anchor() {}

61

62void ExecutionEngine::Init(std::unique_ptr M) {

63 CompilingLazily = false;

64 GVCompilationDisabled = false;

65 SymbolSearchingDisabled = false;

66

67

68

69#ifndef NDEBUG

70 VerifyModules = true;

71#else

72 VerifyModules = false;

73#endif

74

75 assert(M && "Module is null?");

76 Modules.push_back(std::move(M));

77}

78

81 Init(std::move(M));

82}

83

86 Init(std::move(M));

87}

88

92

93namespace {

94

95

96class GVMemoryBlock final : public CallbackVH {

99

100public:

101

102

106 void *RawMemory = ::operator new(

108 new(RawMemory) GVMemoryBlock(GV);

109 return static_cast<char*>(RawMemory) + sizeof(GVMemoryBlock);

110 }

111

112 void deleted() override {

113

114

115

116 this->~GVMemoryBlock();

117 ::operator delete(this);

118 }

119};

120}

121

125

127 llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile.");

128}

129

130void

132 llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile.");

133}

134

136 llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive.");

137}

138

141 Module *Found = I->get();

142 if (Found == M) {

143 I->release();

146 return true;

147 }

148 }

149 return false;

150}

151

153 for (const auto &M : Modules) {

154 Function *F = M->getFunction(FnName);

155 if (F && F->isDeclaration())

156 return F;

157 }

158 return nullptr;

159}

160

162 for (const auto &M : Modules) {

163 GlobalVariable *GV = M->getGlobalVariable(Name, AllowInternal);

165 return GV;

166 }

167 return nullptr;

168}

169

173

174

175

176 if (I == GlobalAddressMap.end())

177 OldVal = 0;

178 else {

179 GlobalAddressReverseMap.erase(I->second);

180 OldVal = I->second;

181 GlobalAddressMap.erase(I);

182 }

183

184 return OldVal;

185}

186

188 assert(GV->hasName() && "Global must have name.");

189

190 std::lock_guardsys::Mutex locked(lock);

192

197

199 return std::string(FullName);

200}

201

203 std::lock_guardsys::Mutex locked(lock);

205}

206

208 std::lock_guardsys::Mutex locked(lock);

209

210 assert(!Name.empty() && "Empty GlobalMapping symbol name!");

211

212 LLVM_DEBUG(dbgs() << "JIT: Map \'" << Name << "\' to [" << Addr << "]\n";);

213 uint64_t &CurVal = EEState.getGlobalAddressMap()[Name];

214 assert((!CurVal || !Addr) && "GlobalMapping already established!");

215 CurVal = Addr;

216

217

218 if (!EEState.getGlobalAddressReverseMap().empty()) {

219 std::string &V = EEState.getGlobalAddressReverseMap()[CurVal];

220 assert((!V.empty() || !Name.empty()) &&

221 "GlobalMapping already established!");

222 V = std::string(Name);

223 }

224}

225

227 std::lock_guardsys::Mutex locked(lock);

228

229 EEState.getGlobalAddressMap().clear();

230 EEState.getGlobalAddressReverseMap().clear();

231}

232

234 std::lock_guardsys::Mutex locked(lock);

235

238}

239

241 void *Addr) {

242 std::lock_guardsys::Mutex locked(lock);

244}

245

247 std::lock_guardsys::Mutex locked(lock);

248

250 EEState.getGlobalAddressMap();

251

252

253 if (!Addr)

254 return EEState.RemoveMapping(Name);

255

256 uint64_t &CurVal = Map[Name];

258

259 if (CurVal && !EEState.getGlobalAddressReverseMap().empty())

260 EEState.getGlobalAddressReverseMap().erase(CurVal);

261 CurVal = Addr;

262

263

264 if (!EEState.getGlobalAddressReverseMap().empty()) {

265 std::string &V = EEState.getGlobalAddressReverseMap()[CurVal];

266 assert((!V.empty() || !Name.empty()) &&

267 "GlobalMapping already established!");

268 V = std::string(Name);

269 }

270 return OldVal;

271}

272

274 std::lock_guardsys::Mutex locked(lock);

277 EEState.getGlobalAddressMap().find(S);

278 if (I != EEState.getGlobalAddressMap().end())

281}

282

283

285 std::lock_guardsys::Mutex locked(lock);

288 return nullptr;

289}

290

292 std::lock_guardsys::Mutex locked(lock);

294}

295

297 std::lock_guardsys::Mutex locked(lock);

298

299

300 if (EEState.getGlobalAddressReverseMap().empty()) {

302 I = EEState.getGlobalAddressMap().begin(),

303 E = EEState.getGlobalAddressMap().end(); I != E; ++I) {

306 EEState.getGlobalAddressReverseMap().insert(

307 std::make_pair(Addr, std::string(Name)));

308 }

309 }

310

311 std::map<uint64_t, std::string>::iterator I =

312 EEState.getGlobalAddressReverseMap().find((uint64_t) Addr);

313

314 if (I != EEState.getGlobalAddressReverseMap().end()) {

316 for (const auto &M : Modules)

317 if (GlobalValue *GV = M->getNamedValue(Name))

318 return GV;

319 }

320 return nullptr;

321}

322

323namespace {

324class ArgvArray {

325 std::unique_ptr<char[]> Array;

326 std::vector<std::unique_ptr<char[]>> Values;

327public:

328

329

331 const std::vectorstd::string &InputArgv);

332};

333}

335 const std::vectorstd::string &InputArgv) {

336 Values.clear();

337 Values.reserve(InputArgv.size());

339 Array = std::make_unique<char[]>((InputArgv.size()+1)*PtrSize);

340

343

344 for (unsigned i = 0; i != InputArgv.size(); ++i) {

345 unsigned Size = InputArgv[i].size()+1;

346 auto Dest = std::make_unique<char[]>(Size);

347 LLVM_DEBUG(dbgs() << "JIT: ARGV[" << i << "] = " << (void *)Dest.get()

348 << "\n");

349

350 llvm::copy(InputArgv[i], Dest.get());

351 Dest[Size-1] = 0;

352

353

355 (GenericValue*)(&Array[i*PtrSize]), SBytePtr);

356 Values.push_back(std::move(Dest));

357 }

358

359

361 (GenericValue*)(&Array[InputArgv.size()*PtrSize]),

362 SBytePtr);

363 return Array.get();

364}

365

367 bool isDtors) {

368 StringRef Name(isDtors ? "llvm.global_dtors" : "llvm.global_ctors");

370

371

372

373

374

376

377

378

380 if (!InitList)

381 return;

382 for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {

384 if (!CS) continue;

385

387 if (FP->isNullValue())

388 continue;

389

390

392 if (CE->isCast())

393 FP = CE->getOperand(0);

394

395

398

399

400

401

402 }

403}

404

406

407 for (std::unique_ptr &M : Modules)

409}

410

411#ifndef NDEBUG

412

415 for (unsigned i = 0; i < PtrSize; ++i)

417 return false;

418 return true;

419}

420#endif

421

423 const std::vectorstd::string &argv,

424 const char * const * envp) {

425 std::vector GVArgs;

428

429

433

434

435 if (NumArgs > 3)

436 report_fatal_error("Invalid number of arguments of main() supplied");

437 if (NumArgs >= 3 && FTy->getParamType(2) != PPInt8Ty)

438 report_fatal_error("Invalid type for third argument of main() supplied");

439 if (NumArgs >= 2 && FTy->getParamType(1) != PPInt8Ty)

440 report_fatal_error("Invalid type for second argument of main() supplied");

442 report_fatal_error("Invalid type for first argument of main() supplied");

446

447 ArgvArray CArgv;

448 ArgvArray CEnv;

449 if (NumArgs) {

450 GVArgs.push_back(GVArgc);

451 if (NumArgs > 1) {

452

453 GVArgs.push_back(PTOGV(CArgv.reset(Fn->getContext(), this, argv)));

455 "argv[0] was null after CreateArgv");

456 if (NumArgs > 2) {

457 std::vectorstd::string EnvVars;

458 for (unsigned i = 0; envp[i]; ++i)

459 EnvVars.emplace_back(envp[i]);

460

461 GVArgs.push_back(PTOGV(CEnv.reset(Fn->getContext(), this, EnvVars)));

462 }

463 }

464 }

465

467}

468

470

472 : M(std::move(M)), WhichEngine(EngineKind::Either), ErrorStr(nullptr),

474

475

476#ifndef NDEBUG

477 VerifyModules = true;

478#else

479 VerifyModules = false;

480#endif

481}

482

484

486 std::unique_ptr mcjmm) {

487 auto SharedMM = std::shared_ptr(std::move(mcjmm));

488 MemMgr = SharedMM;

489 Resolver = SharedMM;

490 return *this;

491}

492

495 MemMgr = std::shared_ptr(std::move(MM));

496 return *this;

497}

498

501 Resolver = std::shared_ptr(std::move(SR));

502 return *this;

503}

504

506 std::unique_ptr TheTM(TM);

507

508

509

511 return nullptr;

512

513

514

515

516 if (MemMgr) {

519 else {

520 if (ErrorStr)

521 *ErrorStr = "Cannot create an interpreter with a memory manager.";

522 return nullptr;

523 }

524 }

525

526

527

530 errs() << "WARNING: This target JIT is not designed for the host"

531 << " you are running. If bad things happen, please choose"

532 << " a different -march switch.\n";

533 }

534

538 std::move(Resolver), std::move(TheTM));

539

540 if (EE) {

542 return EE;

543 }

544 }

545

546

547

551 if (ErrorStr)

552 *ErrorStr = "Interpreter has not been linked in.";

553 return nullptr;

554 }

555

557 if (ErrorStr)

558 *ErrorStr = "JIT has not been linked in.";

559 }

560

561 return nullptr;

562}

563

567

568 std::lock_guardsys::Mutex locked(lock);

570 return P;

571

572

576 else

577 llvm_unreachable("Global hasn't had an address allocated yet!");

578

580}

581

582

583

585

588 switch (C->getType()->getTypeID()) {

589 default:

590 break;

595

596

597 Result.IntVal = APInt(C->getType()->getPrimitiveSizeInBits(), 0);

598 break;

600

602 unsigned int elemNum = STy->getNumElements();

603 Result.AggregateVal.resize(elemNum);

604 for (unsigned int i = 0; i < elemNum; ++i) {

605 Type *ElemTy = STy->getElementType(i);

606 if (ElemTy->isIntegerTy())

607 Result.AggregateVal[i].IntVal =

608 APInt(ElemTy->getPrimitiveSizeInBits(), 0);

609 else if (ElemTy->isAggregateType()) {

612 }

613 }

614 }

615 }

616 break;

619 "Scalable vector support not yet implemented in ExecutionEngine");

622 Type *ElemTy = ArrTy->getElementType();

623 unsigned int elemNum = ArrTy->getNumElements();

624 Result.AggregateVal.resize(elemNum);

625 if (ElemTy->isIntegerTy())

626 for (unsigned int i = 0; i < elemNum; ++i)

627 Result.AggregateVal[i].IntVal =

628 APInt(ElemTy->getPrimitiveSizeInBits(), 0);

629 break;

630 }

632

634 Type *ElemTy = VTy->getElementType();

635 unsigned int elemNum = VTy->getNumElements();

636 Result.AggregateVal.resize(elemNum);

637 if (ElemTy->isIntegerTy())

638 for (unsigned int i = 0; i < elemNum; ++i)

639 Result.AggregateVal[i].IntVal =

640 APInt(ElemTy->getPrimitiveSizeInBits(), 0);

641 break;

642 }

643 }

644 return Result;

645 }

646

647

649 Constant *Op0 = CE->getOperand(0);

650 switch (CE->getOpcode()) {

651 case Instruction::GetElementPtr: {

652

654 APInt Offset(DL.getPointerSizeInBits(), 0);

656

657 char* tmp = (char*) Result.PointerVal;

658 Result = PTOGV(tmp + Offset.getSExtValue());

659 return Result;

660 }

661 case Instruction::Trunc: {

665 return GV;

666 }

667 case Instruction::ZExt: {

671 return GV;

672 }

673 case Instruction::SExt: {

677 return GV;

678 }

679 case Instruction::FPTrunc: {

680

683 return GV;

684 }

685 case Instruction::FPExt:{

686

689 return GV;

690 }

691 case Instruction::UIToFP: {

693 if (CE->getType()->isFloatTy())

695 else if (CE->getType()->isDoubleTy())

697 else if (CE->getType()->isX86_FP80Ty()) {

700 false,

703 }

704 return GV;

705 }

706 case Instruction::SIToFP: {

708 if (CE->getType()->isFloatTy())

710 else if (CE->getType()->isDoubleTy())

712 else if (CE->getType()->isX86_FP80Ty()) {

715 true,

718 }

719 return GV;

720 }

721 case Instruction::FPToUI:

722 case Instruction::FPToSI: {

732 bool ignored;

734 CE->getOpcode()==Instruction::FPToSI,

736 GV.IntVal = v;

737 }

738 return GV;

739 }

740 case Instruction::PtrToInt: {

742 uint32_t PtrWidth = DL.getTypeSizeInBits(Op0->getType());

743 assert(PtrWidth <= 64 && "Bad pointer width");

745 uint32_t IntWidth = DL.getTypeSizeInBits(CE->getType());

747 return GV;

748 }

749 case Instruction::IntToPtr: {

751 uint32_t PtrWidth = DL.getTypeSizeInBits(CE->getType());

755 return GV;

756 }

757 case Instruction::BitCast: {

759 Type* DestTy = CE->getType();

768 break;

772 break;

776 break;

779 break;

780 }

781 return GV;

782 }

783 case Instruction::Add:

784 case Instruction::FAdd:

785 case Instruction::Sub:

786 case Instruction::FSub:

787 case Instruction::Mul:

788 case Instruction::FMul:

789 case Instruction::UDiv:

790 case Instruction::SDiv:

791 case Instruction::URem:

792 case Instruction::SRem:

793 case Instruction::And:

794 case Instruction::Or:

795 case Instruction::Xor: {

799 switch (CE->getOperand(0)->getType()->getTypeID()) {

802 switch (CE->getOpcode()) {

804 case Instruction::Add: GV.IntVal = LHS.IntVal + RHS.IntVal; break;

805 case Instruction::Sub: GV.IntVal = LHS.IntVal - RHS.IntVal; break;

806 case Instruction::Mul: GV.IntVal = LHS.IntVal * RHS.IntVal; break;

807 case Instruction::UDiv:GV.IntVal = LHS.IntVal.udiv(RHS.IntVal); break;

808 case Instruction::SDiv:GV.IntVal = LHS.IntVal.sdiv(RHS.IntVal); break;

809 case Instruction::URem:GV.IntVal = LHS.IntVal.urem(RHS.IntVal); break;

810 case Instruction::SRem:GV.IntVal = LHS.IntVal.srem(RHS.IntVal); break;

811 case Instruction::And: GV.IntVal = LHS.IntVal & RHS.IntVal; break;

812 case Instruction::Or: GV.IntVal = LHS.IntVal | RHS.IntVal; break;

813 case Instruction::Xor: GV.IntVal = LHS.IntVal ^ RHS.IntVal; break;

814 }

815 break;

817 switch (CE->getOpcode()) {

819 case Instruction::FAdd:

820 GV.FloatVal = LHS.FloatVal + RHS.FloatVal; break;

821 case Instruction::FSub:

822 GV.FloatVal = LHS.FloatVal - RHS.FloatVal; break;

823 case Instruction::FMul:

824 GV.FloatVal = LHS.FloatVal * RHS.FloatVal; break;

825 case Instruction::FDiv:

826 GV.FloatVal = LHS.FloatVal / RHS.FloatVal; break;

827 case Instruction::FRem:

828 GV.FloatVal = std::fmod(LHS.FloatVal,RHS.FloatVal); break;

829 }

830 break;

832 switch (CE->getOpcode()) {

834 case Instruction::FAdd:

835 GV.DoubleVal = LHS.DoubleVal + RHS.DoubleVal; break;

836 case Instruction::FSub:

837 GV.DoubleVal = LHS.DoubleVal - RHS.DoubleVal; break;

838 case Instruction::FMul:

839 GV.DoubleVal = LHS.DoubleVal * RHS.DoubleVal; break;

840 case Instruction::FDiv:

841 GV.DoubleVal = LHS.DoubleVal / RHS.DoubleVal; break;

842 case Instruction::FRem:

843 GV.DoubleVal = std::fmod(LHS.DoubleVal,RHS.DoubleVal); break;

844 }

845 break;

849 const fltSemantics &Sem = CE->getOperand(0)->getType()->getFltSemantics();

851 switch (CE->getOpcode()) {

853 case Instruction::FAdd:

856 break;

857 case Instruction::FSub:

861 break;

862 case Instruction::FMul:

866 break;

867 case Instruction::FDiv:

871 break;

872 case Instruction::FRem:

873 apfLHS.mod(APFloat(Sem, RHS.IntVal));

875 break;

876 }

877 }

878 break;

879 }

880 return GV;

881 }

882 default:

883 break;

884 }

885

888 OS << "ConstantExpr not handled: " << *CE;

890 }

891

894 "TargetExtType only supports null constant value");

896 }

897

898

900 switch (C->getType()->getTypeID()) {

902 Result.FloatVal = cast(C)->getValueAPF().convertToFloat();

903 break;

905 Result.DoubleVal = cast(C)->getValueAPF().convertToDouble();

906 break;

910 Result.IntVal = cast (C)->getValueAPF().bitcastToAPInt();

911 break;

914 break;

917 C = A->getAliasee();

918 }

920 Result.PointerVal = nullptr;

925 else

927 break;

930 "Scalable vector support not yet implemented in ExecutionEngine");

932 unsigned elemNum;

933 Type* ElemTy;

937

938 if (CDV) {

941 } else if (CV || CAZ) {

943 elemNum = VTy->getNumElements();

944 ElemTy = VTy->getElementType();

945 } else {

947 }

948

949 Result.AggregateVal.resize(elemNum);

950

951 if(ElemTy->isFloatTy()) {

952 if (CAZ) {

955 llvm::fill(Result.AggregateVal, floatZero);

956 break;

957 }

958 if(CV) {

959 for (unsigned i = 0; i < elemNum; ++i)

962 CV->getOperand(i))->getValueAPF().convertToFloat();

963 break;

964 }

965 if(CDV)

966 for (unsigned i = 0; i < elemNum; ++i)

968

969 break;

970 }

971

972 if (ElemTy->isDoubleTy()) {

973 if (CAZ) {

976 llvm::fill(Result.AggregateVal, doubleZero);

977 break;

978 }

979 if(CV) {

980 for (unsigned i = 0; i < elemNum; ++i)

983 CV->getOperand(i))->getValueAPF().convertToDouble();

984 break;

985 }

986 if(CDV)

987 for (unsigned i = 0; i < elemNum; ++i)

989

990 break;

991 }

992

993 if (ElemTy->isIntegerTy()) {

994 if (CAZ) {

996 intZero.IntVal = APInt(ElemTy->getScalarSizeInBits(), 0ull);

997 llvm::fill(Result.AggregateVal, intZero);

998 break;

999 }

1000 if(CV) {

1001 for (unsigned i = 0; i < elemNum; ++i)

1005 else {

1006 Result.AggregateVal[i].IntVal =

1008 }

1009 break;

1010 }

1011 if(CDV)

1012 for (unsigned i = 0; i < elemNum; ++i)

1013 Result.AggregateVal[i].IntVal = APInt(

1016

1017 break;

1018 }

1020 } break;

1021

1022 default:

1025 OS << "ERROR: Constant unimplemented for type: " << *C->getType();

1027 }

1028

1029 return Result;

1030}

1031

1034

1035

1037 Ty = TETy->getLayoutType();

1038

1040

1041 switch (Ty->getTypeID()) {

1042 default:

1043 dbgs() << "Cannot store value of type " << *Ty << "!\n";

1044 break;

1047 break;

1049 *((float*)Ptr) = Val.FloatVal;

1050 break;

1052 *((double*)Ptr) = Val.DoubleVal;

1053 break;

1055 memcpy(static_cast<void *>(Ptr), Val.IntVal.getRawData(), 10);

1056 break;

1058

1059 if (StoreBytes != sizeof(PointerTy))

1060 memset(&(Ptr->PointerVal), 0, StoreBytes);

1061

1063 break;

1066 for (unsigned i = 0; i < Val.AggregateVal.size(); ++i) {

1068 *(((double*)Ptr)+i) = Val.AggregateVal[i].DoubleVal;

1070 *(((float*)Ptr)+i) = Val.AggregateVal[i].FloatVal;

1071 if (cast(Ty)->getElementType()->isIntegerTy()) {

1072 unsigned numOfBytes =(Val.AggregateVal[i].IntVal.getBitWidth()+7)/8;

1074 (uint8_t*)Ptr + numOfBytes*i, numOfBytes);

1075 }

1076 }

1077 break;

1078 }

1079

1081

1082 std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr);

1083}

1084

1085

1086

1091 Ty = TETy->getLayoutType();

1092

1094

1095 switch (Ty->getTypeID()) {

1097

1100 break;

1102 Result.FloatVal = *((float*)Ptr);

1103 break;

1105 Result.DoubleVal = *((double*)Ptr);

1106 break;

1108 Result.PointerVal = *((PointerTy*)Ptr);

1109 break;

1111

1112

1114 memcpy(y, Ptr, 10);

1115 Result.IntVal = APInt(80, y);

1116 break;

1117 }

1120 "Scalable vector support not yet implemented in ExecutionEngine");

1123 Type *ElemT = VT->getElementType();

1124 const unsigned numElems = VT->getNumElements();

1126 Result.AggregateVal.resize(numElems);

1127 for (unsigned i = 0; i < numElems; ++i)

1128 Result.AggregateVal[i].FloatVal = *((float*)Ptr+i);

1129 }

1131 Result.AggregateVal.resize(numElems);

1132 for (unsigned i = 0; i < numElems; ++i)

1133 Result.AggregateVal[i].DoubleVal = *((double*)Ptr+i);

1134 }

1137 const unsigned elemBitWidth = cast(ElemT)->getBitWidth();

1138 intZero.IntVal = APInt(elemBitWidth, 0);

1139 Result.AggregateVal.resize(numElems, intZero);

1140 for (unsigned i = 0; i < numElems; ++i)

1142 (uint8_t*)Ptr+((elemBitWidth+7)/8)*i, (elemBitWidth+7)/8);

1143 }

1144 break;

1145 }

1146 default:

1149 OS << "Cannot load value of type " << *Ty << "!";

1151 }

1152}

1153

1155 LLVM_DEBUG(dbgs() << "JIT: Initializing " << Addr << " ");

1158 return;

1159

1161 unsigned ElementSize =

1163 for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)

1164 InitializeMemory(CP->getOperand(i), (char*)Addr+i*ElementSize);

1165 return;

1166 }

1167

1169 memset(Addr, 0, (size_t)getDataLayout().getTypeAllocSize(Init->getType()));

1170 return;

1171 }

1172

1174 unsigned ElementSize =

1176 for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)

1177 InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize);

1178 return;

1179 }

1180

1184 for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i)

1186 return;

1187 }

1188

1191

1193 memcpy(Addr, Data.data(), Data.size());

1194 return;

1195 }

1196

1197 if (Init->getType()->isFirstClassType()) {

1200 return;

1201 }

1202

1203 LLVM_DEBUG(dbgs() << "Bad Type: " << *Init->getType() << "\n");

1204 llvm_unreachable("Unknown constant type to initialize memory with!");

1205}

1206

1207

1208

1209

1211

1212

1213

1214 std::map<std::pair<std::string, Type*>,

1216

1217 if (Modules.size() != 1) {

1218 for (const auto &M : Modules) {

1219 for (const auto &GV : M->globals()) {

1222 continue;

1223

1224 const GlobalValue *&GVEntry = LinkedGlobalsMap[std::make_pair(

1226

1227

1228

1229 if (!GVEntry) {

1230 GVEntry = &GV;

1231 continue;

1232 }

1233

1234

1236 continue;

1237

1238

1239

1241 GVEntry = &GV;

1242 }

1243 }

1244 }

1245

1246 std::vector<const GlobalValue*> NonCanonicalGlobals;

1247 for (const auto &M : Modules) {

1248 for (const auto &GV : M->globals()) {

1249

1250 if (!LinkedGlobalsMap.empty()) {

1251 if (const GlobalValue *GVEntry = LinkedGlobalsMap[std::make_pair(

1253

1254 if (GVEntry != &GV) {

1255 NonCanonicalGlobals.push_back(&GV);

1256 continue;

1257 }

1258 }

1259 }

1260

1263 } else {

1264

1265

1267 std::string(GV.getName())))

1269 else {

1272 }

1273 }

1274 }

1275

1276

1277

1278 if (!NonCanonicalGlobals.empty()) {

1279 for (const GlobalValue *GV : NonCanonicalGlobals) {

1280 const GlobalValue *CGV = LinkedGlobalsMap[std::make_pair(

1283 assert(Ptr && "Canonical global wasn't codegen'd!");

1285 }

1286 }

1287

1288

1289

1290 for (const auto &GV : M->globals()) {

1292 if (!LinkedGlobalsMap.empty()) {

1293 if (const GlobalValue *GVEntry = LinkedGlobalsMap[std::make_pair(

1295 if (GVEntry != &GV)

1296 continue;

1297 }

1299 }

1300 }

1301 }

1302}

1303

1304

1305

1306

1309

1310 if (!GA) {

1311

1313

1314

1315 if (!GA) return;

1316

1318 }

1319

1320

1323

1326 NumInitBytes += (unsigned)GVSize;

1327 ++NumGlobals;

1328}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static bool isTargetNullPtr(ExecutionEngine *EE, void *Loc)

isTargetNullPtr - Return whether the target pointer stored at Loc is null.

Definition ExecutionEngine.cpp:413

Module.h This file contains the declarations for the Module class.

This file defines the SmallString class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

static unsigned getBitWidth(Type *Ty, const DataLayout &DL)

Returns the bitwidth of the given scalar or pointer type.

static constexpr roundingMode rmTowardZero

static const fltSemantics & x87DoubleExtended()

static constexpr roundingMode rmNearestTiesToEven

opStatus divide(const APFloat &RHS, roundingMode RM)

opStatus subtract(const APFloat &RHS, roundingMode RM)

opStatus add(const APFloat &RHS, roundingMode RM)

opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM)

opStatus multiply(const APFloat &RHS, roundingMode RM)

APInt bitcastToAPInt() const

opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const

opStatus mod(const APFloat &RHS)

static APFloat getZero(const fltSemantics &Sem, bool Negative=false)

Factory for Positive and Negative Zero.

Class for arbitrary precision integers.

LLVM_ABI APInt udiv(const APInt &RHS) const

Unsigned division operation.

LLVM_ABI APInt zext(unsigned width) const

Zero extend to a new width.

uint64_t getZExtValue() const

Get zero extended value.

LLVM_ABI APInt zextOrTrunc(unsigned width) const

Zero extend or truncate to width.

LLVM_ABI APInt trunc(unsigned width) const

Truncate to new width.

static APInt floatToBits(float V)

Converts a float to APInt bits.

LLVM_ABI APInt urem(const APInt &RHS) const

Unsigned remainder operation.

unsigned getBitWidth() const

Return the number of bits in the APInt.

LLVM_ABI APInt sdiv(const APInt &RHS) const

Signed division function for APInt.

double signedRoundToDouble() const

Converts this signed APInt to a double value.

float bitsToFloat() const

Converts APInt bits to a float.

LLVM_ABI APInt srem(const APInt &RHS) const

Function for signed remainder operation.

static APInt doubleToBits(double V)

Converts a double to APInt bits.

LLVM_ABI APInt sext(unsigned width) const

Sign extend to a new width.

double bitsToDouble() const

Converts APInt bits to a double.

const uint64_t * getRawData() const

This function returns a pointer to the internal storage of the APInt.

LLVM_ABI double roundToDouble(bool isSigned) const

Converts this APInt to a double value.

Value handle with callbacks on RAUW and destruction.

All zero aggregate value.

ConstantArray - Constant Array Declarations.

ConstantDataSequential - A vector or array constant whose element type is a simple 1/2/4/8-byte integ...

LLVM_ABI uint64_t getElementAsInteger(uint64_t i) const

If this is a sequential container of integers (of any size), return the specified element in the low ...

LLVM_ABI float getElementAsFloat(uint64_t i) const

If this is an sequential container of floats, return the specified element as a float.

LLVM_ABI uint64_t getNumElements() const

Return the number of elements in the array or vector.

LLVM_ABI double getElementAsDouble(uint64_t i) const

If this is an sequential container of doubles, return the specified element as a double.

LLVM_ABI Type * getElementType() const

Return the element type of the array/vector.

A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double,...

A constant value that is initialized with an expression using other constant values.

Constant Vector Declarations.

This is an important base class in LLVM.

static LLVM_ABI Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

A parsed version of the target data layout string in and methods for querying it.

bool isDefault() const

Test if the DataLayout was constructed from an empty string.

LLVM_ABI const StructLayout * getStructLayout(StructType *Ty) const

Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...

LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const

Returns the offset in bytes between successive objects of the specified type, including alignment pad...

LLVM_ABI Align getPreferredAlign(const GlobalVariable *GV) const

Returns the preferred alignment of the specified global.

LLVM_ABI unsigned getPointerSize(unsigned AS=0) const

The pointer representation size in bytes, rounded up to a whole number of bytes.

TypeSize getTypeStoreSize(Type *Ty) const

Returns the maximum number of bytes that may be overwritten by storing the specified type.

Builder class for ExecutionEngines.

LLVM_ABI EngineBuilder & setMCJITMemoryManager(std::unique_ptr< RTDyldMemoryManager > mcjmm)

setMCJITMemoryManager - Sets the MCJIT memory manager to use.

Definition ExecutionEngine.cpp:485

LLVM_ABI EngineBuilder()

Default constructor for EngineBuilder.

Definition ExecutionEngine.cpp:469

LLVM_ABI EngineBuilder & setSymbolResolver(std::unique_ptr< LegacyJITSymbolResolver > SR)

Definition ExecutionEngine.cpp:500

LLVM_ABI ~EngineBuilder()

LLVM_ABI EngineBuilder & setMemoryManager(std::unique_ptr< MCJITMemoryManager > MM)

Definition ExecutionEngine.cpp:494

ExecutionEngine * create()

LLVM_ABI uint64_t RemoveMapping(StringRef Name)

Erase an entry from the mapping table.

Definition ExecutionEngine.cpp:170

StringMap< uint64_t > GlobalAddressMapTy

Abstract interface for implementation execution of LLVM modules, designed to support both interpreter...

void setVerifyModules(bool Verify)

Enable/Disable IR module verification.

void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, Type *Ty)

StoreValueToMemory - Stores the data in Val of type Ty at address Ptr.

Definition ExecutionEngine.cpp:1032

GenericValue getConstantValue(const Constant *C)

Converts a Constant* into a GenericValue, including handling of ConstantExpr values.

Definition ExecutionEngine.cpp:584

const DataLayout & getDataLayout() const

void * getPointerToGlobalIfAvailable(StringRef S)

getPointerToGlobalIfAvailable - This returns the address of the specified global value if it is has a...

Definition ExecutionEngine.cpp:284

void clearAllGlobalMappings()

clearAllGlobalMappings - Clear all global mappings and start over again, for use in dynamic compilati...

Definition ExecutionEngine.cpp:226

virtual void addArchive(object::OwningBinary< object::Archive > A)

addArchive - Add an Archive to the execution engine.

Definition ExecutionEngine.cpp:135

void InitializeMemory(const Constant *Init, void *Addr)

Definition ExecutionEngine.cpp:1154

virtual void * getPointerToFunctionOrStub(Function *F)

getPointerToFunctionOrStub - If the specified function has been code-gen'd, return a pointer to the f...

std::string getMangledName(const GlobalValue *GV)

getMangledName - Get mangled name.

Definition ExecutionEngine.cpp:187

virtual bool removeModule(Module *M)

removeModule - Removes a Module from the list of modules, but does not free the module's memory.

Definition ExecutionEngine.cpp:139

virtual void * getPointerToFunction(Function *F)=0

getPointerToFunction - The different EE's represent function bodies in different ways.

sys::Mutex lock

lock - This lock protects the ExecutionEngine and MCJIT classes.

static ExecutionEngine *(* InterpCtor)(std::unique_ptr< Module > M, std::string *ErrorStr)

virtual void runStaticConstructorsDestructors(bool isDtors)

runStaticConstructorsDestructors - This method is used to execute all of the static constructors or d...

Definition ExecutionEngine.cpp:405

static ExecutionEngine *(* MCJITCtor)(std::unique_ptr< Module > M, std::string *ErrorStr, std::shared_ptr< MCJITMemoryManager > MM, std::shared_ptr< LegacyJITSymbolResolver > SR, std::unique_ptr< TargetMachine > TM)

FunctionCreator LazyFunctionCreator

LazyFunctionCreator - If an unknown function is needed, this function pointer is invoked to create it...

void addGlobalMapping(const GlobalValue *GV, void *Addr)

addGlobalMapping - Tell the execution engine that the specified global is at the specified location.

Definition ExecutionEngine.cpp:202

SmallVector< std::unique_ptr< Module >, 1 > Modules

The list of Modules that we are JIT'ing from.

const GlobalValue * getGlobalValueAtAddress(void *Addr)

getGlobalValueAtAddress - Return the LLVM global value object that starts at the specified address.

Definition ExecutionEngine.cpp:296

ExecutionEngine(DataLayout DL)

void clearGlobalMappingsFromModule(Module *M)

clearGlobalMappingsFromModule - Clear all global mappings that came from a particular module,...

Definition ExecutionEngine.cpp:233

void * getPointerToGlobal(const GlobalValue *GV)

getPointerToGlobal - This returns the address of the specified global value.

Definition ExecutionEngine.cpp:564

int runFunctionAsMain(Function *Fn, const std::vector< std::string > &argv, const char *const *envp)

runFunctionAsMain - This is a helper function which wraps runFunction to handle the common task of st...

Definition ExecutionEngine.cpp:422

virtual void addObjectFile(std::unique_ptr< object::ObjectFile > O)

addObjectFile - Add an ObjectFile to the execution engine.

Definition ExecutionEngine.cpp:126

virtual void * getOrEmitGlobalVariable(const GlobalVariable *GV)

getOrEmitGlobalVariable - Return the address of the specified global variable, possibly emitting it t...

uint64_t getAddressToGlobalIfAvailable(StringRef S)

getAddressToGlobalIfAvailable - This returns the address of the specified global symbol.

Definition ExecutionEngine.cpp:273

void emitGlobalVariable(const GlobalVariable *GV)

Definition ExecutionEngine.cpp:1307

virtual GlobalVariable * FindGlobalVariableNamed(StringRef Name, bool AllowInternal=false)

FindGlobalVariableNamed - Search all of the active modules to find the global variable that defines N...

Definition ExecutionEngine.cpp:161

virtual GenericValue runFunction(Function *F, ArrayRef< GenericValue > ArgValues)=0

runFunction - Execute the specified function with the specified arguments, and return the result.

void emitGlobals()

EmitGlobals - Emit all of the global variables to memory, storing their addresses into GlobalAddress.

Definition ExecutionEngine.cpp:1210

void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, Type *Ty)

FIXME: document.

Definition ExecutionEngine.cpp:1087

uint64_t updateGlobalMapping(const GlobalValue *GV, void *Addr)

updateGlobalMapping - Replace an existing mapping for GV with a new address.

Definition ExecutionEngine.cpp:240

virtual char * getMemoryForGV(const GlobalVariable *GV)

getMemoryforGV - Allocate memory for a global variable.

Definition ExecutionEngine.cpp:122

virtual ~ExecutionEngine()

Definition ExecutionEngine.cpp:89

virtual Function * FindFunctionNamed(StringRef FnName)

FindFunctionNamed - Search all of the active modules to find the function that defines FnName.

Definition ExecutionEngine.cpp:152

Class to represent function types.

unsigned getNumParams() const

Return the number of fixed parameters this function type requires.

Type * getParamType(unsigned i) const

Parameter type accessors.

Type * getReturnType() const

FunctionType * getFunctionType() const

Returns the FunctionType for me.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

bool hasExternalLinkage() const

bool isThreadLocal() const

If the value is "Thread Local", its value isn't shared by the threads.

LLVM_ABI bool isDeclaration() const

Return true if the primary definition of this global value is outside of the current translation unit...

bool hasLocalLinkage() const

bool hasExternalWeakLinkage() const

PointerType * getType() const

Global values are always pointers.

LLVM_ABI const DataLayout & getDataLayout() const

Get the data layout of the module this global belongs to.

bool hasAppendingLinkage() const

Type * getValueType() const

const Constant * getInitializer() const

getInitializer - Return the initializer for this global variable.

This is an important class for using LLVM in a threaded context.

LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const

Print the appropriate prefix and the specified global variable's name.

A Module instance is used to store all the information related to an LLVM module.

MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...

static PointerType * getUnqual(Type *ElementType)

This constructs a pointer to an object of the specified type in the default address space (address sp...

static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)

This constructs a pointer to an object of the specified type in a numbered address space.

Interface for looking up the initializer for a variable name, used by Init::resolveReferences.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

StringMapIterBase< uint64_t, false > iterator

StringRef - Represent a constant reference to a string, i.e.

Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...

TypeSize getElementOffset(unsigned Idx) const

Class to represent struct types.

@ HasZeroInit

zeroinitializer is valid for this target extension type.

Primary interface to the complete machine description for the target machine.

const Target & getTarget() const

bool hasJIT() const

hasJIT - Check if this targets supports the just-in-time compilation.

The instances of the Type class are immutable: once they are created, they are never changed.

bool isX86_FP80Ty() const

Return true if this is x86 long double.

bool isPointerTy() const

True if this is an instance of PointerType.

bool isFloatTy() const

Return true if this is 'float', a 32-bit IEEE fp type.

@ ScalableVectorTyID

Scalable SIMD vector type.

@ FloatTyID

32-bit floating point type

@ IntegerTyID

Arbitrary bit width integers.

@ FixedVectorTyID

Fixed width SIMD vector type.

@ DoubleTyID

64-bit floating point type

@ X86_FP80TyID

80-bit floating point type (X87)

@ PPC_FP128TyID

128-bit floating point type (two 64-bits, PowerPC)

@ FP128TyID

128-bit floating point type (112-bit significand)

LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

bool isDoubleTy() const

Return true if this is 'double', a 64-bit IEEE fp type.

bool isFloatingPointTy() const

Return true if this is one of the floating-point types.

bool isIntegerTy() const

True if this is an instance of IntegerType.

TypeID getTypeID() const

Return the type id for the type.

bool isVoidTy() const

Return true if this is 'void'.

static LLVM_ABI UndefValue * get(Type *T)

Static factory methods - Return an 'undef' object of the specified type.

Value * getOperand(unsigned i) const

unsigned getNumOperands() const

Type * getType() const

All values are typed, get the type of this value.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

A raw_ostream that writes to an SmallVector or SmallString.

StringRef str() const

Return a StringRef for the vector contents.

static bool LoadLibraryPermanently(const char *Filename, std::string *ErrMsg=nullptr)

This function permanently loads the dynamic library at the given path.

static LLVM_ABI void * SearchForAddressOfSymbol(const char *symbolName)

This function will search through all previously loaded dynamic libraries for the symbol symbolName.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

APInt RoundFloatToAPInt(float Float, unsigned width)

Converts a float value into a APInt.

LLVM_ABI APInt RoundDoubleToAPInt(double Double, unsigned width)

Converts the given double value into a APInt.

@ C

The default llvm calling convention, compatible with C.

constexpr bool IsLittleEndianHost

This is an optimization pass for GlobalISel generic memory operations.

void fill(R &&Range, T &&Value)

Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes)

StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst with the integer held in In...

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

GenericValue PTOGV(void *P)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

CodeGenOptLevel

Code generation optimization level.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

OutputIt copy(R &&Range, OutputIt Out)

constexpr unsigned BitWidth

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

void * GVTOP(const GenericValue &GV)

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

@ Default

The result values are uniform if and only if all operands are uniform.

LLVM_ABI void LoadIntFromMemory(APInt &IntVal, const uint8_t *Src, unsigned LoadBytes)

LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting from Src into IntVal,...

Implement std::hash so that hash_code can be used in STL containers.

std::vector< GenericValue > AggregateVal