[llvm-commits] [gcc-plugin] r81148 - in /gcc-plugin/trunk: llvm-convert.cpp llvm-internal.h
Duncan Sands
baldrick at free.fr
Mon Sep 7 04:59:55 PDT 2009
Author: baldrick
Date: Mon Sep 7 06:59:54 2009
New Revision: 81148
URL: http://llvm.org/viewvc/llvm-project?rev=81148&view=rev
Log:
Handle SSA default definitions in a more sophisticated way.
These represent the initial value of a variable at the start
of the function. The only non-trivial case occurs for function
parameters. In this case, associate the ssa name with an explicit
load of the parameter value at an appropriate place in the entry
block.
Modified:
gcc-plugin/trunk/llvm-convert.cpp
gcc-plugin/trunk/llvm-internal.h
Modified: gcc-plugin/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-convert.cpp?rev=81148&r1=81147&r2=81148&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-convert.cpp (original)
+++ gcc-plugin/trunk/llvm-convert.cpp Mon Sep 7 06:59:54 2009
@@ -618,6 +618,13 @@
Args = Args == static_chain ? DECL_ARGUMENTS(FnDecl) : TREE_CHAIN(Args);
}
+ // Loading the value of a PARM_DECL at this point yields its initial value.
+ // Remember this for use when materializing the reads implied by SSA default
+ // definitions.
+ SSAInsertionPoint = Builder.Insert(CastInst::Create(Instruction::BitCast,
+ Constant::getNullValue(Type::getInt32Ty(Context)),
+ Type::getInt32Ty(Context)), "ssa point");
+
// If this is not a void-returning function, initialize the RESULT_DECL.
if (DECL_RESULT(FnDecl) && !VOID_TYPE_P(TREE_TYPE(DECL_RESULT(FnDecl))) &&
!DECL_LLVM_SET_P(DECL_RESULT(FnDecl)))
@@ -2232,9 +2239,42 @@
/// EmitSSA_NAME - Return the defining value of the given SSA_NAME.
Value *TreeToLLVM::EmitSSA_NAME(tree exp) {
- if (SSA_NAME_IS_DEFAULT_DEF(exp))
- return Emit(SSA_NAME_VAR(exp), 0);
- return SSANames[exp];
+ DenseMap<tree, Value*>::iterator I = SSANames.find(exp);
+ if (I != SSANames.end())
+ return I->second;
+
+ // This SSA name is the default definition for the underlying symbol.
+ assert(SSA_NAME_IS_DEFAULT_DEF(exp) && "SSA name used before being defined!");
+
+ // The underlying symbol is an SSA variable.
+ tree var = SSA_NAME_VAR(exp);
+ assert(SSA_VAR_P(var) && "Not an SSA variable!");
+
+ // If the variable is itself an ssa name, use its LLVM value.
+ if (TREE_CODE (var) == SSA_NAME)
+ return SSANames[exp] = EmitSSA_NAME(var);
+
+ // Otherwise the symbol is a VAR_DECL, PARM_DECL or RESULT_DECL. Since a
+ // default definition is only created if the very first reference to the
+ // variable in the function is a read operation, and refers to the value
+ // read, it has an undefined value except for PARM_DECLs.
+ if (TREE_CODE(var) != PARM_DECL)
+ return UndefValue::get(ConvertType(TREE_TYPE(exp)));
+
+ // Read the initial value of the parameter and associate it with the ssa name.
+ assert(DECL_LLVM_IF_SET(var) && "Parameter not laid out?");
+
+ unsigned Alignment = DECL_ALIGN(var);
+ assert(Alignment != 0 && "Parameter with unknown alignment!");
+
+ const Type *Ty = ConvertType(TREE_TYPE(exp));
+ Value *Ptr = BitCastToType(DECL_LLVM_IF_SET(var), PointerType::getUnqual(Ty));
+
+ // Perform the load in the entry block, after all parameters have been set up
+ // with their initial values, and before any modifications to their values.
+ LoadInst *LI = new LoadInst(Ptr, "defaultdef", SSAInsertionPoint);
+ LI->setAlignment(Alignment);
+ return SSANames[exp] = LI;
}
/// EmitLoadOfLValue - When an l-value expression is used in a context that
@@ -2855,10 +2895,8 @@
// If this is the definition of an ssa name, record it in the SSANames map.
if (TREE_CODE(lhs) == SSA_NAME) {
- assert(SSANames.find(lhs) == SSANames.end() && "Multiply defined ssa name!");
- Value *RHS = Emit(rhs, 0);
- SSANames[lhs] = RHS;
- return RHS;
+ assert(SSANames.find(lhs) == SSANames.end() && "Multiply defined SSA name!");
+ return SSANames[lhs] = Emit(rhs, 0);
} else if (canEmitRegisterVariable(lhs)) {
// If this is a store to a register variable, EmitLV can't handle the dest
// (there is no l-value of a register variable). Emit an inline asm node
Modified: gcc-plugin/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-internal.h?rev=81148&r1=81147&r2=81148&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-internal.h (original)
+++ gcc-plugin/trunk/llvm-internal.h Mon Sep 7 06:59:54 2009
@@ -324,6 +324,10 @@
// and managed by CreateTemporary.
Instruction *AllocaInsertionPoint;
+ // SSAInsertionPoint - Place to insert reads corresponding to SSA default
+ // definitions.
+ Instruction *SSAInsertionPoint;
+
// SSANames - Map from GCC ssa names to the defining LLVM value.
DenseMap<tree, Value*> SSANames;
More information about the llvm-commits
mailing list