-
Notifications
You must be signed in to change notification settings - Fork 115
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
[CIR][Codegen] Fixes global variables that point to another globals #1277
base: main
Are you sure you want to change the base?
Conversation
Actually, there is another approach for the problem. Instead of rewriting indices we could store an offset in the global view attribute here. The OG does the same: creates a pointer to mlir::ArrayAttr getOffset(mlir::Type Ty) {
auto Offset = Value.getLValueOffset().getQuantity();
if (Offset == 0)
return {};
llvm::SmallVector<mlir::Attribute, 3> Indices;
auto Attr = CGM.getBuilder().getI32IntegerAttr(Offset);
Indices.push_back(Attr);
return CGM.getBuilder().getArrayAttr(Indices);
}
ConstantLValue applyOffset(ConstantLValue &C) {
// Handle attribute constant LValues.
if (auto Attr = mlir::dyn_cast<mlir::Attribute>(C.Value)) {
if (auto GV = mlir::dyn_cast<cir::GlobalViewAttr>(Attr)) {
assert(!GV.getIndices() && "Global view is already indexed");
auto baseTy = mlir::cast<cir::PointerType>(GV.getType()).getPointee();
auto destTy = CGM.getTypes().convertTypeForMem(DestType);
auto offset = getOffset(baseTy);
if (offset) {
auto typ = CGM.getBuilder().getUInt8Ty();
destTy = CGM.getBuilder().getPointerTo(typ);
}
return GlobalViewAttr::get(destTy, GV.getSymbol(), offset);
}
llvm_unreachable("Unsupported attribute type to offset");
}
// TODO(cir): use ptr_stride, or something...
llvm_unreachable("NYI");
} From the other point of view this approach can be too low level for CIR. But we can go this way if you prefer - in this case |
Seems like recent updates are triggering failures |
updated! |
This sounds appealing, can you paste the CIR/LLVM output for the two different approaches so I can give a more informed take? |
Say we have the next structure type and global vars:
The OG LLVM IR:
With the approach in questionThe LLVM IR with CIR and this approach applied:
There are some differences, but
In this case the lowering will require special handling for this In the current CIR's stateThe LLVM IR (with CIR):
CIR itself:
The point is - in this case it's more clear for the reader what the element is accessed - the array element with index 2 and then a field with index 2. And the lowering may be improved later in order to produce more OG-like IR. |
For the readability sake, I guess that a lot depends on how you read it, in the (a) first version:
We are saying that we are first looking at the "final" type
In this one (b) we'd have to look at the original What I'm really trying to make sure with as part of this discussion is that we avoid a mix of these semantics, the indices should always talk about the source type or always about the resulting type. My take is that we should stay with (b) if you have found a way to make it work with the bug you are fixing, otherwise we could go for (a), but we need to change docs and make sure it's consistent across the board. |
Looks like I meet the case (thanks to Let me spend a couple more hours - may be I'll find a solution to keep the existent approach. |
@gitoleg thanks for going the extra length, I appreciate it.
Indeed, but on the bright side it was necessary in order to pinpoint the investigation, hopefully we'll find a middle ground! |
I continue to use `csmith` and catch run time bags. Now it's time to fix the layout for the const structs. There is a divergence between const structs generated by CIR and the original codegen. And this PR makes one more step to eliminate it. There are cases where the extra padding is required - and here is a fix for some of them. I did not write extra tests, since the fixes in the existing already covers the code I added. The point is that now the layout for all of these structs in the LLVM IR with and without CIR is the same.
7b519bf
to
c7954a8
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
I fixed the issue that makes me sad the last time we talked here and covered several more cases as well - but it less important. Basically the problem was that all this globals replacements was not used (the same in OG). The solution is to create a global view with the mlir type of a global var we want to take a view on but now with its AST type (changes in Now I think the PR is ready for merge - once you have no objection of course. |
Testing CIR with
csmith
is in progress! And this PR is not a small one, so I need to apologize. But looks like there is a problem that may affect the run time.Problem
Consider the next code:
This program dumps anything but not
123
.So basically we don't support global variables that refer to another globals in the case of aggregate types.
This PR fixes global views for two cases: structs and array of structs (see the tests).
There is an issue with unions too, but I think we will discuss it later, once we will agree on the approach
Some details
For the example above,
g1
variable is created in two steps:S
type. In our case it's!cir.struct<struct "S" {!cir.array<!cir.int<u, 8> x 3>, !cir.int<s, 32>, !cir.int<s, 32>}
(which differs from the OG btw, and may be I need to take a look at the bit fields again - but it's not a problem right now)!cir.struct<struct {!cir.int<u, 8>, !cir.int<u, 8>, !cir.int<u, 8>, !cir.int<u, 8>, !cir.int<s, 32>, !cir.int<s, 32>}>
which is the same as in OG and theng1
is replaced with the new type.Basically the same happens in the OG. But then the
replaceAllUsesWith
solves all the possible problems.In our case we can not do it this easy. The
g2
is:The problem is in the indexes! After
g1
is replaced, the index ing2
'sGlobalViewAttr
still points to the old type!!!So we have to create a new
GlobalViewAttr
with new indexes!Solution
My solution is based on the
computeGlobalViewIndicesFromFlatOffset
function fromCIRGenBuilder
that is basically a mapping from indexes to offset. I compute an offset and then map it back to the indexes with for the new type.May be there is a better solution though, have some ideas?
Implementation details
Most of the changes are in the
CIRGenModule
where we do the replacement.Also, there are some changes in
CIRGenBuilder
- I movedcomputeGlobalViewIndicesFromFlatOffset
tocpp
with no changes and added the opposite functioncomputeOffsetFromGlobalViewIndices
.One more fix is more important - is about
GlobalViewAttr
indexes generation for vtable. I suggest we don't set the first index to zero in CIR and add it in the lowering - in this case we can do it uniformly asThe previous approach was not completely correct - we have to add the leading zero index for the anon structures as well:
Thus, there are some changes in tests as well. It's not an unrelated issue - we have to fix it - either now or as a separated PR that should come before this one.
Also, I added tests with the covered cases with the original LLVM IR, just for comparison - so there are some divergences as well.
Finally - this code was already tested with
csmith
and I don't have any problems so far. Once we'll fix unions I will have more information.