Skip to content

Commit

Permalink
Revert "[ARM] Follow AACPS standard for volatile bit-fields access wi…
Browse files Browse the repository at this point in the history
…dth"

This reverts commit 6a24339.
Submitted using ide button by mistake
  • Loading branch information
Diogo Sampaio committed Jan 21, 2020
1 parent 6a24339 commit 2147703
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 350 deletions.
118 changes: 5 additions & 113 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,6 @@ llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
Loc);
}

// Helper method to check if the underlying ABI is AAPCS
static bool isAAPCS(const TargetInfo &TargetInfo) {
return TargetInfo.getABI().startswith("aapcs");
}

/// EmitIgnoredExpr - Emit code to compute the specified expression,
/// ignoring the result.
void CodeGenFunction::EmitIgnoredExpr(const Expr *E) {
Expand Down Expand Up @@ -4057,120 +4052,15 @@ static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
return false;
}

// AAPCS requires volatile bitfield accesses to be performed using the
// natural alignment / width of the bitfield declarative type, if that
// won't cause overlap over a non-bitfield member nor access outside the
// the data structure.
bool CodeGenFunction::AdjustAAPCSBitfieldLValue(Address &Base,
CGBitFieldInfo &Info,
const FieldDecl *Field,
const QualType FieldType,
const CGRecordLayout &RL) {
llvm::Type *ResLTy = ConvertTypeForMem(FieldType);
// CGRecordLowering::setBitFieldInfo() pre-adjusts the bitfield offsets for
// big-endian targets, but it assumes a container of width Info.StorageSize.
// Since AAPCS uses a different container size (width of the type), we first
// undo that calculation here and redo it once the bitfield offset within the
// new container is calculated
const bool BE = CGM.getTypes().getDataLayout().isBigEndian();
const unsigned OldOffset =
BE ? Info.StorageSize - (Info.Offset + Info.Size) : Info.Offset;
// Offset to the bitfield from the beginning of the struct
const unsigned AbsoluteOffset =
getContext().toBits(Info.StorageOffset) + OldOffset;

// Container size is the width of the bitfield type
const unsigned ContainerSize = ResLTy->getPrimitiveSizeInBits();
// Nothing to do if the access uses the desired
// container width and is naturally aligned
if (Info.StorageSize == ContainerSize && (OldOffset % ContainerSize == 0))
return false;

// Offset within the container
unsigned MemberOffset = AbsoluteOffset & (ContainerSize - 1);

// Bail out if an aligned load of the container cannot cover the entire
// bitfield. This can happen for example, if the bitfield is part of a packed
// struct. AAPCS does not define access rules for such cases, we let clang to
// follow its own rules.
if (MemberOffset + Info.Size > ContainerSize) {
return false;
}
// Re-adjust offsets for big-endian targets
if (BE)
MemberOffset = ContainerSize - (MemberOffset + Info.Size);

const CharUnits NewOffset =
getContext().toCharUnitsFromBits(AbsoluteOffset & ~(ContainerSize - 1));
const CharUnits End = NewOffset +
getContext().toCharUnitsFromBits(ContainerSize) -
CharUnits::One();

const ASTRecordLayout &Layout =
getContext().getASTRecordLayout(Field->getParent());
// If we access outside memory outside the record, than bail out
const CharUnits RecordSize = Layout.getSize();
if (End >= RecordSize) {
return false;
}

// Bail out if performing this load would access non-bitfields members

for (auto it : Field->getParent()->fields()) {
const FieldDecl &F = *it;
// We distinct allow bitfields overlaps
if (F.isBitField())
continue;
const CharUnits FOffset = getContext().toCharUnitsFromBits(
Layout.getFieldOffset(F.getFieldIndex()));
const CharUnits FEnd =
FOffset +
getContext().toCharUnitsFromBits(
ConvertTypeForMem(F.getType())->getPrimitiveSizeInBits()) -
CharUnits::One();
if (End < FOffset) {
// The other field starts after the desired load end.
break;
}
if (FEnd < NewOffset) {
// The other field ends before the desired load offset.
continue;
}
// The desired load overlaps a non-bitfiel member, bail out.
return false;
}

// Write the new bitfield access parameters
Info.StorageOffset = NewOffset;
Info.StorageSize = ContainerSize;
Info.Offset = MemberOffset;
// GEP into the bitfield container. Here we essentially treat the Base as a
// pointer to a block of containers and index into it appropriately
Base =
Builder.CreateConstInBoundsGEP(Builder.CreateElementBitCast(Base, ResLTy),
AbsoluteOffset / ContainerSize);
return true;
}

