aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver
AgeCommit message (Collapse)Author
2013-04-24[driver] Put -fvectorize under the -Ofast umbrella flag.Chad Rosier
Part of rdar://13622687 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180206 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-24[driver] Improve the implementation of the -Ofast option.Chad Rosier
Specifically, allow the flags that fall under this umbrella (i.e., -O3, -ffast-math, and -fstrict-aliasing) to be overridden/disabled with the individual -O[0|1|2|s|z]/-fno- flags. This also fixes the handling of various floating point optimization flags that are modified by -ffast-math (and thus -Ofast as well). Part of rdar://13622687 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180204 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-24[driver] Add a hasFlag API that accepts a positive alias.Chad Rosier
Part of rdar://13622687 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180203 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-21[Mips] Convert a GNU style Mips ABI name to the name accepted by LLVMSimon Atanasyan
Mips backend. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179981 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-21[Mips] Do not add unnecessary Mips toolchain path to the listSimon Atanasyan
of system include directories with extern "C" semantics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179979 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-20Supports Sourcery CodeBench Mips toolchain directories tree.Simon Atanasyan
Sourcery CodeBench and modern FSF Mips toolchains require a bit more complicated algorithm to calculate headers, libraries and sysroot paths than implemented by Clang driver now. The main problem is that all these paths depend on a set of command line arguments additionally to a target triple value. For example, let $TC is a toolchain installation directory. If we compile big-endian 32-bit mips code, crtbegin.o is in the $TC/lib/gcc/mips-linux-gnu/4.7.2 folder and the toolchain's linker requires --sysroot=$TC/mips-linux-gnu/libc argument. If we compile little-endian 32-bit soft-float mips code, crtbegin.o is in the $TC/lib/gcc/mips-linux-gnu/4.7.2/soft-float/el folder and the toolchain's linker requires --sysroot=$TC/mips-linux-gnu/libc/soft-float/el argument. 1. Calculate MultiarchSuffix using all necessary command line options and use this MultiarchSuffix to detect crtbegin.o location in the GCCInstallationDetector::ScanLibDirForGCCTriple() routine. 2. If a user does not provide --sysroot argument to the driver explicitly, calculate new sysroot value based on command line options. Then use this calculated sysroot path: a. To populate a file search paths list in the Linux::Linux() constructor. b. To find Mips toolchain specific include headers directories in the Linux::AddClangSystemIncludeArgs() routine. c. To provide -–sysroot argument for a linker. Note: - The FSF's tree slightly differs (folder names) and is not supported yet. - New addExternCSystemIncludeIfExits() routine is a temporary solution. I plan to move path existence check to the addExternCSystemInclude() routine by a separate commit. The patch reviewed by Rafael Espindola. http://llvm-reviews.chandlerc.com/D644 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179934 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-17Add support for gcc's spelling of -fcolor-diagnostics.Nico Weber
See http://gcc.gnu.org/onlinedocs/gcc/Language-Independent-Options.html git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179728 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-16[Modules] Convert module specific -fno-modules-autolink into -fno-autolink.Daniel Dunbar
- There is no reason to have a modules specific flag for disabling autolinking. Instead, convert the existing flag into -fno-autolink (which should cover other autolinking code generation paths like #pragmas if and when we support them). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179612 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-15Add a new flag -vectorize-slp-aggressive to enable Hals BB vectorizer.Nadav Rotem
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179507 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-15Rename the slp-vectorizer clang/llvm flags. No functionality change.Nadav Rotem
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179506 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-14[Mips] Support -mmicromips / -mno-micromips command line options.Simon Atanasyan
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179489 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-14[Mips] Fix indentation.Simon Atanasyan
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179488 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-14[Mips] Follow-up to r179481. Reduce code duplication. UseSimon Atanasyan
AddTargetFeature() routine to handle -msingle-float / -mdouble-float options. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179487 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-14Add driver support for fedora 18 on ARM.Rafael Espindola
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179484 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-14[Mips] Remove "single" from the list of valid MIPS float ABI names. AddSimon Atanasyan
two new options –msingle-float and –mdouble-float. These options can be used simultaneously with float ABI selection options (-mfloat-abi, -mhard-float, -msoft-float). They mark whether a floating-point coprocessor supports double-precision operations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179481 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-13Remove duplicated comment.Simon Atanasyan
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179454 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-11Fix the driver logic for recent versions of DragonFly.John McCall
Patch by John Marino. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179334 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-11Add a new -mimplicit-float option for symmetry with -mno-implicit-float.Bob Wilson
This new option is the default, but it is useful to have a flag to override -mno-implicit-float by putting -mimplicit-float later on the command line. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179309 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-11Hexagon: Remove -g option from the assembler command line.Jyotsna Verma
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179299 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-10For split dwarf we should also run the objcopy action if we'reEric Christopher
just assembling a file and have passed the option. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179218 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-10Add an option to parse all comments as documentation commentsDmitri Gribenko
Patch by Amin Shali. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179180 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-09One more follow-up to r179082 - parse PIC/PIE arguments even on platfroms ↵Alexey Samsonov
that force default PIC (like Darwin x86-64), otherwise specifying -fPIC will produce bogus unused argument warning git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179092 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-09Follow-up for r179082: more careful handling of ↵Alexey Samsonov
-f(no-)sanitize-address-zero-base-shadow on Android git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179089 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-09If the user requested a zero-base-shadow sanitizer, infer -pie and -fPIC ↵Peter Collingbourne
when appropriate. Differential Revision: http://llvm-reviews.chandlerc.com/D502 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179082 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-05[analyzer] Re-enable cplusplus.NewDelete (but not NewDeleteLeaks).Jordan Rose
As mentioned in the previous commit message, the use-after-free and double-free warnings for 'delete' are worth enabling even while the leak warnings still have false positives. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178891 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-04Initial support for struct-path aware TBAA.Manman Ren
Added TBAABaseType and TBAAOffset in LValue. These two fields are initialized to the actual type and 0, and are updated in EmitLValueForField. Path-aware TBAA tags are enabled for EmitLoadOfScalar and EmitStoreOfScalar. Added command line option -struct-path-tbaa. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178797 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-04revert r178784 since it does not have a commit messageManman Ren
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178796 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-04Index: include/clang/Driver/CC1Options.tdManman Ren
=================================================================== --- include/clang/Driver/CC1Options.td (revision 178718) +++ include/clang/Driver/CC1Options.td (working copy) @@ -161,6 +161,8 @@ HelpText<"Use register sized accesses to bit-fields, when possible.">; def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">; +def struct_path_tbaa : Flag<["-"], "struct-path-tbaa">, + HelpText<"Turn on struct-path aware Type Based Alias Analysis">; def masm_verbose : Flag<["-"], "masm-verbose">, HelpText<"Generate verbose assembly output">; def mcode_model : Separate<["-"], "mcode-model">, Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td (revision 178718) +++ include/clang/Driver/Options.td (working copy) @@ -587,6 +587,7 @@ Flags<[CC1Option]>, HelpText<"Disable spell-checking">; def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>; def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>; +def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>; def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>; def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>; def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>, Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def (revision 178718) +++ include/clang/Frontend/CodeGenOptions.def (working copy) @@ -85,6 +85,7 @@ VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified. CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. +CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero ///< offset in AddressSanitizer. Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp (revision 178718) +++ lib/CodeGen/CGExpr.cpp (working copy) @@ -1044,7 +1044,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) { return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(), lvalue.getAlignment().getQuantity(), - lvalue.getType(), lvalue.getTBAAInfo()); + lvalue.getType(), lvalue.getTBAAInfo(), + lvalue.getTBAABaseType(), lvalue.getTBAAOffset()); } static bool hasBooleanRepresentation(QualType Ty) { @@ -1106,7 +1107,9 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, - llvm::MDNode *TBAAInfo) { + llvm::MDNode *TBAAInfo, + QualType TBAABaseType, + uint64_t TBAAOffset) { // For better performance, handle vector loads differently. if (Ty->isVectorType()) { llvm::Value *V; @@ -1158,8 +1161,11 @@ Load->setVolatile(true); if (Alignment) Load->setAlignment(Alignment); - if (TBAAInfo) - CGM.DecorateInstruction(Load, TBAAInfo); + if (TBAAInfo) { + llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, + TBAAOffset); + CGM.DecorateInstruction(Load, TBAAPath); + } if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) || (SanOpts->Enum && Ty->getAs<EnumType>())) { @@ -1217,7 +1223,8 @@ bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo, - bool isInit) { + bool isInit, QualType TBAABaseType, + uint64_t TBAAOffset) { // Handle vectors differently to get better performance. if (Ty->isVectorType()) { @@ -1268,15 +1275,19 @@ llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile); if (Alignment) Store->setAlignment(Alignment); - if (TBAAInfo) - CGM.DecorateInstruction(Store, TBAAInfo); + if (TBAAInfo) { + llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, + TBAAOffset); + CGM.DecorateInstruction(Store, TBAAPath); + } } void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit) { EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(), lvalue.getAlignment().getQuantity(), lvalue.getType(), - lvalue.getTBAAInfo(), isInit); + lvalue.getTBAAInfo(), isInit, lvalue.getTBAABaseType(), + lvalue.getTBAAOffset()); } /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this @@ -2494,9 +2505,12 @@ llvm::Value *addr = base.getAddress(); unsigned cvr = base.getVRQualifiers(); + bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; if (rec->isUnion()) { // For unions, there is no pointer adjustment. assert(!type->isReferenceType() && "union has reference member"); + // TODO: handle path-aware TBAA for union. + TBAAPath = false; } else { // For structs, we GEP to the field that the record layout suggests. unsigned idx = CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field); @@ -2508,6 +2522,8 @@ if (cvr & Qualifiers::Volatile) load->setVolatile(true); load->setAlignment(alignment.getQuantity()); + // Loading the reference will disable path-aware TBAA. + TBAAPath = false; if (CGM.shouldUseTBAA()) { llvm::MDNode *tbaa; if (mayAlias) @@ -2541,6 +2557,16 @@ LValue LV = MakeAddrLValue(addr, type, alignment); LV.getQuals().addCVRQualifiers(cvr); + if (TBAAPath) { + const ASTRecordLayout &Layout = + getContext().getASTRecordLayout(field->getParent()); + // Set the base type to be the base type of the base LValue and + // update offset to be relative to the base type. + LV.setTBAABaseType(base.getTBAABaseType()); + LV.setTBAAOffset(base.getTBAAOffset() + + Layout.getFieldOffset(field->getFieldIndex()) / + getContext().getCharWidth()); + } // __weak attribute on a field is ignored. if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak) Index: lib/CodeGen/CGValue.h =================================================================== --- lib/CodeGen/CGValue.h (revision 178718) +++ lib/CodeGen/CGValue.h (working copy) @@ -157,6 +157,11 @@ Expr *BaseIvarExp; + /// Used by struct-path-aware TBAA. + QualType TBAABaseType; + /// Offset relative to the base type. + uint64_t TBAAOffset; + /// TBAAInfo - TBAA information to attach to dereferences of this LValue. llvm::MDNode *TBAAInfo; @@ -175,6 +180,10 @@ this->ImpreciseLifetime = false; this->ThreadLocalRef = false; this->BaseIvarExp = 0; + + // Initialize fields for TBAA. + this->TBAABaseType = Type; + this->TBAAOffset = 0; this->TBAAInfo = TBAAInfo; } @@ -232,6 +241,12 @@ Expr *getBaseIvarExp() const { return BaseIvarExp; } void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } + QualType getTBAABaseType() const { return TBAABaseType; } + void setTBAABaseType(QualType T) { TBAABaseType = T; } + + uint64_t getTBAAOffset() const { return TBAAOffset; } + void setTBAAOffset(uint64_t O) { TBAAOffset = O; } + llvm::MDNode *getTBAAInfo() const { return TBAAInfo; } void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; } Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h (revision 178718) +++ lib/CodeGen/CodeGenFunction.h (working copy) @@ -2211,7 +2211,9 @@ /// the LLVM value representation. llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, - llvm::MDNode *TBAAInfo = 0); + llvm::MDNode *TBAAInfo = 0, + QualType TBAABaseTy = QualType(), + uint64_t TBAAOffset = 0); /// EmitLoadOfScalar - Load a scalar value from an address, taking /// care to appropriately convert from the memory representation to @@ -2224,7 +2226,9 @@ /// the LLVM value representation. void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, - llvm::MDNode *TBAAInfo = 0, bool isInit=false); + llvm::MDNode *TBAAInfo = 0, bool isInit = false, + QualType TBAABaseTy = QualType(), + uint64_t TBAAOffset = 0); /// EmitStoreOfScalar - Store a scalar value to an address, taking /// care to appropriately convert from the memory representation to Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp (revision 178718) +++ lib/CodeGen/CodeGenModule.cpp (working copy) @@ -227,6 +227,20 @@ return TBAA->getTBAAStructInfo(QTy); } +llvm::MDNode *CodeGenModule::getTBAAStructTypeInfo(QualType QTy) { + if (!TBAA) + return 0; + return TBAA->getTBAAStructTypeInfo(QTy); +} + +llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy, + llvm::MDNode *AccessN, + uint64_t O) { + if (!TBAA) + return 0; + return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O); +} + void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst, llvm::MDNode *TBAAInfo) { Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo); Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h (revision 178718) +++ lib/CodeGen/CodeGenModule.h (working copy) @@ -501,6 +501,11 @@ llvm::MDNode *getTBAAInfo(QualType QTy); llvm::MDNode *getTBAAInfoForVTablePtr(); llvm::MDNode *getTBAAStructInfo(QualType QTy); + /// Return the MDNode in the type DAG for the given struct type. + llvm::MDNode *getTBAAStructTypeInfo(QualType QTy); + /// Return the path-aware tag for given base type, access node and offset. + llvm::MDNode *getTBAAStructTagInfo(QualType BaseTy, llvm::MDNode *AccessN, + uint64_t O); bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); Index: lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- lib/CodeGen/CodeGenTBAA.cpp (revision 178718) +++ lib/CodeGen/CodeGenTBAA.cpp (working copy) @@ -21,6 +21,7 @@ #include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" #include "clang/Frontend/CodeGenOptions.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" @@ -225,3 +226,87 @@ // For now, handle any other kind of type conservatively. return StructMetadataCache[Ty] = NULL; } + +/// Check if the given type can be handled by path-aware TBAA. +static bool isTBAAPathStruct(QualType QTy) { + if (const RecordType *TTy = QTy->getAs<RecordType>()) { + const RecordDecl *RD = TTy->getDecl()->getDefinition(); + // RD can be struct, union, class, interface or enum. + // For now, we only handle struct. + if (RD->isStruct() && !RD->hasFlexibleArrayMember()) + return true; + } + return false; +} + +llvm::MDNode * +CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { + const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); + assert(isTBAAPathStruct(QTy)); + + if (llvm::MDNode *N = StructTypeMetadataCache[Ty]) + return N; + + if (const RecordType *TTy = QTy->getAs<RecordType>()) { + const RecordDecl *RD = TTy->getDecl()->getDefinition(); + + const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); + SmallVector <std::pair<uint64_t, llvm::MDNode*>, 4> Fields; + // To reduce the size of MDNode for a given struct type, we only output + // once for all the fields with the same scalar types. + // Offsets for scalar fields in the type DAG are not used. + llvm::SmallSet <llvm::MDNode*, 4> ScalarFieldTypes; + unsigned idx = 0; + for (RecordDecl::field_iterator i = RD->field_begin(), + e = RD->field_end(); i != e; ++i, ++idx) { + QualType FieldQTy = i->getType(); + llvm::MDNode *FieldNode; + if (isTBAAPathStruct(FieldQTy)) + FieldNode = getTBAAStructTypeInfo(FieldQTy); + else { + FieldNode = getTBAAInfo(FieldQTy); + // Ignore this field if the type already exists. + if (ScalarFieldTypes.count(FieldNode)) + continue; + ScalarFieldTypes.insert(FieldNode); + } + if (!FieldNode) + return StructTypeMetadataCache[Ty] = NULL; + Fields.push_back(std::make_pair( + Layout.getFieldOffset(idx) / Context.getCharWidth(), FieldNode)); + } + + // TODO: This is using the RTTI name. Is there a better way to get + // a unique string for a type? + SmallString<256> OutName; + llvm::raw_svector_ostream Out(OutName); + MContext.mangleCXXRTTIName(QualType(Ty, 0), Out); + Out.flush(); + // Create the struct type node with a vector of pairs (offset, type). + return StructTypeMetadataCache[Ty] = + MDHelper.createTBAAStructTypeNode(OutName, Fields); + } + + return StructMetadataCache[Ty] = NULL; +} + +llvm::MDNode * +CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode, + uint64_t Offset) { + if (!CodeGenOpts.StructPathTBAA) + return AccessNode; + + const Type *BTy = Context.getCanonicalType(BaseQTy).getTypePtr(); + TBAAPathTag PathTag = TBAAPathTag(BTy, AccessNode, Offset); + if (llvm::MDNode *N = StructTagMetadataCache[PathTag]) + return N; + + llvm::MDNode *BNode = 0; + if (isTBAAPathStruct(BaseQTy)) + BNode = getTBAAStructTypeInfo(BaseQTy); + if (!BNode) + return StructTagMetadataCache[PathTag] = AccessNode; + + return StructTagMetadataCache[PathTag] = + MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset); +} Index: lib/CodeGen/CodeGenTBAA.h =================================================================== --- lib/CodeGen/CodeGenTBAA.h (revision 178718) +++ lib/CodeGen/CodeGenTBAA.h (working copy) @@ -35,6 +35,14 @@ namespace CodeGen { class CGRecordLayout; + struct TBAAPathTag { + TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O) + : BaseT(B), AccessN(A), Offset(O) {} + const Type *BaseT; + const llvm::MDNode *AccessN; + uint64_t Offset; + }; + /// CodeGenTBAA - This class organizes the cross-module state that is used /// while lowering AST types to LLVM types. class CodeGenTBAA { @@ -46,8 +54,13 @@ // MDHelper - Helper for creating metadata. llvm::MDBuilder MDHelper; - /// MetadataCache - This maps clang::Types to llvm::MDNodes describing them. + /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing + /// them. llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; + /// This maps clang::Types to a struct node in the type DAG. + llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache; + /// This maps TBAAPathTags to a tag node. + llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache; /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing /// them for struct assignments. @@ -89,9 +102,49 @@ /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of /// the given type. llvm::MDNode *getTBAAStructInfo(QualType QTy); + + /// Get the MDNode in the type DAG for given struct type QType. + llvm::MDNode *getTBAAStructTypeInfo(QualType QType); + /// Get the tag MDNode for a given base type, the actual sclar access MDNode + /// and offset into the base type. + llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType, + llvm::MDNode *AccessNode, uint64_t Offset); }; } // end namespace CodeGen } // end namespace clang +namespace llvm { + +template<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> { + static clang::CodeGen::TBAAPathTag getEmptyKey() { + return clang::CodeGen::TBAAPathTag( + DenseMapInfo<const clang::Type *>::getEmptyKey(), + DenseMapInfo<const MDNode *>::getEmptyKey(), + DenseMapInfo<uint64_t>::getEmptyKey()); + } + + static clang::CodeGen::TBAAPathTag getTombstoneKey() { + return clang::CodeGen::TBAAPathTag( + DenseMapInfo<const clang::Type *>::getTombstoneKey(), + DenseMapInfo<const MDNode *>::getTombstoneKey(), + DenseMapInfo<uint64_t>::getTombstoneKey()); + } + + static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) { + return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^ + DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^ + DenseMapInfo<uint64_t>::getHashValue(Val.Offset); + } + + static bool isEqual(const clang::CodeGen::TBAAPathTag &LHS, + const clang::CodeGen::TBAAPathTag &RHS) { + return LHS.BaseT == RHS.BaseT && + LHS.AccessN == RHS.AccessN && + LHS.Offset == RHS.Offset; + } +}; + +} // end namespace llvm + #endif Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp (revision 178718) +++ lib/Driver/Tools.cpp (working copy) @@ -2105,6 +2105,8 @@ options::OPT_fno_strict_aliasing, getToolChain().IsStrictAliasingDefault())) CmdArgs.push_back("-relaxed-aliasing"); + if (Args.hasArg(options::OPT_fstruct_path_tbaa)) + CmdArgs.push_back("-struct-path-tbaa"); if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums, false)) CmdArgs.push_back("-fstrict-enums"); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp (revision 178718) +++ lib/Frontend/CompilerInvocation.cpp (working copy) @@ -324,6 +324,7 @@ Opts.UseRegisterSizedBitfieldAccess = Args.hasArg( OPT_fuse_register_sized_bitfield_access); Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing); + Opts.StructPathTBAA = Args.hasArg(OPT_struct_path_tbaa); Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags); Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants); Opts.NoCommon = Args.hasArg(OPT_fno_common); Index: test/CodeGen/tbaa.cpp =================================================================== --- test/CodeGen/tbaa.cpp (revision 0) +++ test/CodeGen/tbaa.cpp (working copy) @@ -0,0 +1,217 @@ +// RUN: %clang_cc1 -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH +// Test TBAA metadata generated by front-end. + +#include <stdint.h> +typedef struct +{ + uint16_t f16; + uint32_t f32; + uint16_t f16_2; + uint32_t f32_2; +} StructA; +typedef struct +{ + uint16_t f16; + StructA a; + uint32_t f32; +} StructB; +typedef struct +{ + uint16_t f16; + StructB b; + uint32_t f32; +} StructC; +typedef struct +{ + uint16_t f16; + StructB b; + uint32_t f32; + uint8_t f8; +} StructD; + +typedef struct +{ + uint16_t f16; + uint32_t f32; +} StructS; +typedef struct +{ + uint16_t f16; + uint32_t f32; +} StructS2; + +uint32_t g(uint32_t *s, StructA *A, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !5 + *s = 1; + A->f32 = 4; + return *s; +} + +uint32_t g2(uint32_t *s, StructA *A, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !8 + *s = 1; + A->f16 = 4; + return *s; +} + +uint32_t g3(StructA *A, StructB *B, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9 + A->f32 = 1; + B->a.f32 = 4; + return A->f32; +} + +uint32_t g4(StructA *A, StructB *B, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !11 + A->f32 = 1; + B->a.f16 = 4; + return A->f32; +} + +uint32_t g5(StructA *A, StructB *B, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !12 + A->f32 = 1; + B->f32 = 4; + return A->f32; +} + +uint32_t g6(StructA *A, StructB *B, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !13 + A->f32 = 1; + B->a.f32_2 = 4; + return A->f32; +} + +uint32_t g7(StructA *A, StructS *S, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !14 + A->f32 = 1; + S->f32 = 4; + return A->f32; +} + +uint32_t g8(StructA *A, StructS *S, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5 +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !16 + A->f32 = 1; + S->f16 = 4; + return A->f32; +} + +uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14 +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !17 + S->f32 = 1; + S2->f32 = 4; + return S->f32; +} + +uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14 +// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !19 + S->f32 = 1; + S2->f16 = 4; + return S->f32; +} + +uint32_t g11(StructC *C, StructD *D, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !20 +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !22 + C->b.a.f32 = 1; + D->b.a.f32 = 4; + return C->b.a.f32; +} + +uint32_t g12(StructC *C, StructD *D, uint64_t count) { +// CHECK: define i32 @{{.*}}( +// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4 +// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4 +// TODO: differentiate the two accesses. +// PATH: define i32 @{{.*}}( +// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !9 +// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9 + StructB *b1 = &(C->b); + StructB *b2 = &(D->b); + // b1, b2 have different context. + b1->a.f32 = 1; + b2->a.f32 = 4; + return b1->a.f32; +} + +// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2} +// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"} +// CHECK: !4 = metadata !{metadata !"int", metadata !1} +// CHECK: !5 = metadata !{metadata !"short", metadata !1} + +// PATH: !1 = metadata !{metadata !"omnipotent char", metadata !2} +// PATH: !4 = metadata !{metadata !"int", metadata !1} +// PATH: !5 = metadata !{metadata !6, metadata !4, i64 4} +// PATH: !6 = metadata !{metadata !"_ZTS7StructA", i64 0, metadata !7, i64 4, metadata !4} +// PATH: !7 = metadata !{metadata !"short", metadata !1} +// PATH: !8 = metadata !{metadata !6, metadata !7, i64 0} +// PATH: !9 = metadata !{metadata !10, metadata !4, i64 8} +// PATH: !10 = metadata !{metadata !"_ZTS7StructB", i64 0, metadata !7, i64 4, metadata !6, i64 20, metadata !4} +// PATH: !11 = metadata !{metadata !10, metadata !7, i64 4} +// PATH: !12 = metadata !{metadata !10, metadata !4, i64 20} +// PATH: !13 = metadata !{metadata !10, metadata !4, i64 16} +// PATH: !14 = metadata !{metadata !15, metadata !4, i64 4} +// PATH: !15 = metadata !{metadata !"_ZTS7StructS", i64 0, metadata !7, i64 4, metadata !4} +// PATH: !16 = metadata !{metadata !15, metadata !7, i64 0} +// PATH: !17 = metadata !{metadata !18, metadata !4, i64 4} +// PATH: !18 = metadata !{metadata !"_ZTS8StructS2", i64 0, metadata !7, i64 4, metadata !4} +// PATH: !19 = metadata !{metadata !18, metadata !7, i64 0} +// PATH: !20 = metadata !{metadata !21, metadata !4, i64 12} +// PATH: !21 = metadata !{metadata !"_ZTS7StructC", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4} +// PATH: !22 = metadata !{metadata !23, metadata !4, i64 12} +// PATH: !23 = metadata !{metadata !"_ZTS7StructD", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4, i64 32, metadata !1} git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178784 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-04Plumb through the -fsplit-stack option using the existing backendEric Christopher
support. Caveat: Other than the existing segmented stacks support, no claims are made of this working. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178744 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-03From PR9121 gcc defaulted to omitting the frame pointer on linux,Eric Christopher
however, it doesn't do that unless we're optimizing. Change that and haul out to a helper function. Also make this a driver test appropriate rather than an assembly test. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178606 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-02[analyzer] Moving cplusplus.NewDelete to alpha.* for now.Anton Yartsev
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178529 91177308-0d34-0410-b5e6-96231b3b80d8
2013-04-01R600: Handle -mcpu option v3Tom Stellard
v2: - Add a test case v3: - Use the -### clang option in the tests git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178499 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-30Add support for gcc-compatible -mfprnd -mno-fprnd PPC optionsHal Finkel
gcc provides -mfprnd and -mno-fprnd for controlling the fprnd target feature; support these options as well. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178414 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-29Hexagon: Set Hexagon tool-chain when configured as OSless target.Jyotsna Verma
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178358 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-28Rename clang::driver::tools::linuxtools to clang::driver::tools::gnutools.Thomas Schwinge
This is about the GNU Binutils' assembler and linker, so reflect that in the name. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178272 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-28Rename LinuxDistro to Distro.Thomas Schwinge
The concept of such a software distribution is not tied to the Linux kernel; for example Debian GNU/Linux, Debian GNU/Hurd, and Debian GNU/kFreeBSD all share the same source packages and generally the same user-space configuration. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178270 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-28Add support for gcc-compatible -mpopcntd -mno-popcntd PPC optionsHal Finkel
gcc provides -mpopcntd and -mno-popcntd for controlling the popcntd target feature; support these options as well. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178235 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-28[Mips] Handle pseudo-target flags '-EL' and '-EB' and properly adjustSimon Atanasyan
toolchain flags for MIPS targets. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178232 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-28Add support for gcc-compatible -mmfcrf -mno-mfcrf PPC optionsHal Finkel
gcc provides -mmfcrf and -mno-mfcrf for controlling what we call the mfocrf target feature. Also, PPC is now making use of the static function AddTargetFeature used by the Mips Driver code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178227 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-27<rdar://problem/13509689> Introduce -module-file-info option that provides ↵Douglas Gregor
information about a particular module file. This option can be useful for end users who want to know why they ended up with a ton of different variants of the "std" module in their module cache. This problem should go away over time, as we reduce the need for module variants, but it will never go away entirely. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178148 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-26[driver] Do not generate crash diagnostics if the compilation command failedChad Rosier
to execute as the crash will surely reoccur while generating the diagnostics. rdar://13362359 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178089 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-25<rdar://problem/13434605> Periodically prune the module cache so that it ↵Douglas Gregor
does not grow forever. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177918 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-25[analyzer] Adds cplusplus.NewDelete checker that check for memory leaks, ↵Anton Yartsev
double free, and use-after-free problems of memory managed by new/delete. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177849 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-24Reject -no-integrated-as on windows.Rafael Espindola
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177840 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-23Revert svn r176894 and r177658.Bob Wilson
Changing -ccc-install-dir to affect cc1's resource-dir setting broke our internal LNT tests. After discussing the situation with Jim, we've decided to pursue an alternate approach. We really want the resource-dir to be located relative to clang, even when using -ccc-install-dir, but we're going to add a fallback setting for the libc++ headers if they don't exist alongside the compiler. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177815 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-23If a .syms file is available alongside a sanitizer runtime, pass it to theRichard Smith
linker via --dynamic-list instead of using --export-dynamic. This reduces the size of the dynamic symbol table, and thus of the binary (in some cases by up to ~30%). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177783 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-21<rdar://problem/13477190> Give the Clang module cache directory some ↵Douglas Gregor
structure, so it's easier to find. We now put the Clang module cache in <system-temp-directory>/org.llvm.clang/ModuleCache. Perhaps some day there will be other caches under <system-temp-directory>/org.llvm.clang>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177671 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-21Avoid warnings from compilers that think you can drop off the end of a fully ↵Benjamin Kramer
covered switch. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177656 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-21[ASan] Let the users to invoke `clang -fsanitize=address` to link binaries ↵Alexander Potapenko
targeting the iOS simulator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177633 91177308-0d34-0410-b5e6-96231b3b80d8
2013-03-20Split ubsan runtime into three pieces (clang part):Richard Smith
* libclang_rt-san-* is sanitizer_common, and is linked in only if no other sanitizer runtime is present. * libclang_rt-ubsan-* is the piece of the runtime which doesn't depend on a C++ ABI library, and is always linked in. * libclang_rt-ubsan_cxx-* is the piece of the runtime which depends on a C++ ABI library, and is only linked in when linking a C++ binary. This change also switches us to using -whole-archive for the ubsan runtime (which is made possible by the above split), and switches us to only linking the sanitizer runtime into the main binary and not into DSOs (which is made possible by using -whole-archive). The motivation for this is to only link a single copy of sanitizer_common into any binary. This is becoming important now because we want to share more state between multiple sanitizers in the same process (for instance, we want a single shared output mutex). The Darwin ubsan runtime is unchanged; because we use a DSO there, we don't need this complexity. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177605 91177308-0d34-0410-b5e6-96231b3b80d8