Skip to content

Commit 55c5e9b

Browse files
authored
Merge pull request rust-lang#152 from vext01/dyn-gep
Yk serialiser: Handle dynamic indexing in getelementptr instructions.
2 parents d885f26 + 1359671 commit 55c5e9b

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

llvm/lib/YkIR/YkIRWriter.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -632,21 +632,41 @@ class YkIRWriter {
632632

633633
void serialiseGetElementPtrInst(GetElementPtrInst *I, FuncLowerCtxt &FLCtxt,
634634
unsigned BBIdx, unsigned &InstIdx) {
635-
unsigned BitWidth = 64;
636-
MapVector<Value *, APInt> Offsets;
637-
APInt Offset(BitWidth, 0);
638-
639-
bool Res = I->collectOffset(DL, BitWidth, Offsets, Offset);
640-
assert(Res);
641-
642635
// opcode:
643636
serialiseOpcode(OpCodePtrAdd);
644637
// type_idx:
645638
OutStreamer.emitSizeT(typeIndex(I->getType()));
646639
// pointer:
647640
serialiseOperand(I, FLCtxt, I->getPointerOperand());
648-
// offset:
649-
serialiseOperand(I, FLCtxt, ConstantInt::get(I->getContext(), Offset));
641+
642+
// GetElementPtrInst::collectOffset() reduces the GEP to:
643+
// - a static offset and
644+
// - zero or more dynamic offsets of the form `elem_count * elem_size`,
645+
// where `elem_count` is not known statically.
646+
//
647+
// We lower this information directly into a Yk PtrAdd instruction.
648+
//
649+
// Note: the width of the collected constant offset must be the same as the
650+
// index type bit-width.
651+
unsigned BitWidth = DL.getIndexSizeInBits(I->getPointerAddressSpace());
652+
APInt ConstOff(BitWidth, 0);
653+
MapVector<Value *, APInt> DynOffs;
654+
bool CollectRes = I->collectOffset(DL, BitWidth, DynOffs, ConstOff);
655+
assert(CollectRes);
656+
657+
// const_off:
658+
OutStreamer.emitSizeT(ConstOff.getZExtValue());
659+
// num_dyn_offs:
660+
size_t NumDyn = DynOffs.size();
661+
OutStreamer.emitSizeT(NumDyn);
662+
// dyn_elem_counts:
663+
for (auto &KV : DynOffs) {
664+
serialiseOperand(I, FLCtxt, std::get<0>(KV));
665+
}
666+
// dyn_elem_sizes:
667+
for (auto &KV : DynOffs) {
668+
OutStreamer.emitSizeT(std::get<1>(KV).getZExtValue());
669+
}
650670

651671
FLCtxt.updateVLMap(I, InstIdx);
652672
InstIdx++;

0 commit comments

Comments
 (0)