Skip to content

Commit f091357

Browse files
authored
Merge pull request rust-lang#113 from ptersilie/more-bytecode
More work on lowering LLVMIR to YKIR.
2 parents 5bd64cb + 59ceaec commit f091357

File tree

1 file changed

+65
-4
lines changed

1 file changed

+65
-4
lines changed

llvm/lib/YkIR/YkIRWriter.cpp

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "llvm/BinaryFormat/ELF.h"
88
#include "llvm/IR/Constant.h"
99
#include "llvm/IR/Constants.h"
10+
#include "llvm/IR/GlobalValue.h"
1011
#include "llvm/IR/InstrTypes.h"
1112
#include "llvm/IR/Instructions.h"
1213
#include "llvm/IR/Module.h"
@@ -39,13 +40,13 @@ enum OpCode {
3940
Store,
4041
Alloca,
4142
Call,
42-
GetElementPtr,
4343
Br,
4444
CondBr,
4545
ICmp,
4646
BinaryOperator,
4747
Ret,
4848
InsertValue,
49+
PtrAdd,
4950
UnimplementedInstruction = 255, // YKFIXME: Will eventually be deleted.
5051
};
5152

@@ -56,6 +57,7 @@ enum OperandKind {
5657
Function,
5758
Block,
5859
Arg,
60+
Global,
5961
UnimplementedOperand = 255,
6062
};
6163

@@ -124,9 +126,11 @@ class YkIRWriter {
124126
private:
125127
Module &M;
126128
MCStreamer &OutStreamer;
129+
DataLayout DL;
127130

128131
vector<llvm::Type *> Types;
129132
vector<llvm::Constant *> Constants;
133+
vector<llvm::GlobalVariable *> Globals;
130134

131135
// Return the index of the LLVM type `Ty`, inserting a new entry if
132136
// necessary.
@@ -163,6 +167,19 @@ class YkIRWriter {
163167
return Idx;
164168
}
165169

170+
// Return the index of the LLVM global `G`, inserting a new entry if
171+
// necessary.
172+
size_t globalIndex(class GlobalVariable *G) {
173+
vector<class GlobalVariable *>::iterator Found =
174+
std::find(Globals.begin(), Globals.end(), G);
175+
if (Found != Globals.end()) {
176+
return std::distance(Globals.begin(), Found);
177+
}
178+
size_t Idx = Globals.size();
179+
Globals.push_back(G);
180+
return Idx;
181+
}
182+
166183
size_t functionIndex(llvm::Function *F) {
167184
// FIXME: For now we assume that function indicies in LLVM IR and our IR
168185
// are the same.
@@ -220,9 +237,16 @@ class YkIRWriter {
220237
OutStreamer.emitSizeT(A->getArgNo());
221238
}
222239

240+
void serialiseGlobalOperand(GlobalVariable *G) {
241+
OutStreamer.emitInt8(OperandKind::Global);
242+
OutStreamer.emitSizeT(globalIndex(G));
243+
}
244+
223245
void serialiseOperand(Instruction *Parent, ValueLoweringMap &VLMap,
224246
Value *V) {
225-
if (llvm::Function *F = dyn_cast<llvm::Function>(V)) {
247+
if (llvm::GlobalVariable *G = dyn_cast<llvm::GlobalVariable>(V)) {
248+
serialiseGlobalOperand(G);
249+
} else if (llvm::Function *F = dyn_cast<llvm::Function>(V)) {
226250
serialiseFunctionOperand(F);
227251
} else if (llvm::Constant *C = dyn_cast<llvm::Constant>(V)) {
228252
serialiseConstantOperand(Parent, C);
@@ -326,6 +350,30 @@ class YkIRWriter {
326350
}
327351
}
328352

353+
void serialiseGetElementPtr(GetElementPtrInst *I, ValueLoweringMap &VLMap,
354+
unsigned BBIdx, unsigned &InstIdx) {
355+
unsigned BitWidth = 64;
356+
MapVector<Value *, APInt> Offsets;
357+
APInt Offset(BitWidth, 0);
358+
359+
bool Res = I->collectOffset(DL, BitWidth, Offsets, Offset);
360+
assert(Res);
361+
362+
// type_index:
363+
OutStreamer.emitSizeT(typeIndex(I->getType()));
364+
// opcode:
365+
serialiseOpcode(OpCode::PtrAdd);
366+
// num_operands:
367+
OutStreamer.emitInt32(2);
368+
// pointer:
369+
serialiseOperand(I, VLMap, I->getPointerOperand());
370+
// offset:
371+
serialiseOperand(I, VLMap, ConstantInt::get(I->getContext(), Offset));
372+
373+
VLMap[I] = {BBIdx, InstIdx};
374+
InstIdx++;
375+
}
376+
329377
void serialiseInst(Instruction *I, ValueLoweringMap &VLMap, unsigned BBIdx,
330378
unsigned &InstIdx) {
331379
// Macros to help dispatch to serialisers.
@@ -344,15 +392,16 @@ class YkIRWriter {
344392

345393
GENERIC_INST_SERIALISE(I, LoadInst, Load)
346394
GENERIC_INST_SERIALISE(I, StoreInst, Store)
347-
GENERIC_INST_SERIALISE(I, GetElementPtrInst, GetElementPtr)
348395
GENERIC_INST_SERIALISE(I, ICmpInst, ICmp)
349396
GENERIC_INST_SERIALISE(I, llvm::BinaryOperator, BinaryOperator)
350397
GENERIC_INST_SERIALISE(I, ReturnInst, Ret)
351398
GENERIC_INST_SERIALISE(I, llvm::InsertValueInst, InsertValue)
399+
GENERIC_INST_SERIALISE(I, StoreInst, Store)
352400

353401
CUSTOM_INST_SERIALISE(I, AllocaInst, serialiseAllocaInst)
354402
CUSTOM_INST_SERIALISE(I, CallInst, serialiseCallInst)
355403
CUSTOM_INST_SERIALISE(I, BranchInst, serialiseBranchInst)
404+
CUSTOM_INST_SERIALISE(I, GetElementPtrInst, serialiseGetElementPtr)
356405

357406
// GENERIC_INST_SERIALISE and CUSTOM_INST_SERIALISE do an early return upon
358407
// a match, so if we get here then the instruction wasn't handled.
@@ -485,9 +534,14 @@ class YkIRWriter {
485534
}
486535
}
487536

537+
void serialiseGlobal(class GlobalVariable *G) {
538+
OutStreamer.emitInt8(G->isThreadLocal());
539+
serialiseString(G->getName());
540+
}
541+
488542
public:
489543
YkIRWriter(Module &M, MCStreamer &OutStreamer)
490-
: M(M), OutStreamer(OutStreamer) {}
544+
: M(M), OutStreamer(OutStreamer), DL(&M) {}
491545

492546
// Entry point for IR serialisation.
493547
//
@@ -516,6 +570,13 @@ class YkIRWriter {
516570
serialiseConstant(C);
517571
}
518572

573+
// num_globals:
574+
OutStreamer.emitSizeT(Globals.size());
575+
// globals:
576+
for (class GlobalVariable *&G : Globals) {
577+
serialiseGlobal(G);
578+
}
579+
519580
// num_types:
520581
OutStreamer.emitSizeT(Types.size());
521582
// types:

0 commit comments

Comments
 (0)