LValue CodeGenFunction::EmitLValueForField(LValue base,
const FieldDecl *field) {
LValueBaseInfo BaseInfo = base.getBaseInfo();

if (field->isBitField()) {
const CGRecordLayout &RL =
CGM.getTypes().getCGRecordLayout(field->getParent());
CGBitFieldInfo Info = RL.getBitFieldInfo(field);
CGM.getTypes().getCGRecordLayout(field->getParent());
const CGBitFieldInfo &Info = RL.getBitFieldInfo(field);
Address Addr = base.getAddress(*this);
const QualType FieldType =
field->getType().withCVRQualifiers(base.getVRQualifiers());

if (isAAPCS(CGM.getTarget()) && FieldType.isVolatileQualified()) {
if (AdjustAAPCSBitfieldLValue(Addr, Info, field, FieldType, RL)) {
return LValue::MakeBitfield(Addr, Info, FieldType, BaseInfo,
TBAAAccessInfo());
}
}

unsigned Idx = RL.getLLVMFieldNo(field);
const RecordDecl *rec = field->getParent();
if (!IsInPreservedAIRegion &&
Expand All @@ -4192,9 +4082,11 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
if (Addr.getElementType() != FieldIntTy)
Addr = Builder.CreateElementBitCast(Addr, FieldIntTy);

QualType fieldType =
field->getType().withCVRQualifiers(base.getVRQualifiers());
// TODO: Support TBAA for bit fields.
LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource());
return LValue::MakeBitfield(Addr, Info, FieldType, FieldBaseInfo,
return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo,
TBAAAccessInfo());
}

Expand Down
22 changes: 9 additions & 13 deletions clang/lib/CodeGen/CGValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
#ifndef LLVM_CLANG_LIB_CODEGEN_CGVALUE_H
#define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H

#include "Address.h"
#include "CGRecordLayout.h"
#include "CodeGenTBAA.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Type.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Type.h"
#include "Address.h"
#include "CodeGenTBAA.h"

namespace llvm {
class Constant;
Expand Down Expand Up @@ -182,10 +181,10 @@ class LValue {

// ExtVector element subset: V.xyx
llvm::Constant *VectorElts;
};

// BitField start bit and size
CGBitFieldInfo BitFieldInfo;
// BitField start bit and size
const CGBitFieldInfo *BitFieldInfo;
};

QualType Type;

Expand Down Expand Up @@ -358,13 +357,10 @@ class LValue {
Address getBitFieldAddress() const {
return Address(getBitFieldPointer(), getAlignment());
}
llvm::Value *getBitFieldPointer() const {
assert(isBitField());
return V;
}
llvm::Value *getBitFieldPointer() const { assert(isBitField()); return V; }
const CGBitFieldInfo &getBitFieldInfo() const {
assert(isBitField());
return BitFieldInfo;
return *BitFieldInfo;
}

// global register lvalue
Expand Down Expand Up @@ -419,7 +415,7 @@ class LValue {
LValue R;
R.LVType = BitField;
R.V = Addr.getPointer();
R.BitFieldInfo = Info;
R.BitFieldInfo = &Info;
R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo,
TBAAInfo);
return R;
Expand Down
8 changes: 1 addition & 7 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1619,14 +1619,8 @@ class CodeGenFunction : public CodeGenTypeCache {
void EmitOpenCLKernelMetadata(const FunctionDecl *FD,
llvm::Function *Fn);

/// Perform AAPCS specific tweaks on volatile bitfield accesses.
bool AdjustAAPCSBitfieldLValue(Address &Base, CGBitFieldInfo &Info,
const FieldDecl *Field,
const QualType FieldType,
const CGRecordLayout &RL);

public:
CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext = false);
CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false);
~CodeGenFunction();

CodeGenTypes &getTypes() const { return CGM.getTypes(); }
Expand Down
Loading

0 comments on commit 2147703

Please sign in to comment.